设置 IDT 然后启用 STI 后出现一般保护故障 [已解决]

问题描述 投票:0回答:1

我是操作系统开发新手,想将 IDT 添加到我的爱好操作系统中。启用 STI 后,我立即收到 GPF。现在我的 ISR 确实正确接收中断,但我不知道问题是什么。我有 64 位操作系统。

#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();
}

结构是

#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

和 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

我尝试查看 ISR 是否是问题所在,但不是。我注释掉了 ISR,但仍然收到了 GPF。

前几次转储。

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

这是要求的 gpf 转储:

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
assembly gcc x86-64 interrupt osdev
1个回答
3
投票

所以,问题是在 kernel_main 中,它在设置 IDT 后立即返回,然后我们最终回到 long_mode_start 中的 main64.asm 中,在那里它遇到了 hlt 指令。问题是 hlt 会暂停 CPU,直到下一个中断发生,就像计时器一样。但是当第一个中断发生时,hlt 之后没有代码可以运行。我应该做类似 .hltloop: hlt jmp .hltloop 这样的事情,这样 hlt 就会无限循环运行。否则,CPU 可能会尝试执行 hlt 之后的任何内容,这将导致不可预测的行为。

这是固定部分。

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
© www.soinside.com 2019 - 2024. All rights reserved.