[第6天] 中断

       坑爹的一周终于过去了,今天去考了所谓的java证书,一天学习的东西还能应付应付。但是那考卷质量不行,估计这结果也是可以是水水过的。所以一有时间,我就开始第六天。毕竟我的目标是学习linux,要抓紧时间,先实现一个自己的。今天也把GDT大概搞清楚了。而且今天学了键盘的中断,感觉还是蛮好的。虽然掉进一个坑。

分割文件:

        kernel.c文件太大了,必须分开处理。现在的分割为4个,如下:

  1. graphic.c: 处理图像绘制,界面等
  2. init.c: kernel入口
  3. dsctbl.c: GDT和IDT初始化
  4. int.c: 中断设置

      Makefile用通配符,可以同时编译依赖关系,免得写上一大坨。还学到了ld -r选项,relocatable,就可以把这些.o文件都重新整合起来。所以代码还是见github

GDT理解:

        感觉今天最大的收获,是搞明白了GDT。原本以为GDT会影响代码的跳转,后来看看资料,发现GDT的作用就是分割内存,保护系统和机器。CS,SS等寄存器不影响代码的执行和跳转。我现在实现的还只是Flat Setup,就是系统代码段使用32bits地址空间,系统数据段也是使用全部内存。这当然不能实现数据隔离,但是目前我还没有真正区别开数据和代码,所以先这样不管。能运行就好。GDT的意义如下:

580px-SegmentDescriptor.svg

       要注意的是,Base是分成3块的。还有G,DB,A各种意义,可以直接网上找。要注意这只是一条GDT。可以设置很多记录。当然进入保护模式,必不可少的有3个记录。Null Segment,Code Segment,Data Segment。Null是保留的,无意义,起始位置是0x00,Code Segment为0x08,Data Segment为0x10,因为每个有8 bytes。以此类推下去。当要跳转时, jmp CODE_SEG:init_pm ,CODE_SEG就是0x8。CPU就会自动将该地址描述的GDT内容读入。大概是这样,估计还有点理解错误。还有IDT,没去搞。

中断处理:

        中断处理,先要初始化PIC,我就直接抄代码,跳过了。直接IRQ,IRQ是指Interrupt Request。用INT 0x20-INT 0x2f,接收IRQ0~15, (因为INT 0x1f之前是CPU自己用的)。鼠标对应的中断是IRQ12,键盘是IRQ1,因此要处理INT 0x2c和INT 0x21。先要注册中断处理程序。其中_asm_inthandler是用汇编写的处理程序。1*8 指第一块GDT,我就傻逼了。作者用的是2*8,因为作者把第二块当作代码段,不按常理出牌啊!害我搞了半天。中断发生后总是会自动重启。因为这用的是数据段,不能执行。所以CPU启动了保护机制。

         说是使用_asm_inthandler处理,其实是在中间CALL了C写的函数。比如INT 0x21的真正出来函数为:

 最后的键盘中断,鼠标还没有完成,要到下一天。

SlefMouse

链接:

  1. Makeflie ld
  2. GDT and IDT