全局描述符表 gdtr
中断描述符表 idtr
与中断相关的中断向量i(0~255),cpu固定的,8255,初始化都是在start kernel时做,要找到一个程序-》两个部分代码段基址和偏移量(代码段中可以有一个程序也可以多个)
->>读idtr寄存器指向的IDT表中的第i项,idtr+8×i,(来确定gdtr的第几项)
->>从gdtr获得GDT的基地址,并在GDT中查找,以读取IDT中的段选择符所标识的段描述符(gdtr+cs*8),再使用IDT里的offset
IDT(段选择因子,偏移量,权限(执行这个中断程序所具有的权限?))
X86中程序的跳转 段机制+段内偏移
->>确定中断是由授权的发生原发出的
中断:中断处理程序的特权不能低于引起中断的程序的特权(对应GDT表项中的DPL >= cs寄存器中的CPL)(禁止低特权等级用户访问特殊的门)
编程异常:还需比较CPL与对应IDT表项的DPL(引起引起异常的指令。。。???)
--》》检查是否发生了特权等级的变化,一般指是否由用户态进入了内核态,如果由用户态陷入了内核态,控制单元必须开始使用与新的特权等级相关的堆栈
中断上下文在内核态,中断只在内核态工作
a.读tr寄存器,访问运行进程的tss段,在进程的thread_info中
b.用与新特权等级相关的栈段和栈指针装载ss和esp。这些值可以在进程的tss段中找到
c.在新的栈中保存ss和esp以前的值,这些值指明了与旧特权等级相关的栈的逻辑地址。
--》
--》》在栈中保存eflag cs和eip
-->>如果产生来了一个硬件出错吗
--》》装载cs和eip,IDT表中第i项门描述符的段
两张示意图,从用户态进入和从内核态进入
恢复
如何初始化中断描述符表?
内核启动前,初始化IDT,包IDT的基地址装载到idtr中
int 指令(是个异常)
IDT的DPL设置为3来允许模拟
中断门
系统门 特权等级3
陷进门
trap_init(异常,
这个是第二次初始化)
内核编译完成后,中断处理程序的地址确定了
初始化中断描述符表
此处程序代码 代码分析
就是往里面填中断处理程序的地址
异常处理过程
进一步保存现场。。。
三步:1.进一步保存现场 2.调用C语言函数 3.
error_code函数的执行过程:保存现场,取出错误号给edx,把当前栈顶指针赋给eax,在当前栈顶指正加一个常数取出C语言函数,调用此函数(赋值给cs:eip)
中断处理
门种类,短选择因子,权限 ,偏移量,保留位
初始化在cpu开中断之前!
第一次初始化,把表中所有的中断处理程序都设置为同样的一个函数。
setup_idt()都设置为ignore_int
此处是具体的汇编代码,待填。。。