OSDev.org
https://forum.osdev.org/

General Protection Fault on context switch
https://forum.osdev.org/viewtopic.php?f=1&t=33756
Page 1 of 1

Author:  Crumble14 [ Fri Jul 05, 2019 5:52 am ]
Post subject:  General Protection Fault on context switch

Hello,

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:
.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


(My TSS is initialized somewhere else, see: https://forum.osdev.org/viewtopic.php?f=1&t=33720)

Here is my code for context switching:
Code:
.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


I'm calling this function from C code, its prototype is:

Code:
extern void context_switch(void *esp, void *eip);


I'm passing a pointer to the last byte of an allocated page of memory in esp (for the stack) and a function pointer for 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?

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/