您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 本书基于IA32体系结构来分析内核
前言本书基于IA32体系结构来分析内核,但是,并没有专门开设一章来讲IA32体系结构,而是分散到各个章节中,当需要时进行描述。这样可以更好地体会软件和硬件之间的交互技术。本书以Linux2.4.20内核作为分析对象。第一部分系统初始化本部分首先描述IA32处理器本身的初始化规程,然后讲述计算机加电后,操作系统自举的过程。其中,对系统引导部分详细描述,对内核初始化部分,仅描述各个子系统的初始化总体流程,各个子系统的详细初始化过程,在分析该子系统的相应的章节中再分别详细分析。IA32处理器的初始化本章暂时抛开操作系统,仅就IA32处理器本身的初始化功能和作用进行较为详细的描述。内容包括处理器初始化、处理器配置、工作模式切换等。1.1处理器初始化概述处理器的初始化过程总的分为硬件初始化和软件初始化两大部分。当系统加电或者RESET引脚有效后,处理器进入硬件初始化过程。硬件初始化过程的第一步是硬件复位。硬件复位将处理器的寄存器设置为复位初始值,并将处理器设置为实模式工作状态。同时,硬件复位还将处理器内部高速缓存(cache)、转换后援缓冲器(TLB)和分支目标缓冲器(BTB)设置为无效的状态。复位操作按照处理器系列不同而有所不同:P6系列处理器——总是经先进可编程中断控制器(APIC)执行多处理器(MP)初始化操作,然后,MP初始化规程所选择的引导处理器(BSP)开始执行初始化代码(即进入软件初始化过程)。初始化代码的起始地址,由当前代码段中的段基地址和EIP寄存器中的偏移量给定。其余非主处理器(AP)在BSP执行初始化代码时,进入停止状态。Pentium处理器——无论是在单处理器系统还是多处理器系统中,总有一个处理器被设置为主处理器(注意,这里的主处理器只是在初始化过程中起作用,当操作系统被加载后,系统工作在主从状态还是SMP状态,由操作系统决定)。主处理器按照预定的双处理器(DP)初始化规程执行软件初始化代码,代码的起始地址由当前代码段中的段基地址和EIP寄存器中的偏移量确定。辅助处理器进入停止状态。Intel486处理器——主处理器立刻从当前代码段中,由EIP寄存器中偏移量确定的起始地址开始执行软件初始化代码。486处理器不会自动按照DP或者MP规程进行初始化。硬件复位期间,浮点单元(FPU)也被初始化为复位状态,然后可以执行FPU软件初始化代码。由于无论处理器工作在哪种模式下,FPU的操作总是相同的,所以FPU的初始化不需要进行工作模式切换操作。1.1.1复位后的处理器状态表1-1是加电后各个处理器系列中各个寄存器地状态。其中,控制寄存器CR0的状态为60000010H,该状态将处理器设置为实地址工作方式,见图1-1。表1-1复位后,IA32处理器的状态寄存器P6处理器Pentium处理器Intel486处理器EFLAGS00000002H00000002H00000002HEIP0000FFF0H0000FFF0H0000FFF0HCR060000010H60000010H60000010HCR2、CR3、CR400000000H00000000H00000000HCS选择符=F000H基址=FFFF0000H段限=FFFFHAR=存在、R/W、已访问选择符=F000H基址=FFFF0000H段限=FFFFHAR=存在、R/W、已访问选择符=F000H基址=FFFF0000H段限=FFFFHAR=存在、R/W、已访问SS、DS、ES、FS、GS选择符=0000H基址=00000000H段限=FFFFHAR=存在、R/W、已访问选择符=0000H基址=00000000H段限=FFFFHAR=存在、R/W、已访问选择符=0000H基址=00000000H段限=FFFFHAR=存在、R/W、已访问EDX000006xxH000005xxH000004xxHEAX、EBX、ECX、ESI、EDI、EBP、ESP00000000H00000000H00000000HGDTR、IDTR基址=00000000H段限=FFFFHAR=存在、R/W基址=00000000H段限=FFFFHAR=存在、R/W基址=00000000H段限=FFFFHAR=存在、R/WLDTR、TR选择符=0000H基址=00000000H段限=FFFFHAR=存在、R/W选择符=0000H基址=00000000H段限=FFFFHAR=存在、R/W选择符=0000H基址=00000000H段限=FFFFHAR=存在、R/WDR0、DR1、DR2、DR300000000H00000000H00000000HDR6FFFF0FF0HFFFF0FF0HFFFF1FF0HDR700000400H00000400H00000000H时间戳寄存器0H0H未实现性能计数器及事件选择寄存器0H0H未实现其他模式专用寄存器(MSR)未定义未定义未定义数据和代码cache、TLB无效无效无效固定的和可变的MTRR禁止未实现未实现机器校验结构未定义未实现未实现APIC使能使能未实现1.1.2软件初始化代码软件初始化作为处理器初始化的一部分,在处理器复位后,初始化代码必须在引导处理器或者主处理器上完成系统专用初始化以及系统逻辑初始化。对于多处理器(MP)或者双处理器(DP)系统,BSP处理器在完成初始化后,唤醒各个AP处理器,由各个AP处理器执行初始化代码,完成各自的初始化。软件初始化代码必须构造必要的运行环境,如在内存中初始化中断描述符表、全局描述符表等系统数据结构。硬件复位后,处理器中CS寄存器中可见的段选择符部分的值为F000H,EIP的值为0000FFF0H,由于处理器运行于实模式,并不使用CS中隐含的描述符部分,故处理器执行的第一条指令的地址遵循实模式下的物理地址生成规则而得:CS*16+EIP,即FFFF0000H+FFF0H=FFFFFFF0H。所以,硬件复位后,处理器从物理地址为FFFFFFF0H的存储单元取指执行。因此,要求含有初始化代码(一般就是所谓的BIOS)的EPROM必须映射到该地址。为确保EPROM中的软件初始化代码的正常执行,CS寄存器选择符部分的值必须维持不变,在EPROM软件初始化完成以前,代码中不能有包含远程跳转或者远程调用的指令,也不能允许中断,因为这会导致改变CS选择符的值。只有在EPROM软件完成初始化之后,才用一条远程跳转指令将程序控制转移到后续的引导初始化代码上去。1.2高速缓存及模式专用寄存器(MSR)的初始化本部分的初始化主要由软件初始化代码完成两项任务:开放处理器高速缓存(cache),设置模式专用寄存器(MSR)1.2.1开放高速缓存(cache)IA32体系结构内部具有指令cache和数据cache。通过设置控制寄存器CR0重的CD和NW标志位,可以实现禁止或者开放cache的目的。当处理器加电复位后,CD和NW被置位,所有内部cache行均处于无效状态,因此初始化代码应当通过清除CR0中的CD和NW标志来开放cache。处理器外部具有所谓的二级cache。对二级cache的初始化需要使用系统专用的代码序列来初始化。1.2.2设置模式专用寄存器(MSR)IA32体系结构内部具有一组模式专用寄存器MSR。MSR与处理器工作模式和硬件、软件的有关特性相关。这些特性对于支持多任务操作系统的开发是非常重要的。下面对它们作一简要介绍。性能监视计数器及相应的性能监视控制器。P6系列处理器有两个40位的性能监视计数器,一个用来事件计数,一个用于时间间隔测量。时间戳计数器。一个64位的计数器,以处理器时钟进行增量计数。调试扩展寄存器。P6系列处理器除了使用8各调试寄存器(DR0~DR7)以外,还设置了两个模式专用的调试扩展寄存器,进一步完善其调试功能。调试扩展寄存器用以记录最近分支、中断和异常,于是可以用来在分支、中断和异常处设置断点。存储器类型范围寄存器(MTRR)。对于现代计算机而言,其系统存储器的组成成分比较复杂,包括ROM、RAM、帧缓冲存储器以及存储器映射I/O。为了能对不同类型的存储器进行优化操作,P6系列处理器使用MTRR来指定存储器类型以及包含的地址范围。所谓固定的MTRR是指这一组MTRR所指定的存储空间是在00000000H~000F8000H范围内;而可变MTRR则可以指定任意的存储空间。在初始化代码中,必须对MSR进行设置。使用的指令是运行于0级的特权指令RDMSR和WRMSR。1.3软件初始化的任务本节分别阐述实模式和保护模式下软件初始化所要完成的工作。两种处理器工作模式的切换在1.4节中叙述。前面已经指出,CPU加电复位后,处理器处于实模式工作方式。CPU将从物理地址FFFFFFF0H开始取指执行,进入实模式的软件初始化。实模式的软件初始化的主要任务是设置处理器的基本运行环境,包括处理中断和异常的IDT数据结构。实模式下的IDT在实模式工作方式下,唯一需要加载进入内存的系统数据结构是IDT(中断向量表)。初始化代码使用LIDT指令来改变处理器中的中断向量表基地址寄存器IDTR。在开放中断之前,初始化代码必须在IDT中正确设置中断和异常处理程序指针。实际的中断和异常处理程序代码一般也加载到RAM中,并且必须位于处理器在实模式下可寻址的1M地址空间内。NMI中断处理在IDT和实际的中断和异常处理程序尚未加载到RAM中之前,必须禁止NMI。分两种情况:l一种情况是简单的IDT和NMI中断处理程序可以放在EPROM中(如BIOS系统),l这样在复l位初始化之后,l可以立即处理NMI中断。l另一种情况是由系统硬件提供一个机构来开放和禁止NMI中断。通常的方法是,l使处理器的NMI信号通过一个与门,l该与门受控于一位I/O端口。这样初始代码可以通过操纵该I/O端口实现对NMI的控制。如果处理器还要进一步切换到保护模式下,则在实模式下需要做更多的工作来支持模式切换。这些任务是:并初始化保护模式下的IDT表初始化GDT表初始化一个TSS段初始化一个LDT表如果要使用分页机制,则需要初始化页目录和至少一个页表初始化GDTR寄存器初始化IDTR寄存器初始化控制寄存器CR1~CR4初始化MTRR(仅限于P6系列处理器)进行了上述必要的初始化后,处理器就可以修改控制寄存器CR0,使PE置位,切换到保护模式。具体的切换细节在1.4节中叙述。1.4工作模式的切换在完成必要的准备后,初始化代码可以通过下述步骤完成从实模式到保护模式的切换。禁止中断。CLI指令可以禁止可屏蔽中断(INTR),NMI中断可以通过外部电路禁止。执行LGDT指令,将GDT的基地址加载到GDTR寄存器中。执行MOVCR0指令,将控制寄存器CR0的PE标志置位,如果要使用分页机制的话,同时把PG标志置位。紧跟在MOVCR0指令之后,执行一条远程跳转或者远程过程调用指令。典型方式是,远程跳转或者远程过程调用到指令流的下一条指令(JMP或者CALL指令的下一条指令)。紧跟在MOVCR0后的指令JMP或者CALL指令既改变了指令执行流程,又对处理器的指令预取队列进行了清除。需要注意的是,如果启用了分页,则MOVCR0指令和JMP或者CALL指令的代码必须在映射同一个页面上,转移目标指令的代码可以不在同一个页面上。如果要使用局部描述符表,执行LLDT指令,将LDT的段选择符加载到LDTR寄存器中。实行LTR指令,将段选择符加载到任务寄存器,以初始化保护方式的任务。进入保护模式后,段寄存器继续保持在实模式方式下的值。步骤4中的JMP指令或者CALL指令重置了CS寄存器。使用下列方法之一完成其余段寄存器值的更新:l重新显式加载DS、SS、ES、FS和GS的值。l执行一条JMP或者CALL指l令,l转到一个新的任务上去,l这样可以根据新任务的TSS段中的内容自动重置所有段寄存器的值。执行LIDT指令,将保护模式的IDT基地址和界限加载到IDTR寄存器中。执行STI指令,开放可屏蔽中断(INTR),并执行必要的硬件操作以开放NMI中断。第二章BIOS引导过程2.1BIOS的基本概
本文标题:本书基于IA32体系结构来分析内核
链接地址:https://www.777doc.com/doc-3144765 .html