Linux 0.11中断机制解读
Linux 0.11中断机制解读
在bios启动的时候首先使用的是bios自带的中断服务函数,int 0x13和int 0x19。
在setup.s里面关中断:将EFLAGS置为0。setup将head.s和内核代码搬运到0x0000开始的地址处,覆盖了原BIOS的中断函数部分,废除了BIOS的中断函数机制。故事就从这里开始。
与中断相关的标志位:iF 中断许可(第 9 位)
中断服务函数挂接
外部中断、软件中断和异常是通过中断描述符表(IDT)处理的。 IDT 中包含访问中断和异常处理程序的门描述符的集合。像 GDT 一样,IDT 不是一个段, IDT 的线性基地址包含在 IDT 寄存器中(IDTR)。
异常处理类中断服务函数
trap_init();函数把中断异常处理服务程序与IDT进行挂接
将异常处理函数插入IDT的表项是由set_trap_gate()和set_system_gate()函数来完成的
1 | void trap_init(void) |
1 |
|
1 |
|
这里面的偏移地址,就是段偏移再加上gdt里面的段基址就得到了真正的线性地址
这里本来edx里面有着完整的中断服务程序段偏移地址:"d" ((char *) (addr)),为了配合中断描述符,强行把低字部分给了eax(movw %%dx,%%ax\n\t)。
注意,前两条汇编这部分代码一直是在对寄存器进行操作,还没有放到内存里面,后面再添到&idt[0]里面
中断描述符
1 | "i" ((short) (0x8000+(dpl<<13)+(type<<8))) |
movw %%dx,%%ax\n\t将edx的低字赋值给eax,也就是÷_error的低字,使得中断服务程序偏移地址符合上述中断描述符
系统描述符:,这里的1111即_set_gate(gate_addr,type,dpl,addr)里面的type,属于系统描述符,从下面这张表中可以看出这里15是32位的陷阱门。
例如这个输入的是14就是32位中断门
1 |
IDT的变迁
系统调用
system_call路径: