assemblygccx86-64interruptosdev

General Protection Fault after setting up IDT then enabling STI


I'm new to OS dev and wanted to add an IDT to my hobby OS. Just after enabling the STI I receive a GPF. Now my ISR does receive interrupts correctly but I don't know what the problem is. I have a 64-bit OS.

#include "idt.h"
#include "isr.h"
#include "io.h" 
#include <stdint.h>

#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
#define PIC_EOI 0x20

#define ICW1_INIT 0x10
#define ICW1_ICW4 0x01
#define ICW4_8086 0x01

struct idt_entry idt[IDT_ENTRIES];
struct idt_ptr idtp;

extern void load_segment_selectors();
extern void idt_load(uint64_t);

static void idt_set_gate(int num, uint64_t base, uint16_t sel, uint8_t flags) {
    idt[num].base_low = base & 0xFFFF;
    idt[num].base_mid = (base >> 16) & 0xFFFF;
    idt[num].base_high = (base >> 32) & 0xFFFFFFFF;
    idt[num].sel = sel;
    idt[num].always0 = 0;
    idt[num].flags = flags;
    idt[num].reserved = 0;
}

static void pic_remap(int offset1, int offset2) {
    uint8_t a1, a2;

    a1 = inb(PIC1_DATA);
    a2 = inb(PIC2_DATA);

    outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); 
    outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
    outb(PIC1_DATA, offset1);
    outb(PIC2_DATA, offset2); 
    outb(PIC1_DATA, 4); 
    outb(PIC2_DATA, 2);

    outb(PIC1_DATA, ICW4_8086);
    outb(PIC2_DATA, ICW4_8086);

    outb(PIC1_DATA, a1); // Restore saved masks
    outb(PIC2_DATA, a2);

}

void init_idt() {
    idtp.limit = (sizeof(struct idt_entry) * IDT_ENTRIES) - 1;
    idtp.base = (uint64_t)&idt;

    for (int i = 0; i < IDT_ENTRIES; i++) {
        idt_set_gate(i, 0, 0, 0);
    }

    idt_set_gate(0, (uint64_t)isr0, 0x08, 0x8E); 
    idt_set_gate(1, (uint64_t)isr1, 0x08, 0x8E); 
    idt_set_gate(8, (uint64_t)isr8, 0x08, 0x8E);  
    idt_set_gate(13, (uint64_t)isr13, 0x08, 0x8E);
    idt_set_gate(14, (uint64_t)isr14, 0x08, 0x8E);
    idt_set_gate(32, (uint64_t)isr32, 0x08, 0x8E); 

    idt_load((uint64_t)&idtp);

    pic_remap(0x20, 0x28); 

    load_segment_selectors(); 

    enable_interrupts();
}

and the struct is

#ifndef IDT_H
#define IDT_H

#include <stdint.h>

#define IDT_ENTRIES 256

struct idt_entry {
    uint16_t base_low;
    uint16_t sel;
    uint8_t always0;
    uint8_t flags;
    uint16_t base_mid;
    uint32_t base_high;
    uint32_t reserved;
} __attribute__((packed));

struct idt_ptr {
    uint16_t limit;
    uint64_t base;
} __attribute__((packed));

void init_idt();

#endif

and the idt_load

global idt_load
global enable_interrupts

section .text

idt_load:
    cli                   ; Disable interrupts
    lidt [rdi]            ; Load IDT using the address in rdi (64-bit mode uses rdi for first argument)
    ret                   ; Return

enable_interrupts:
    sti                   ; Enable interrupts
    ret                   ; Return

I tried to see if the ISR was the problem but no, it wasn't. I commented out ISR and still received the GPF.

First few dumps.

Servicing hardware INT=0x20
     0: v=20 e=0000 i=0 cpl=0 IP=0008:0000000000100cf4 pc=0000000000100cf4 SP=0010:000000000010a000 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000000000000 RCX=000000000000008e RDX=00000000000000a1
