Page 1 of 1
[Solved] Switching to user mode: Kernel hang up
Posted: Sun Aug 25, 2013 6:33 pm
by narke
Hi,
I'm trying to with to user mode (ring3) and execute a function via a system call.
The thing is that, it doesn't works.
Qemu hangs up, or is trying to load the kernel and stops there:
or if lucky it display everything before the executon of a system call.
But interruptions are disabled (even if I enabled them in EFLAGS, like explained here:
http://www.jamesmolloy.co.uk/tutorial_h ... 0Mode.html)
I'm also allocating a stack which is mapped in virtual memory, otherwise I'm getting a page fault (that's normal).
The system call infratructure is OK, I tested it in kernel mode, in order to go into user mode I'm using the snippet provided by James Molloy.
The GDT is set with user data/code segments + TSS:
https://github.com/narke/Roentgenium/bl ... /mmu/gdt.c .
The TSS is also set:
https://github.com/narke/Roentgenium/bl ... cess/tss.c .
I'm suspecting that the kernel stack (esp0) is to blame but I'm not getting page faults, so how?
The stack allocation and user mode switching is done here, just to test:
https://github.com/narke/Roentgenium/bl ... /startup.c .
I think that I'm close to a working solution but I have a mistake somewhere, can you advice me please?
Re: Switching to user mode: Kernel hang up
Posted: Sun Aug 25, 2013 11:30 pm
by xenos
What are you doing after the system call? Halt the CPU with interrupts disabled (cli + hlt) or an endless loop? QEMU's display freezes in case of cli + hlt, an it might do so even before displaying all the output send to it.
Re: Switching to user mode: Kernel hang up
Posted: Mon Aug 26, 2013 2:31 am
by narke
No there is no "cli" or "hlt" during or after the system call.
Even if I don't call a system call the behaviour is the same, Interrupts are disabled so it's like the kernel hangs up.
The asm code should be OK, other people are using the same approach, the stack allocation seems OK too, so I'm lost.
Any idea?
Re: Switching to user mode: Kernel hang up
Posted: Mon Aug 26, 2013 5:07 am
by xenos
I would suggest debugging the code in Bochs - it usually gives you a lot more information if something is going wrong.
Re: Switching to user mode: Kernel hang up
Posted: Mon Aug 26, 2013 5:47 am
by egos
narke wrote:Any idea?
Try this:
Code: Select all
...
iomap_base_address dw 68h
db 0FFh
And increase TSS limit to 68h.
Re: Switching to user mode: Kernel hang up
Posted: Mon Aug 26, 2013 6:35 am
by narke
egos
AFAIK providing TSS size isn't mandatory. I tried with it but nothing changed.
So, I run qemu in monitor mode to see registers and it appears that when user mode switching is disabled the memory mapping (physical and virtual) and the registers have right values.
When user mode switch is enabled thes values are trashed along GDT I think, memory mappings are unavailable when I do "info tlb" and "info mem" on qemu. And registers are set to 0.
Entering user mode disabled:
Code: Select all
(qemu) info registers
EAX=ffff3fff EBX=00035b80 ECX=00000000 EDX=00000001
ESI=00000000 EDI=0005c760 EBP=00067dfc ESP=00110280
EIP=00101016 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=1
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00110d00 00067fff 0080e911 DPL=3 TSS32-avl
GDT= 0010c000 0000002f
IDT= 001102a0 000007ff
CR0=80000011 CR2=00000000 CR3=007fc000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Entering user mode enabled:
Code: Select all
(qemu) info registers
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000633
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=0000fff0 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =f000 ffff0000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 0000ffff
IDT= 00000000 0000ffff
CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Is the DPL for something here? I don't know what is trashing these values except the asm snippet from James Molloy tutorial?
This snippet is:
Code: Select all
asm volatile(" \
cli; \
mov $0x23, %ax; \
mov %ax, %ds; \
mov %ax, %es; \
mov %ax, %fs; \
mov %ax, %gs; \
\
mov %esp, %eax; \
pushl $0x23; \
pushl %eax; \
pushf; \
pop %eax;\
orl $0x200, %eax;\
push %eax;\
pushl $0x1B;\
push $1f;\
iret; \
1: \
");
Re: Switching to user mode: Kernel hang up
Posted: Mon Aug 26, 2013 7:50 am
by Combuster
narke wrote:CS =f000 ffff0000
That's not just any magic number - it's the first instruction that gets executed after a reset. Can you guess what just happened?
XenOS wrote:I would suggest debugging the code in Bochs
I would make running that in Bochs a must rather than a suggestion now