30天自制操作系统(Mac版)读书笔记(day6)

初始化PIC和IDT

  1. PIC ,prograrnmable interrupt controller ,可编程中断控制器,从书上的描述,这里我们可以把这种东西理解成事件与回调函数,上层的UI程序在处理键盘鼠标事件也是同样的方法,绑定一段代码给某个时间,在操作系统中,键盘和鼠标在敲击的时候,会产生一些列中断,PIC就是产生事件的地方,CPU会把事件和对应的汇编代码绑定。
  2. 书上介绍了一般电脑都有两个PIC,然后两个级联。然后各种概念啥的,在这里,我们大概理解一下就行了,不用太在意细节。特别是init_pic函数,不用理解其具体含义,因为和芯片初始化相关的,知道了也没啥作用。
  3. 主要注意调用过程中,需要加上以下代码去打开键盘的中断通知。
io_out8(PIC0_IMR, 0xf9);
io_out8(PIC1_IMR, 0xef);
  1. 做到PIC的初始化还是不够的,还需要加上IDT(Interrupt Descriptor Table),这部分是在 day5里面说的。在刚刚#1中,说到,PIC是产生中断的地方,那么绑定中断和对应的函数的地方叫做IDT,这里初始化的代码如下:
LABEL_IDT:
%rep  255
    Gate  SelectorCode32, SpuriousHandler,0, DA_386IGate //配置中断调用函数
%endrep

IdtLen  equ $ - LABEL_IDT
IdtPtr  dw  IdtLen - 1
        dd  0
    xor   eax, eax
    mov   ax,  ds
    shl   eax, 4
    add   eax, LABEL_IDT
    mov   dword [IdtPtr + 2], eax
    lidt  [IdtPtr]

    sti //这里有被坑到,打开终端的意思。
_SpuriousHandler: //加上IDT对应的函数实现,其实就是调用C实现的函数。
SpuriousHandler  equ _SpuriousHandler - $$
     push es
     push ds
     pushad
     mov  eax, esp
     push eax

     call intHandlerFromC

     pop  eax
     mov  esp, eax
     popad
     pop  ds
     pop  es

     sti
    
     iretd

  1. C函数的实现。我们先实现一个简单的。
void intHandlerFromC() {
	char * vram = (char *) 0xa0000;
	showString(vram, 320, 0, 0, COL8_FFFFFF, "Hello");
}
  1. 运行一下,发现敲击任何键,屏幕都会打印Hello,说明,我们的系统已经接收到了键盘的时间消息了。

识别某个键

修改 intHandlerFromC如下:

char charToHexVal(char c) {
    if (c >= 10) {
        return 'A' + c - 10;
    } 
    return '0' + c;
}
char*  charToHexStr(unsigned char c) {
    int i = 0;
    char mod = c % 16;
    keyval[3] = charToHexVal(mod);
    c = c / 16;
    keyval[2] = charToHexVal(c);
    return keyval;
}
void intHandlerFromC() {
	char * vram = (char *) 0xa0000;
    io_out8(PIC0_OCW2, 0x21);
    unsigned char data = 0;
    data = io_in8(PORT_KEYDAT);
	char* pStr = charToHexStr(data);
	static int showPos = 0;
	showString(vram, 320, showPos, 0, COL8_FFFFFF, pStr);
	showPos += 32;
}

鼠标的支持

  1. 调试过程中发现,之前的代码中,并没有初始化栈的GDT,需要抄一下代码。
  2. 然后修改init_pic里的值,添加对鼠标的支持。
io_out8(PIC0_IMR,  0xfb  ); 
io_out8(PIC1_IMR,  0xef  );
  1. 添加init_keyboard和enable_mouse两个函数,还有一些io_sti和io_stihlt等函数,感觉不是很理解,先把程序跑起来吧。
  2. 在IDT里面添加鼠标中断的函数回调。
%rep  10
    Gate  SelectorCode32, SpuriousHandler,0, DA_386IGate
%endrep
.2CH:
    Gate SelectorCode32, mouseHandler,0, DA_386IGate

实现一个FIFO的队列

这里可以理解成两个线程,一个是主程序的主线程,一个是事件线程,但实际上并没有分开线程,只是打个比方。在这里,主线程中读取队列中的数据,事件回掉负责写入数据。

下一篇是day9,day7和day8内容比较少

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值