文章目录
01、中断和异常概述
协同式任务切换不一定要通过一个专门的接口例程进行,也可以用一般的例程进行。
用户任务通过调用门切换到内核的put_string
例程执行,在内核任务返回用户任务之前可以进行任务切换,之后再通过retf
返回用户任务执行。
- 硬件中断信号,
NMI
是不可屏蔽中断、INTR
是来自硬件中断引脚的可屏蔽中断。随机产生,与处理器是异步的。 - 软件中断,
INT n
是在软件内部主动引发的中断。 - 处理异常中断(
Exceptions
),是处理器内部产生的中断,表示处理器执行时产生了错误的状况。比如当处理器执行一条非法指令或者因条件不具备指令不能正常执行时将会引发这种类型的中断。如div指令
中除数是0
的情况。
中断和异常。
按照异常的产生原因分类:
- 指令执行异常:处理器在执行指令时检测到程序的错误并由此而引发的异常。
- 程序调试异常:供调试器使用,由
INTO、INT3
主动发起。用来检查特定的机器状态是否出现。INTO
检查标志寄存器的OF=1
(溢出标志)则执行指令引发异常。INT3
指令供调试器进行单步执行。 - 机器检查异常:和处理器架构有关,如在奔腾4、P6处理器家族上就实现了机器检查架构,用这种异常检测与硬件有关的总线错误、奇偶校验错误、高速缓存错误等等。
根据异常的性质和严重性分类:
- 故障(
Faults
):通常可以纠正,如缺页异常。中断程序返回的是当前指令。 - 陷阱(
Traps
):通常是在执行了截获陷阱条件的指令之后立即产生,通常用于调试INT3、INTO
。中断程序返回的是当前指令的下一条指令。 - 终止(
Aborts
):通常标志最严重的错误,如硬件错误、系统表错误(如GDT
、LDT
数据不一致、无效、错误),这类异常一般无法精确的报告引起错误的指令的位置。发生时程序和错误都不可能重新启动,双重异常(当处理器发生异常时,在转入异常执行时有发生了另外一个异常)如中断向量号18,INT 0x18
。
对于某些异常来说,处理器在转入异常处理程序之前,会在当前栈中压入一个称为错误代码的数值,这样可以帮助诊断异常产生的位置和原因。
02、保护模式下中断和异常的向量分配
中断和异常的编号叫做中断向量。
其中错误代码是在中断发生时,在进入中断处理程序之前压在栈中的错误代码。
03、中断描述符表、中断门和陷阱门
实模式下的中断向量表:
中断发生时,处理器要么自发产生一个中断向量、要么从软中断指令的操作数的到中断向量、或者从外部的中断控制器取得一个中断向量。将该向量作为索引访问中断向量表IVT
,具体做法是将中断向量乘以4作为偏移量访问IVT,从中取得中断处理过程的段地址和偏移地址,并转到那里执行。
保护模式下:使用中断描述符表IDT
(Interrupt Descriptor Table
),保存和中断处理过程相关的描述符,包括中断门、陷阱门、任务门,门是特殊的描述符。
中断门
描述符用来描述中断处理过程。
陷阱门
描述符用来描述陷阱中断的处理过程。
任务门,32位处理器中支持,若IDT
中描述的是一个任务门,则执行的是一个任务切换。在64位处理器中既不支持硬件任务切换、也不支持任务门。
实模式下的中断向量表IVT
只能位于内存的最低端。保护模式下的中断描述符表IDT
可以位于内存的任何位置。
IDT
的第一个描述符即0号槽位
也是有效的。
- 处理器用中断向量 乘以 8得到表内偏移量,联合
IDTR
内的IDT
基地址去访问内存; - 从中取得中断门或陷阱门描述符;
- 在描述符中有中断处理过程的代码段选择子和段内偏移量;
- 取决与代码段选择子的
TI位
,去GDT
或LDT
中取得目标代码段的描述符。 - 从目标代码段的描述符中取得目标代码段的段基地址;
- 将段基地址 和 偏移量相加得到中带处理过程的线性基地址,从而转移执行。
使用中断向量访问IDT
时,中断向量超过IDT
界限值时,就会产生常规保护异常#GP
。
04、本章程序介绍
引导程序:c13_mbr0.asm
- 1、取出
GDT
所在线性基地址 - 2、创建本程序相关描述符,接着使用
cli
指令关闭中断响应。 - 3、进入保护模式
- 4、加载内核代码到内存中
- 5、创建内核相关描述符
- 6、跳转执行内核
内核程序:c30_core0.asm
- 1、创建各个段的选择子常量和
IDT
线性地址; - 2、内核头部段;
- 3、内核公共历例程段,除了之前创建的相关历程,本章增加了几个和中断相关的例程;
- 4、内核核心数据段,各种数据。
- 5、内核核心代码段,改变了内核入口点
start
的程序。
用户程序0:c30_app0.asm
- 其他不变,死循环打印字符
,,,,,
。
用户程序1