[读书笔记]30 天自制操作系统 day6 分割编译与中断处理
来源:互联网 发布:宿州煤电集团知乎 编辑:程序博客网 时间:2024/05/20 20:48
1. 分割源文件
- 由于原先的bootpack.c 太过冗长, 将他分割成几个部分
- 同时为了节省声明所占空间, 使用 头文件
2. 整理Makefile
- 将多个类似的编译规则, 使用一般规则进行合并, 简化书写
- 一般而言, 普通规则的优先级比一般规则要高 (类似于 C++ 模板 和 偏特化情形)
4. 意犹未尽
4.1 load_gdtr
_load_gdtr: ; void load_gdtr(int limit, int addr); MOV AX,[ESP+4] ; limit MOV [ESP+6],AX LGDT [ESP+6] RET
- 这里本质上涉及到 GDTR 寄存器的使用方式, 知道了他的使用方式就可以理解这段汇编代码的意思了
- GDTR 寄存器是 48bit 的, 他不能直接使用mov 操作, 如果需要对他进行赋值, 可以指定一个内存地址, 然后从这个地址中读取 6 个字节(48bit), 赋值给 GDTR 寄存器, 使用 LGDT 指令。
- 该寄存器低 16 bit (即 内存的最初的 2 个字节)为 段上限, 它等于 “GDT 的有效字节数 - 1”。剩下的高32 bit (剩余 4 个字节), 代表GDT 的开始地址。
- 由于我们的平台是 i386 平台, 所以采用的是小端字节序 http://blog.csdn.net/sky453589103/article/details/50595287
4.2 set_segmdesc
void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar){ if (limit > 0xfffff) { ar |= 0x8000; /* G_bit = 1 */ limit /= 0x1000; } sd->limit_low = limit & 0xffff; sd->base_low = base & 0xffff; sd->base_mid = (base >> 16) & 0xff; sd->access_right = ar & 0xff; sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0); sd->base_high = (base >> 24) & 0xff; return;}
- 这段代码实际上是用来设置 gdt 表的
- 我们首先来看一下 i386 平台中对 段寄存器的定义 http://blog.csdn.net/zhyh1435589631/article/details/50989569
- 由于历史遗留因素, base 地址 和 limit 字段被拆成了多个部分, limit字段 高位是段属性的设置
5. 初始化 PIC
- PIC 亦即 可编程中断控制器
init_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;}
- 其中 IMR 是 中断屏蔽寄存器, ICW 是初始化控制数据, ICW3 设定主从连接(确定是使用哪个IRQ 来通知CPU), ICW2 确定 使用哪一号中断。
6. 中断处理程序制作
- 首先编写 中断处理程序, 然后将程序注册到 IDT 表中, 即可
- 需要注意的是这里 鼠标使用 IRQ12, 键盘使用 IRQ1
- 相应调用代码:
void HariMain(void){ struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; char s[40], mcursor[256]; int mx, my; init_gdtidt(); init_pic(); io_sti(); /* IDT/PICの初期化が終わったのでCPUの割り込み禁止を解除 */ init_palette(); init_screen8(binfo->vram, binfo->scrnx, binfo->scrny); mx = (binfo->scrnx - 16) / 2; /* 画面中央になるように座標計算 */ my = (binfo->scrny - 28 - 16) / 2; init_mouse_cursor8(mcursor, COL8_008484); putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16); sprintf(s, "(%d, %d)", mx, my); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); io_out8(PIC0_IMR, 0xf9); /* PIC1とキーボードを許可(11111001) */ io_out8(PIC1_IMR, 0xef); /* マウスを許可(11101111) */ for (;;) { io_hlt(); }}
0 0
- [读书笔记]30 天自制操作系统 day6 分割编译与中断处理
- 《30天自制操作系统》读书笔记Day6
- 《30天自制操作系统》 day6 小结
- [读书笔记]30 天自制操作系统 day10 叠加处理
- [读书笔记]30 天自制操作系统 day7 FIFO与鼠标控制
- 第6天 分割编译与中断处理
- 6、分割编译与中断处理
- 06day 分割编译与中断处理
- 读书笔记《30天自制操作系统》day01
- 读书笔记《30天自制操作系统》day02
- 读书笔记《30天自制操作系统》day03
- 读书笔记《30天自制操作系统》day04
- 读书笔记《30天自制操作系统》day05
- 读书笔记《30天自制操作系统》day06
- 读书笔记《30天自制操作系统》day07
- 读书笔记《30天自制操作系统》day08
- 读书笔记《30天自制操作系统》day09
- 读书笔记《30天自制操作系统》day10
- POJ 2104 K-th Number 平方分割
- 安装和使用EPEL源linux安装包进行扩展
- 真正决定人生高度的,是你做事的速度
- mySql数据库备份与恢复
- 第十四周课后作业——项目一(4)
- [读书笔记]30 天自制操作系统 day6 分割编译与中断处理
- 20161206全志R16暂时没有发现只会ubuntu,全志H3可以支持UbuntuCore
- 1206
- Java多线程之Thread VS Runnable(根据慕课网视频编写)
- 工厂方法模式
- 在framework.jar和services.jar中增加新类
- YOLO源码详解(四)- 反向传播(back propagation)
- 穷是因为慢半拍
- jsp EL表达式截取字符串