<30天自制操作系统>第六天
来源:互联网 发布:剑三明教成女捏脸数据 编辑:程序博客网 时间:2024/05/16 23:50
为了让鼠标能移动起来,必须使用中断,而要使用中断则必须将GDT和IDT初始化。在此之前,首先要初始化PIC,它的意思是可编程中断控制器。它是将多个中断信号集合成一个中断信号的装置,PIC检测着输入管脚的多个中断信号,只要有一个中断信号过来,就将唯一的输出管脚信号变成ON,并通知给CPU。
其中与CPU直接相连的PIC为主PIC,与主PIC相连的PIC称为从PIC。其中从PIC通过第2号IRQ与主PIC相连。
PIC设定如下:
void init_pic(void)/* PIC的初始化 */{ io_out8(PIC0_IMR, 0xff ); /* 禁止所有中断 */ io_out8(PIC1_IMR, 0xff ); /* 禁止所有中断 */ io_out8(PIC0_ICW1, 0x11 ); /* 边沿触发模式 */ io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7由INT20-27接收 */ io_out8(PIC0_ICW3, 1 << 2); /* PIC1由IRQ2连接 */ io_out8(PIC0_ICW4, 0x01 ); /* 无缓冲区模式 */ io_out8(PIC1_ICW1, 0x11 ); /* 边沿触发模式 */ io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15由INT28-2f接收 */ io_out8(PIC1_ICW3, 2 ); /* PIC1由IRQ2连接 */ io_out8(PIC1_ICW4, 0x01 ); /* 无缓冲区模式 */ io_out8(PIC0_IMR, 0xfb ); /* 11111011 PIC1以外全部禁止 */ io_out8(PIC1_IMR, 0xff ); /* 11111111 禁止所有中断 */ return;}
从CPU角度看,PIC是外部设备,CPU使用OUT指令进行操作。
PIC的寄存器都是8位寄存器,其中IMR是中断屏蔽寄存器。ICW是初始化控制数据。ICW有4个,其中ICW1与ICW4与主板配线方式、中断信号的电气特性有关。ICW3是有关主从连接的设定。ICW2则决定哪一号中断通知CPU。至于为什么从INT20开始,原因是0x00~0x1f已经被操作系统所用,当应用程序对操作系统干坏事时,CPU内部会自动产生INT0x00~0x1f,如果IRQ与这些号码重复,则CPU会分不清它到底是IRQ还是CPU的系统保护通知。
初始化完PIC之后就可以来设定鼠标中断和键盘中断了,它们分别对应IRQ12和IRQ1。代码如下:
void inthandler21(int *esp)/* 来自PS/2键盘的中断 */{ struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 21 (IRQ-1) : PS/2 keyboard"); for (;;) { io_hlt(); }}void inthandler2c(int *esp)/* 来自PS/2鼠标的中断 */{ struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 2C (IRQ-12) : PS/2 mouse"); for (;;) { io_hlt(); }}
有了相关的中断函数,则进行注册,注册语句如下:
set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);
asm_inthandler21注册在idt的第0x21号,如果中断发生,CPU会自动调用asm_inthandler21,2 * 8表示的是asm_inthandler21属于哪一个段,即段号是2,乘以8是因为低3位有别的意思。对于号码段为2的段,有如下设置:
set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);
该段涵盖了整个bootpack。最后的AR_INTGATE32将IDT的属性设定为0x008e,表示这是中断处理的有效设定。
- 30天自制操作系统-第六天
- <30天自制操作系统>第六天
- 《30天自制操作系统》学习笔记——第六天
- 30天自制操作系统
- 30天自制操作系统
- 30天自制操作系统
- 30天自制操作系统
- 30天自制操作系统 导读
- [30天自制操作系统]day_2
- 30天自制操作系统day00
- 30天自制操作系统day01
- 30天自制操作系统day02
- 30天自制操作系统(1)
- 30天自制操作系统day2
- 30天自制操作系统day3
- 30天自制操作系统day4
- 30天自制操作系统day5
- 30天自制操作系统day7
- 第一次机房收费系统--安装连接之初体验
- #pragma预编译的使用
- 好模板收藏地址
- Spring Aop实例(XML形式)
- PHP中session的工作原理
- <30天自制操作系统>第六天
- Android博客周刊第28期
- 使用Myeclipse + SVN + TaoCode 免费实现项目版本控制的详细教程
- iOS-深复制(mutableCopy)与浅复制(copy)
- hdu5725 Game 2016年多校C
- 三分法
- 使用js实现表格增加与删除
- css实现动态进度条
- HDU5120Intersection(两圆环相交的面积)