RSI=000000000000008e RDI=00000000000000a1 RBP=0000000000000000 RSP=000000000010a000
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=0000000000100cf4 RFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000010 CCD=0000000000109fa8 CCO=EFLAGS
EFER=0000000000000500
check_exception old: 0xffffffff new 0x6
     1: v=06 e=0000 i=0 cpl=0 IP=0008:00000000001010d1 pc=00000000001010d1 SP=0010:0000000000109fd8 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000a RBP=0000000000000000 RSP=0000000000109fd8
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000001010d1 RFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000053 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0xd
     2: v=0d e=0032 i=0 cpl=0 IP=0008:00000000001010d1 pc=00000000001010d1 SP=0010:0000000000109fd8 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000a RBP=0000000000000000 RSP=0000000000109fd8
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000001010d1 RFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000053 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0x6
     3: v=06 e=0000 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:0000000000109fa0 env->regs[R_EAX]=000000000000001a
RAX=000000000000001a RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000a RBP=0000000000000000 RSP=0000000000109fa0
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=000000000000001a CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0xd
     4: v=0d e=0032 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:0000000000109fa0 env->regs[R_EAX]=000000000000001a
RAX=000000000000001a RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000a RBP=0000000000000000 RSP=0000000000109fa0
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=000000000000001a CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0x6
     5: v=06 e=0000 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:0000000000109f70 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000000000 RSP=0000000000109f70
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000002 CCO=ADDB
EFER=0000000000000500

here is the asked gpf dump:

check_exception old: 0xffffffff new 0x6
   845: v=06 e=0000 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:00000000001050b0 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000000000 RSP=00000000001050b0
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000002 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0xd
   846: v=0d e=0032 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:00000000001050b0 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000000000 RSP=00000000001050b0
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000002 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0x6
   847: v=06 e=0000 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:0000000000105080 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000000000 RSP=0000000000105080
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000002 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0xd
   848: v=0d e=0032 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:0000000000105080 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000000000 RSP=0000000000105080
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000002 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0x6
   849: v=06 e=0000 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:0000000000105050 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000000000 RSP=0000000000105050
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000002 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0xd
   850: v=0d e=0032 i=0 cpl=0 IP=0008:000000000000004c pc=000000000000004c SP=0010:0000000000105050 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000000000 RSP=0000000000105050
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000000004c RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000002 CCO=ADDB
EFER=0000000000000500
check_exception old: 0xffffffff new 0xe
   851: v=0e e=000a i=0 cpl=0 IP=0008:00000000001006b3 pc=00000000001006b3 SP=0010:0000000000105000 CR2=0000000000104ff8
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000105018 RSP=0000000000105000
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000001006b3 RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000104ff8 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000010 CCD=0000000000105008 CCO=SUBQ
EFER=0000000000000500
check_exception old: 0xe new 0xe
   852: v=08 e=0000 i=0 cpl=0 IP=0008:00000000001006b3 pc=00000000001006b3 SP=0010:0000000000105000 env->regs[R_EAX]=0000000000000002
RAX=0000000000000002 RBX=0000000000000000 RCX=0000000000000021 RDX=0000000000100042
RSI=0000000000000000 RDI=000000000000000d RBP=0000000000105018 RSP=0000000000105000
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000001006b3 RFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000100060 00000017
IDT=     0000000000101000 00000fff
CR0=80000011 CR2=0000000000104ff8 CR3=0000000000103000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000010 CCD=0000000000105008 CCO=SUBQ
EFER=0000000000000500
check_exception old: 0x8 new 0xe

Solution

  • So, the issue was that in kernel_main, it returns right after setting up the IDT, and then we end up back in main64.asm in long_mode_start, where it hits a hlt instruction. The problem is that hlt halts the CPU until the next interrupt occurs, like a timer. But when the first interrupt happens, there’s no code to run after the hlt. I should have done something like .hltloop: hlt jmp .hltloop so that the hlt would run in an infinite loop. Otherwise, the CPU could try to execute whatever comes after hlt, and that would lead to unpredictable behavior.

    Here is the fixed part.

    section .text
    bits 64
    long_mode_start:
        ; load null into all data segment registers
        mov ax, 0
        mov ss, ax
        mov ds, ax
        mov es, ax
        mov fs, ax
        mov gs, ax
    
        call kernel_main
    
    .hltloop:
        hlt
        jmp .hltloop