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:
+31
-10
@@ -50,16 +50,37 @@ static void serial_init(void) {
|
||||
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) {
|
||||
uint64_t low = (offset & 0xFFFFULL) |
|
||||
((uint64_t)selector << 16) |
|
||||
((uint64_t)(type_attr & 0xFF) << 40) |
|
||||
((offset & 0xFFFF0000ULL) << 32);
|
||||
uint64_t high = offset >> 32;
|
||||
idt_entries[vector][0] = low;
|
||||
idt_entries[vector][1] = high;
|
||||
uint64_t low =
|
||||
(offset & 0x000000000000FFFFULL) | /* offset[15:0] */
|
||||
((uint64_t)selector << 16) | /* selector */
|
||||
/* bits 34:32 = IST=0, bits 39:35 = 0 */
|
||||
((uint64_t)type_attr << 40) | /* type+attr */
|
||||
((offset & 0x00000000FFFF0000ULL) << 32); /* offset[31:16] */
|
||||
uint64_t high = offset >> 32; /* offset[63:32] */
|
||||
idt_entries[vector].low = low;
|
||||
idt_entries[vector].high = high;
|
||||
}
|
||||
|
||||
static struct {
|
||||
@@ -224,8 +245,8 @@ void kernel_main(void) {
|
||||
serial_init();
|
||||
|
||||
idt_set_gate(0x21, (uint64_t)isr_keyboard, 0x08, 0x8E);
|
||||
idt_ptr.limit = sizeof(idt_entries) - 1;
|
||||
idt_ptr.base = (uint64_t)idt_entries;
|
||||
idt_ptr.limit = (uint16_t)(sizeof(idt_entries) - 1);
|
||||
idt_ptr.base = (uint64_t)(uintptr_t)idt_entries;
|
||||
__asm__ volatile ("lidt %0" : : "m"(idt_ptr));
|
||||
|
||||
pic_remap();
|
||||
|
||||
Reference in New Issue
Block a user