From d73ace71fbe30b8b09307af67aa4a93250f9bb31 Mon Sep 17 00:00:00 2001 From: Emin Arslan Date: Tue, 5 May 2026 21:30:47 +0300 Subject: [PATCH] fix: correct GDT, segment loads, and ISR stack alignment Co-authored-by: aider (openrouter/anthropic/claude-opus-4.7) --- kernel_entry.S | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/kernel_entry.S b/kernel_entry.S index 51478f8..2e37f47 100644 --- a/kernel_entry.S +++ b/kernel_entry.S @@ -80,8 +80,21 @@ _start: .code64 long_mode_start: + /* Load data segment registers with the data descriptor (0x10). + * In long mode most of these are ignored for access checks, but + * %ss must be a valid (or null) selector so that iretq from an + * interrupt can safely reload it. */ + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + movabsq $stack_top, %rax movq %rax, %rsp + /* Ensure 16-byte alignment for the System V AMD64 ABI. */ + andq $-16, %rsp call kernel_main cli @@ -93,6 +106,7 @@ long_mode_start: .global isr_keyboard .align 16 isr_keyboard: + /* Save all caller-saved registers used by the SysV AMD64 ABI. */ pushq %rax pushq %rcx pushq %rdx @@ -102,8 +116,14 @@ isr_keyboard: pushq %r9 pushq %r10 pushq %r11 + /* On interrupt entry the CPU pushed 5 qwords (40 bytes), and we + * pushed 9 more (72 bytes) = 112 bytes total. That leaves %rsp + * misaligned by 8 relative to a 16-byte boundary after the + * upcoming `call`. Push one dummy qword to realign. */ + subq $8, %rsp cld call keyboard_handler + addq $8, %rsp popq %r11 popq %r10 popq %r9 @@ -127,8 +147,10 @@ isr_keyboard: .section .rodata .align 8 gdt64: - .quad 0x0000000000000000 - .quad 0x00209A0000000000 + .quad 0x0000000000000000 /* 0x00: null descriptor */ + .quad 0x00209A0000000000 /* 0x08: 64-bit code, DPL=0 */ + .quad 0x0000920000000000 /* 0x10: data, writable, present */ +gdt64_end: gdt64_pointer: - .word gdt64_pointer - gdt64 - 1 + .word gdt64_end - gdt64 - 1 .quad gdt64