problem switching to user mode
Posted: Thu May 24, 2012 2:51 am
Hi,
I am following JamesM's tutorial to write my OS but I have a problem with switching from kernel to user mode.
The tutorial provides the following function for switching to user mode.
In my code I call this function from my main function and after that there is call to another function to print a string
To make the code work in user mode I set User mode in the Page directory and page table entries.
However the code is not working. On running it in bochs it keeps on restarting.
When I ran it in bochs debugger I found that control returns from switch_to_user_mode() to the main function
but then it hits a far jump instruction and stops there.
Here the instruction - mov dword ptr ss:[esp], 0x0010277d is the first instruction executed after call to switch_to_user_mode
but after that strangely a far jump is encountered while there is no jump in the disassembly.
Here is the dissassembly of the instructions from main function shown above
It can be seen that the instruction to move a pointer into esp - is fine as it is also shown by bochs debugger but after that there should be a call to ConsoleWriteString instead of a jump.
I checked the GDT and it seemed fine. The segment registers also had the required user mode selectors. However
I found some difference in the segment registers after two different instructions.I checked the segment registers after the iret instruction in switch_to_user_mode and then after the ret instruction I checked them again
Here are the values after iret
And here are the values after ret
The selector values are fine. The only difference I could find is that for the Stack segment register the value of valid is different. In case of iret it is 1 while after ret it is 3. I don't know what is the significance of valid here but I am guessing that it is related to the problem because the code
breaks just after the instruction which writes to stack.
I hope I am clear. Please help.
Thanks
Vaibhav Jain
I am following JamesM's tutorial to write my OS but I have a problem with switching from kernel to user mode.
The tutorial provides the following function for switching to user mode.
Code: Select all
void switch_to_user_mode()
{
asm volatile(" \
cli; \
mov $0x23, %ax; \
mov %ax, %ds; \
mov %ax, %es; \
mov %ax, %fs; \
mov %ax, %gs; \
\
mov %esp, %eax; \
push $0x23; \
push %eax; \
pushfl; \
push $0x1B; \
push $1f; \
iret; \
1: \
");
}
Code: Select all
switch_to_user_mode();
ConsoleWriteString("\nIn User MODE\n");
However the code is not working. On running it in bochs it keeps on restarting.
When I ran it in bochs debugger I found that control returns from switch_to_user_mode() to the main function
but then it hits a far jump instruction and stops there.
Code: Select all
<bochs:21> s
Next at t=148248984
(0) [0x00000000001000b3] 001b:001000b3 (kmain+a7): mov dword ptr ss:[esp], 0x0010277d ; c704247d271000
<bochs:22> s
(0).[148248984] [0x00000000001000b3] 001b:001000b3 (kmain+a7): mov dword ptr ss:[esp], 0x0010277d ; c704247d271000
Next at t=148248985
(0) [0x00000000fffffff0] f000:fff0 (no symbol): jmp far f000:e05b ; ea5be000f0
but after that strangely a far jump is encountered while there is no jump in the disassembly.
Here is the dissassembly of the instructions from main function shown above
Code: Select all
1000ae: e8 39 26 00 00 call 1026ec <switch_to_user_mode>
1000b3: c7 04 24 7d 27 10 00 movl $0x10277d,(%esp)
1000ba: e8 f7 04 00 00 call 1005b6 <ConsoleWriteString>
It can be seen that the instruction to move a pointer into esp -
Code: Select all
movl $0x10277d,(%esp)
I checked the GDT and it seemed fine. The segment registers also had the required user mode selectors. However
I found some difference in the segment registers after two different instructions.I checked the segment registers after the iret instruction in switch_to_user_mode and then after the ret instruction I checked them again
Here are the values after iret
Code: Select all
<bochs:17> s
Next at t=148248983
(0) [0x0000000000102707] 001b:00102707 (switch_to_user_mode+1b): ret ; c3
<bochs:18> sreg
es:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x001b, dh=0x00cffb00, dl=0x0000ffff, valid=1
Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Accessed, 32-bit
ss:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1 ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1
gdtr:base=0x00108020, limit=0x27
idtr:base=0x001080e0, limit=0x7ff
Code: Select all
<bochs:17> s
Next at t=149328457
(0) [0x00000000001000b3] 001b:001000b3 (kmain+a7): mov dword ptr ss:[esp], 0x0010277d ; c704247d271000
<bochs:18> sreg
es:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x001b, dh=0x00cffb00, dl=0x0000ffff, valid=1
Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Accessed, 32-bit
ss:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=3 ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1
gdtr:base=0x00108020, limit=0x27
idtr:base=0x001080e0, limit=0x7ff
breaks just after the instruction which writes to stack.
I hope I am clear. Please help.
Thanks
Vaibhav Jain