《30天自制操作系统》学习笔记(六)
本文关键词:30天自制操作系统,由笔耕文化传播整理发布。
《30天自制操作系统》学习笔记(六)
发表于2016/7/3 14:51:55 99人阅读
分类: 操作系统
IDT学习心得
(一)什么是中断?
通常被定义为一个事件,该事件改变处理器执行的指令顺序。例如通过键盘输入、点击鼠标等
(二)为什么要引入中断?
因为CPU的处理速度远高于外围硬件设备的响应速度,为了提高CPU的利用率,所以引入了中断机制。当某个设备发生变化时便会产生中断,CPU就暂时停止正在处理的事务,并做好接下来能够继续处理的准备,转而执行中断程序。中断执行完以后,在调用事先设定好的函数,返回处理中的任务。这样CPu可以不用一直查询外围硬件设备的状态,而将精力放在处理任务上。
(三)由中断机制引出的问题--当发生中断时,如何告诉CPU该做些什么?
通过中断描述,中断描述符包括了中断门描述符、陷阱门描述符和任务门描述符
(四)中断描述符如何存储?
与GDT类似,中断描述符也是在内存中连续存储,形成了一个中断描述符表(Interruptor Descriptor Table,IDT),所以要想正确使用中断,必须正确设置GDT和IDT。
(五)CPU如何查找IDT?
与GDT的原理一样,利用了一个叫IDTR的寄存器(注意此处是寄存器,不是内存了,需要和IDT区别对待)。GDTR中高32位表示GDT在内存中的基地址,低16位表示表界限,所以就明确的给出了GDT在内存中的存储信息。
通过中断门描述符的结构图可知,其中存储了16位的段选择符(Segment Selector),CPU根据这个段选择符,从GDT中选择相应的段描述符(Segment Descriptor),并执行相应的代码。如下图。
(七)中断向量又是什么?
其实每一种中断(异常)都会对应一个中断向量号,具体有哪些中断向量,可以看下表:
向量号 助记符 描述 类型 出错码 源
0 #DE 除法错 Fault 无 DIV和IDIV指令
1 #DB 调试异常 Fault/Trap 无 任何代码和数据的访问
2 — 非屏蔽中断 Interrupt 无 非屏蔽外部中断
3 #BP 调试断点 Trap 无 指令INT 3
4 #OF 溢出 Trap 无 指令INTO
5 #BR 越界 Fault 无 指令BOUND
6 #UD 无效(未定义)操作码 Fault 无 指令UD2或无效指令
7 #NM 设备不可用(无数学协处理器) Fault 无 浮点或WAIT/FWAIT指令
8
#DF
双重错误
Abort
有(0)
所有能产生异常或NMI或INTR
的指令
9
异常)
10 #TS 无效TSS Fault 有 任务切换或访问TSS时
11 #NP 段不存在 Fault 有 加载段寄存器或访问系统段时
12 #SS 堆栈段错误 Fault 有 堆栈操作或加载SS时
13 #GP 常规保护错误 Fault 有 内存或其他保护检验
14 #PF 页错误 Fault 有 内存访问
15 — Intel保留,未使用
16 #MF x87FPU浮点错(数学错) Fault 无 x87FPU浮点指令或WAIT/FWAIT指令
17 #AC 对齐检验 Fault 有(0) 内存中的数据访问(486开始支持)
18
#MC
Machine Check
Abort
无
错误码(若有的话)和源依赖于
具体模式(奔腾CPU开始支持)
19
#XF
SIMD浮点异常
Fault
无
SSE和SSE2浮点指令(奔腾三
开始支持)
20~31 — Inter保留,未使用
32~255 — 用户定义中断 Interrupt
上表中除了两个Interrupt(中断)外,其他还有三种Fault、Trap、Abort异常。我们这里讨论的中断主要是用户定义中断,这种中断产生的原因有两种:一是外部中断,就是由硬件产生的中断;另一种是由指令int n产生的中断。
外部中断的情况则复杂一些,因为需要建立硬件中断和向量号之间的对应关系。外部中断的简单示意图如下:
(八)如何将中断向量与中断描述联系起来
1.通过对8259A的配置,可将IRQ0~IRQ7对应到中断向量20h~27h,同样地IRQ8~IRQ15可对应到中断向量28h~2Fh。书中给出的代码如下:
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;
}
2.制作中断处理程序
3.注册到IDT中
void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{
gd->offset_low = offset & 0xffff;
gd->selector = selector;
gd->dw_count = (ar >> 8) & 0xff;
gd->access_right = ar & 0xff;
gd->offset_high = (offset >> 16) & 0xffff;
return;
}
struct GATE_DESCRIPTOR *gd--表示要注册的IDT位置
int offset--偏移(这个偏移是在代码段中的偏移)
int selector--对应的段描述符的选择子
4.调用
例如set_getdesc(idt+0x21,(int)asm_inthandler21,2*8,AR_INTGATE32)
本文关键词:30天自制操作系统,由笔耕文化传播整理发布。
,本文编号:317020
本文链接:https://www.wllwen.com/wenshubaike/mishujinen/317020.html