Linux内核设计学习_main函数之前过程(一)

来源:互联网 发布:中国高铁 知乎 编辑:程序博客网 时间:2024/06/07 03:53

    setup程序为保护模式做准备,通过setup程序自身提供的数据信息对中断描述符表(IDTR)和全局描述符表(GDTR)进行初始化设置。

    GDT(Global Descriptor Table),在系统中唯一的存放段寄存器内容(段描述符)的数组,配合程序进行保护模式下的段寻址。它在操作系统的进程切换中具有重要意义,可理解为所有进程的总目录表,其中存放每一个任务(task)局部描述符表(LDT,Local Descriptor Table)地址和任务状态段(TSS,Task Structures Segment)地址,完成进程中各段的寻址、现场保护与现场恢复。

    GDTR(Global Descriptor Table Register,GDT基地址寄存器),GDT可以存放在内存的任何位置。当程序通过段寄存器引用一个段描述符时,需要取得GDT的入口,GDTR标识的即为此入口。在操作系统对GDT的初始化完成后,可以用LGDT(Load GDT)指令将GDT基地址加载至GDTR。

    IDT(Interrupt Descriptor Table,中断描述符表),保存保护模式下所有中断服务程序的入口地址,类似于实模式下的中断向量表。

    IDTR(Interrupt Descriptor Table Register,IDT基地址寄存器),保存IDT的起始地址。

   32位的中断机制和16位的中断机制,在原理上有比较大的差别。最明显的是16位的中断机制用的是中断向量表,中断向量表的起始地址在0x00000处,这个位置是固定的;32位的中断机制用的是中断描述符表(IDT),位置是不固定的,可以由操作系统的设计者根据设计要求灵活安排,由IDTR来锁定其位置。

    GDT是保护模式下管理段描述符的数据结构,对操作系统自身的运行以及管理、调度进程有重大意义。

    因为此时此刻内核尚未真正运行起来,还没有进程,所以创建的GDT第一项为空,第二项为内核代码段描述符,第三项为内核数据段描述符,其余项皆为空。

    IDT虽然已经设置,实为一张空表,原因是目前已关中断,无需调用中断服务程序。此处反映的是数据“够用即得”的思想。

    创建这两个表的过程可理解为是分两步进行的:

   1)在设计内核代码时,已经将两个表写好,并且把需要的数据也写好。

    2)将专用寄存器(IDTR、GDTR)指向表。

    此处的数据区域是在内核源代码中设定、编译并直接加载至内存形成的一块数据区域。专用寄存器的指向由程序中的lidt和lgdt指令完成。

    值得一提的是,在内存中做出数据的方法有两种:

    1)划分一块内存区域并初始化数据,“看住”这块内存区域,使之能被找到;

    2)有代码做出数据,如用push代码压栈,“做出”数据。

    Linux内核设计采用的是第一种方法。

0 0
原创粉丝点击