General Protection Fault on context switch

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Crumble14
Posts: 16
Joined: Tue Jan 01, 2019 4:10 pm
Location: Normandy, France

General Protection Fault on context switch

Post by Crumble14 »

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: 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
(My TSS is initialized somewhere else, see: viewtopic.php?f=1&t=33720)

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
I'm calling this function from C code, its prototype is:

Code: Select all

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?
Student at School 42 Paris (FR: https://42.fr/)
Post Reply