fix: correct GDT, segment loads, and ISR stack alignment

Co-authored-by: aider (openrouter/anthropic/claude-opus-4.7) <aider@aider.chat>
This commit is contained in:
2026-05-05 21:30:47 +03:00
parent 9c242187ea
commit d73ace71fb
+25 -3
View File
@@ -80,8 +80,21 @@ _start:
.code64 .code64
long_mode_start: 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 movabsq $stack_top, %rax
movq %rax, %rsp movq %rax, %rsp
/* Ensure 16-byte alignment for the System V AMD64 ABI. */
andq $-16, %rsp
call kernel_main call kernel_main
cli cli
@@ -93,6 +106,7 @@ long_mode_start:
.global isr_keyboard .global isr_keyboard
.align 16 .align 16
isr_keyboard: isr_keyboard:
/* Save all caller-saved registers used by the SysV AMD64 ABI. */
pushq %rax pushq %rax
pushq %rcx pushq %rcx
pushq %rdx pushq %rdx
@@ -102,8 +116,14 @@ isr_keyboard:
pushq %r9 pushq %r9
pushq %r10 pushq %r10
pushq %r11 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 cld
call keyboard_handler call keyboard_handler
addq $8, %rsp
popq %r11 popq %r11
popq %r10 popq %r10
popq %r9 popq %r9
@@ -127,8 +147,10 @@ isr_keyboard:
.section .rodata .section .rodata
.align 8 .align 8
gdt64: gdt64:
.quad 0x0000000000000000 .quad 0x0000000000000000 /* 0x00: null descriptor */
.quad 0x00209A0000000000 .quad 0x00209A0000000000 /* 0x08: 64-bit code, DPL=0 */
.quad 0x0000920000000000 /* 0x10: data, writable, present */
gdt64_end:
gdt64_pointer: gdt64_pointer:
.word gdt64_pointer - gdt64 - 1 .word gdt64_end - gdt64 - 1
.quad gdt64 .quad gdt64