2016年4月29日

时间:2022-01-15 13:49:24

全局描述符表 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

此处是具体的汇编代码,待填。。。