Page 1 of 2

problem of SWITCH TO USER MODE solved :-)

Posted: Fri Aug 08, 2008 2:15 am
by micro
first : sorry for my poor english ...

following is the code of PL0--->PL3

Code: Select all

#define switch_to_user_mode()\
__asm____volatile__("movl $0x23, %%eax\n\t" \
      "movw %%ax, %%ds\n\t" \
      "movw %%ax, %%es\n\t" \
      "movw %%ax, %%fs\n\t" \
      "movw %%ax, %%gs\n\t" \
      "mov %%eax, %%esp\n\t"\
      "pushl $0x23\n\t" \
      "pushl %%esp\n\t" \
      "pushfl \n\t" \
      "pushl $0x1b\n\t" \
      "pushl $1f\n\t" \
      "iret\n\t" \
    "1: "\
      :::ax)
run it in bochs , panic " iret: AR byte indicated non code segment"


following code is the initialization of GDT

Code: Select all

#define load_gdtr(n)\
__asm__("lgdt (%%eax)\n\t"\
::"a" (n));

void init_gdt(void)
{
	gdt_ptr.limit=(sizeof(gdt_entry_t))*5-1;
	gdt_ptr.base=(u32int)&gdt_entries;	
	
	set_gdt_gate(0,0,0,0,0);
	set_gdt_gate(1, 0, 0xffFFffff, 0x9A, 0xCF); // Code segment    0x08
    	set_gdt_gate(2, 0, 0xffFFffff, 0x92, 0xCF); // Data segment	   0x10
    	set_gdt_gate(3, 0, 0xffFFffff, 0xFA, 0xcF); // User mode code segment	0x1b    0001 1011
    	set_gdt_gate(4, 0, 0xffFFffff, 0xF2, 0xcF); // User mode data segment	0x23	   0020 0011
	
	load_gdtr((u32int)&gdt_ptr);
}
void set_gdt_gate(u32int num, u32int base, u32int limit, u8int access, u8int gran)
{
	gdt_entries[num].base_low=(base&0xffff);
	gdt_entries[num].base_middle=((base>>16)&0xff);
	gdt_entries[num].base_high=((base>>24)&0xff);

	gdt_entries[num].limit_low=(limit&0xffff);
	gdt_entries[num].granularity=((limit>>16)&0x0f);

	gdt_entries[num].granularity|=(gran&0xf0);
	gdt_entries[num].access=access;

}
please help me to check the problem. about " iret: AR byte indicated non code segment" ..

i just want PL0-->PL3 and then do nothing to decrease complexity :oops: :oops:

thank you everymuch. :oops: :oops: ...

Re: problem of SWITCH TO USER MODE

Posted: Fri Aug 08, 2008 3:21 am
by Adek336
"mov %%eax, %%esp\n\t"\
this looks suspicious. eax is set to 0x23 at that point

Re: problem of SWITCH TO USER MODE

Posted: Fri Aug 08, 2008 3:39 am
by micro
Adek336 wrote:
"mov %%eax, %%esp\n\t"\
this looks suspicious. eax is set to 0x23 at that point
i think the ESP should be 0x23 , at the data segment...

am i right ? :oops:

Re: problem of SWITCH TO USER MODE

Posted: Fri Aug 08, 2008 3:50 am
by Adek336
CS, DS, ES, FS, GS, ESP... they do form a pattern, don't they? :D But somehow it feels better with CS, DS, ES, FS, GS, SS :D

