EDIT:对于源代码,您可以查看我在Github上的repo: https://github.com/tuhdo/os-study.
我将2个pic (x86)上的irq映射到IDT中的第32条及以后的入口。为了测试PIC中断,我将前31个例程放在同一个函数中。问题是,我无法获得第15个中断条目的工作,因为它是根据中断向量表保留的。也就是说,每当我进入保护模式时,在启用cr0
中的模式并跳转到内核空间中的第一条指令(stage2.asm
中的最后一行,即jmp 08h:0xFF0
),它就会崩溃(在Bochs中,它跳转到地址f000:fff0
,这在出现问题时发生)。在不添加第15个条目的情况下,我可以执行所有代码并正确地终止hlt
指令。
由于条目是保留的,我应该怎么做才能跳过15h条目?目前,我的通用IDT条目看起来像这样:
;; IRQ0
dw 0
dw 0x30 ; gdt selector 0x30
db 0
db 011001110b ; interrupt gate callable from userspace
dw 0
相关代码在gdt中。Inc .和idt.inc.。我的操作系统有一些基本功能:
- 引导装载程序
- 32位保护模式
- 系统调用(从用户空间到内核再返回)
- 初始中断支持:到目前为止,我可以处理除0或显式中断调用(即
int 1
)。我已经激活了PIC (PIC .inc),并且想尝试一下,因为我在0x32处映射了PIC中断。但是,在添加了第15条IDT条目后,我出现了三重故障,而第14条及以下的我没有出现这种问题。
我知道哪里不对了。原因是,我只为stage2.asm
分配了一个扇区,但是添加更多的条目会使阶段2引导加载程序超过512字节。由于这个原因,IDT在加载和发生故障时变得畸形。
我改变了Makefile
中的这一行,它只分配了1个扇区:
dd if=$(BUILD_DIR)/stage2.bin of=disk.dsk bs=512 count=1 seek=1
分配3个扇区:
dd if=$(BUILD_DIR)/stage2.bin of=disk.dsk bs=512 count=3 seek=1
我知道我应该开始编写一个文件系统,但我将稍后再做,因为内核对我来说具有更高的优先级。