I'm working on multitasking with protection. I started with stack based task switching which runs properly in kernel space.
But now if I try to run a task in ring 3 I get a double fault.
The output from my exception handler shows, that my stack seems to be corrupted somehow. But this seems to be a bit strange as the same layout works for kernel mode pretty fine.
Here's the setup:
Code: Select all
stack[0]=0x20 | 3; //gs
stack[1]=0x20 | 3; //fs
stack[2]=0x20 | 3; //es
stack[3]=0x20 | 3; //ds
stack[4]=0; //edi
stack[5]=0; //esi
stack[6]=0; //ebp
stack[7]=0; //esp
stack[8]=0; //ebx
stack[9]=0; //edx
stack[10]=0; //ecx
stack[11]=0; //eax
stack[12]=(uint)0x80002000; //entry point (eip)
stack[13]=0x18 | 0x03; // user code seg
stack[14]=0x3202; // eflags
stack[15]=0x80001FF4; // ring 3 esp
stack[16]=0x20 | 0x03; // ss
The assembly stub:
Code: Select all
go_on:
call ktask_handler
mov eax, [curProc] ;switch to procs kstack
mov esp, [eax]
mov [ktss + 4], esp ;patch tss
mov al, 0x20
out 0x20,al
pop gs
pop fs
pop es
pop ds
popad
;cmp esp, 0x80000000
;ja stop << here I jumped to a hlt for debugging
iretd
The fault handler shows that the values are'shifted' by one meaning that the values are in the register that follows the correct target register.
Code: Select all
EIP: 0x05 ; should be 0x80002000
CS: 0x80002000 ; should be 0x18 | 3 >> 0x1B
EFLAGS: 0x1B ; should be 0x3202
ESP: 0x3202 ; should be 0x80001FF4
SS: 0x80001FF4; should be 0x20 | 3 >> 0x23