对应labOS版本1.3
程序源码可以私聊我
picirq.h
int 0x20~0x2f
接收中断信号IRQ0~15
,因为int 0x00~0x1f
不能用于IRQ。
picirq.c
-
pic0_mask=0xfb
即1111 1011
;PIC1以外全部禁止。pic1_mask=0xff
即1111 1111
;禁止所有中断 -
pic_enable
函数就是将irq_num
即IRQ号屏蔽取消 -
当一个外部中断请求通过中断请求线
IRQ
传输到IMR(中断屏蔽寄存器)
,IMR根据设定的中断屏蔽字决定丢弃还是接受。 -
主从PIC如下如所示,PIC是一个8259A芯片,上面有一些引脚,其中包括了ICW、OCW等引脚。
-
每一个8259A芯片都有两个I/O ports,程序员可以通过它们对8259A进行编程。
Master 8259A的端口地址是0x20,0x21;Slave 8259A的端口地址是0xA0,0xA1。 -
EOI:end of interrupt
kbd.h
- 键盘按键参考
https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_1
int_handlers.c
- 键盘控制器是8042(PS/2)芯片,它的作用是接收和解码来自键盘的数据并放到缓冲区,然后通知8259A产生IRQ1。
- 读缓冲区,读0x60端口
- 写缓冲区,写0x60端口
- 读状态寄存器,读0x64端口
- 控制寄存器,写0x64端口
- 其中读出的缓存数据0xe0和0xe1是特殊键值需要单独处理
- 键盘抬起产生的数值=按下产生的数值+0x80
init.c
- CR3寄存器存储的是页目录表页面起始物理地址,因为页目录表都是4KB对齐,因此只有高20位是有效的。低12位有其他用处。
- CR0寄存器最低位是PE保护模式标志位,最高位是PG分页模式标志位。
- 启动分页机制需要三步:1、准备好页目录表和页表;2、将页表地址写入CR3;3、将CR0的PG位制1。
- 另外启动分段或者启动分页,也就是修改CR0的相关位置后,以后都是由硬件自动进行地址的转换。
- 再记录一下中断的开发。先定义好函数声明和函数实现,然后再GDT表初始化完成的基础上用中断函数指针去初始化IDT表,然后再做好IDTR,这样就可以根据中断号去找中断函数了。然后需要注意的是什么中断对应什么编号是由硬件本身决定的,比如
https://logix.cz/michal/doc/i386/chp09-08.htm#09-08
,然后重点是要设置IMR取消对此中断的屏蔽,这样当下次产生中断时,硬件根据自身情况产生中断号,经过IDTR找IDT,然后找到相应的中断处理函数执行。这样就完成了一次中断处理。
最后的运行效果