I'm currently trying to switch to ring 3 on my kernel. However when I try, I get a General Protection Fault.
Here is my GDT:
Code: Select all
.align 8
gdt_start:
gdt_null:
.quad 0
gdt_kernel_code:
.word 0xffff
.word 0
.byte 0
.byte 0b10011010
.byte 0b11001111
.byte 0
gdt_kernel_data:
.word 0xffff
.word 0
.byte 0
.byte 0b10010010
.byte 0b11001111
.byte 0
gdt_user_code:
.word 0xffff
.word 0
.byte 0
.byte 0b11111010
.byte 0b11001111
.byte 0
gdt_user_data:
.word 0xffff
.word 0
.byte 0
.byte 0b11110010
.byte 0b11001111
.byte 0
gdt_tss:
.quad 0
gdt:
.word gdt - gdt_start - 1
.long gdt_start
Here is my code for context switching:
Code: Select all
.global context_switch
context_switch:
push %ebp
mov %esp, %ebp
mov $GDT_USER_DATA_OFFSET, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
push $GDT_USER_DATA_OFFSET
push 8(%ebp)
pushf
push $GDT_USER_CODE_OFFSET
push 16(%ebp)
iret
# TODO Error handling
mov %ebp, %esp
pop %ebp
ret
Code: Select all
extern void context_switch(void *esp, void *eip);
The error happens when reaching the iret instruction.
When catching the General Protection Fault interrupt, the error code tells me that the problem comes from segment 0x18 (gdt_user_code).
Am I doing something wrong?