fix: correct 64-bit IDT gate descriptor layout to prevent triple fault on keypress

Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4.6) <aider@aider.chat>
This commit is contained in:
2026-05-05 21:28:27 +03:00
parent 75ddd75ab9
commit 9c242187ea
+31 -10
View File
@@ -50,16 +50,37 @@ static void serial_init(void) {
outb(0x3F8 + 4, 0x0B); outb(0x3F8 + 4, 0x0B);
} }
static uint64_t idt_entries[256][2]; /* Each 64-bit IDT entry is 16 bytes = two uint64_t words.
*
* Word 0 layout:
* [15: 0] offset[15:0]
* [31:16] segment selector
* [34:32] IST (0 = no IST)
* [39:35] reserved (0)
* [47:40] type+attr (0x8E = present, DPL=0, 64-bit interrupt gate)
* [63:48] offset[31:16]
*
* Word 1 layout:
* [31: 0] offset[63:32]
* [63:32] reserved (0)
*/
typedef struct {
uint64_t low;
uint64_t high;
} __attribute__((packed)) IdtEntry;
static IdtEntry idt_entries[256];
static void idt_set_gate(int vector, uint64_t offset, uint16_t selector, uint8_t type_attr) { static void idt_set_gate(int vector, uint64_t offset, uint16_t selector, uint8_t type_attr) {
uint64_t low = (offset & 0xFFFFULL) | uint64_t low =
((uint64_t)selector << 16) | (offset & 0x000000000000FFFFULL) | /* offset[15:0] */
((uint64_t)(type_attr & 0xFF) << 40) | ((uint64_t)selector << 16) | /* selector */
((offset & 0xFFFF0000ULL) << 32); /* bits 34:32 = IST=0, bits 39:35 = 0 */
uint64_t high = offset >> 32; ((uint64_t)type_attr << 40) | /* type+attr */
idt_entries[vector][0] = low; ((offset & 0x00000000FFFF0000ULL) << 32); /* offset[31:16] */
idt_entries[vector][1] = high; uint64_t high = offset >> 32; /* offset[63:32] */
idt_entries[vector].low = low;
idt_entries[vector].high = high;
} }
static struct { static struct {
@@ -224,8 +245,8 @@ void kernel_main(void) {
serial_init(); serial_init();
idt_set_gate(0x21, (uint64_t)isr_keyboard, 0x08, 0x8E); idt_set_gate(0x21, (uint64_t)isr_keyboard, 0x08, 0x8E);
idt_ptr.limit = sizeof(idt_entries) - 1; idt_ptr.limit = (uint16_t)(sizeof(idt_entries) - 1);
idt_ptr.base = (uint64_t)idt_entries; idt_ptr.base = (uint64_t)(uintptr_t)idt_entries;
__asm__ volatile ("lidt %0" : : "m"(idt_ptr)); __asm__ volatile ("lidt %0" : : "m"(idt_ptr));
pic_remap(); pic_remap();