The ESP is an offset into the stack segment. I am not sure if you should change SS and ESP before IRET or after :( Try both :D

Re: problem of SWITCH TO USER MODE

Posted: Fri Aug 08, 2008 5:35 am
by micro
Adek336 wrote:CS, DS, ES, FS, GS, ESP... they do form a pattern, don't they? :D But somehow it feels better with CS, DS, ES, FS, GS, SS :D

The ESP is an offset into the stack segment. I am not sure if you should change SS and ESP before IRET or after :( Try both :D

Code: Select all

     "pushl $0x23\n\t" \
      "pushl %%esp\n\t" \
      "pushfl \n\t" \
      "pushl $0x1b\n\t" \
      "pushl $1f\n\t" \
      "iret\n\t" \
i think it has been changed before iret... :( :(

and after the IRET, i have no idea about it ... :oops: :cry: :cry:

like this?? :shock:

Code: Select all

#define switch_to_user_mode()\
__asm__("movl %%esp,%%eax\n\t"\
	"pushl $0x23\n\t"\
	"pushl %%eax\n\t"\
	"pushfl \n\t"\
	"pushl $0x1b\n\t"\
	"pushl $1f\n\t"\
	"iret\n"\
	"1: \t movl $0x23,%%eax\n\t"\
	"movw %%ax,%%ds\n\t"\
	"movw %%ax,%%es\n\t"\
	"movw %%ax,%%fs\n\t"\
	"movw %%ax,%%gs"\
	:::"ax")
i hope it is not like this, they are the same, with panic " iret: AR byte indicated non code segment" :cry: :cry:

Re: problem of SWITCH TO USER MODE

Posted: Fri Aug 08, 2008 10:00 am
by Adek336
No, change DS,ES,FS,GS before IRET, and "after IRET" was supposed to mean "in the userland code" :) Are you sure you have code at 0x1b:0x1f ?

Re: problem of SWITCH TO USER MODE

Posted: Sat Aug 09, 2008 12:28 am
by micro
Adek336 wrote:No, change DS,ES,FS,GS before IRET, and "after IRET" was supposed to mean "in the userland code" :) Are you sure you have code at 0x1b:0x1f ?
ox1b is the GDT selector, and ox1f is the label "1" of the following code.

Code: Select all

   "pushl $1f\n\t"\
   "iret\n"\
   "1: \

i think ... :oops: :oops:

and could some one tell more details about
change DS,ES,FS,GS before IRET, and "after IRET" was supposed to mean "in the userland
, or some examples... :oops: that is gratefull.. :oops:

Re: problem of SWITCH TO USER MODE

Posted: Sat Aug 09, 2008 6:13 pm
by micro
the following is the debug information from bochs, i see something wrong ,
i have no idea why this happen :oops: :oops: :oops: .....

help .... please. :cry:

<bochs:61> info gdt
Global Descriptor Table (0x00002740):
GDT[0x00]=??? descriptor hi=00000000, lo=00000000
GDT[0x01]=??? descriptor hi=00000000, lo=00000000
GDT[0x02]=??? descriptor hi=00000000, lo=00000000
GDT[0x03]=??? descriptor hi=00000000, lo=00000000
GDT[0x04]=??? descriptor hi=00000000, lo=00000000
You can list individual entries with 'info gdt NUM'.


<bochs:62> info idt
Interrupt Descriptor Table (0x00000000):
IDT[0x00]=Code segment, linearaddr=f053f000, len=0ff53 bytes, Execute/Read, Conf
orming, Accessed, 16-bit addrs
You can list individual entries with 'info idt NUM' or groups with 'info idt NUM
NUM'
<bochs:63><bochs:68> info r
eax 0x0 0
ecx 0x0 0
edx 0x300 768
ebx 0x0 0
esp 0x0 0x0
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0xfff0 0xfff0
eflags 0x2 2
cs 0xf000 61440
ss 0x0 0
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
<bochs:69>



<bochs:69> info cpu
eax:0x0
ebx:0x0
ecx:0x0
edx:0x300
ebp:0x0
esi:0x0
edi:0x0
esp:0x0
eflags:0x2
eip:0xfff0
cs:s=0xf000, dl=0xffff, dh=0x9b0f, valid=1
ss:s=0x0, dl=0xffff, dh=0x9300, valid=1
ds:s=0x0, dl=0xffff, dh=0x9300, valid=1
es:s=0x0, dl=0xffff, dh=0x9300, valid=1
fs:s=0x0, dl=0xffff, dh=0x9300, valid=1
gs:s=0x0, dl=0xffff, dh=0x9300, valid=1
ldtr:s=0x0, dl=0x0, dh=0x0, valid=0
tr:s=0x0, dl=0x0, dh=0x0, valid=0

gdtr:base=0x0, limit=0x0
idtr:base=0x0, limit=0x3ff
dr0:0x0
dr1:0x0
dr2:0x0
dr3:0x0
dr6:0xffff0ff0
dr7:0x400
tr3:0x0
tr4:0x0
tr5:0x0
tr6:0x0
tr7:0x0
cr0:0x60000010
cr1:0x0
cr2:0x0
cr3:0x0
cr4:0x0
inhibit_mask:0
done
<bochs:70>

Re: problem of SWITCH TO USER MODE

Posted: Sun Aug 10, 2008 2:55 pm
by Combuster
I would start by fixing your GDT, its bogus (and probably not where you want it to be either)

Re: problem of SWITCH TO USER MODE

Posted: Sun Aug 10, 2008 6:00 pm
by micro
Combuster wrote:I would start by fixing your GDT, its bogus (and probably not where you want it to be either)
thank you ...!!!! :lol:

i use the following code, in the head.s , and it works well....

Code: Select all

gdt: .quad 0x0000000000000000 /* NULL descriptor */
 .quad 0x00c09a01000007ff /* 8Mb 0x08, base = 0x10000 */
 .quad 0x00c09201000007ff /* 8Mb 0x10 */
 .quad 0x00c0fa01000007ff
 .quad 0x00c0f201000007ff
it works well...

Re: problem of SWITCH TO USER MODE

Posted: Mon Aug 11, 2008 12:18 am
by micro
i had been test the code for few days...

<bochs:61> info gdt
Global Descriptor Table (0x00002740):
GDT[0x00]=??? descriptor hi=00000000, lo=00000000
GDT[0x01]=??? descriptor hi=00000000, lo=00000000
GDT[0x02]=??? descriptor hi=00000000, lo=00000000
GDT[0x03]=??? descriptor hi=00000000, lo=00000000
GDT[0x04]=??? descriptor hi=00000000, lo=00000000

i am confused why this happen... it can not recognize the parameters ...

the problem come from the function?? or GCC changes it ?? :oops:

Code: Select all

void set_gdt_gate(u32int num, u32int base, u32int limit, u8int access, u8int gran)
{
   gdt_entries[num].base_low=(base&0xffff);
   gdt_entries[num].base_middle=((base>>16)&0xff);
   gdt_entries[num].base_high=((base>>24)&0xff);

   gdt_entries[num].limit_low=(limit&0xffff);
   gdt_entries[num].granularity=((limit>>16)&0x0f);

   gdt_entries[num].granularity|=(gran&0xf0);
   gdt_entries[num].access=access;

}

Re: problem of SWITCH TO USER MODE

Posted: Mon Aug 11, 2008 1:54 am
by Combuster
Once again, your GDT is not where you tell the processor that it is.

Re: problem of SWITCH TO USER MODE

Posted: Mon Aug 11, 2008 2:17 am
by micro
Combuster wrote:Once again, your GDT is not where you tell the processor that it is.

i c, :oops: thank you

Re: problem of SWITCH TO USER MODE

Posted: Mon Aug 11, 2008 7:40 am
by Adek336
how about halting the program with a for(;;); or a asm volatile("cli\nhlt") before your task switching code and then check info gdt in bochs? then you'll see if gdt is properly loaded in that point of the program

Re: problem of SWITCH TO USER MODE

Posted: Mon Aug 11, 2008 8:13 pm
by micro
Adek336 wrote:how about halting the program with a for(;;); or a asm volatile("cli\nhlt") before your task switching code and then check info gdt in bochs? then you'll see if gdt is properly loaded in that point of the program
thank you !!

GDT just like this:

Code: Select all

<bochs:61> info gdt
Global Descriptor Table (0x00002740):
GDT[0x00]=??? descriptor hi=00000000, lo=00000000
GDT[0x01]=??? descriptor hi=00000000, lo=00000000
GDT[0x02]=??? descriptor hi=00000000, lo=00000000
GDT[0x03]=??? descriptor hi=00000000, lo=00000000
GDT[0x04]=??? descriptor hi=00000000, lo=00000000
as Combuster says. "GDT is not where you tell the processor that it is"

i am looking for why this happen... :oops: