构建64位操作系统-Intel架构:实模式,保护模式,实模式长寻址,IA-32e

1.Intel处理器架构-实模式

        BIOS加载引导程序开始执行时,程序位于实模式。

        实模式下特点有:

 1.1.实模式下的物理寻址       

jmp 0x1000:0x0010

          实模式下上述0x1000:0x0010对应的目标位置物理地址为0x1000 << 4 + 0x0010 = 0x10010。

1.1.1.实模式下物理地址位宽限制

        其中形如0x1000:0x0010这样的寻址形式。

        前一部分称为段地址,后一部分称为段内偏移。两个地址数值上必须限定在16位宽度。两部分合起来计算出的物理地址位宽限定在20位宽度。

        这样实模式下

        0xFFFF:0xFFFF = 0xFFFF << 4 + 0xFFFF = 0x10FFEF,这样的一个物理地址至少需要21个比特位来表达,就超过了20个比特位的限制。所以,0xFFFF:0xFFFF实际的物理地址为0xFFEF。超出20个比特位部分被舍弃掉了。

        这样实模式下,可表达的最大物理地址为0xFFFFF。这样的一个物理地址可用0xF000:0xFFFF来得到。

  1.2.寄存器和标号位数限制

es
cs
ds
...

        上述实模式下寄存器位数是16位。

Label1:
    xxxx
Label2 dd 0x00

        上述标号代表标号所在位置距离所在段首部的偏移。在实模式下上述标号数值是16位宽度的。

1.3.实模式下中断处理

        实模式下在物理地址[0, 1KB)范围内存储中断向量表。每个表项占据4B,共256项。

        每一项前2字节存储offset,后2字节存储segment。

2.Intel处理器架构-保护模式

        保护模式显著特点是重新设计了分段机制。

        物理内存的一块区域可被定义为一个段,段通过段描述符来描述该段的属性信息。

        特别的段描述符还可以用来描述调用门,陷阱门,中断门任务门以便实现特定的功能。

        段描述符需要存放在表结构中。

        存放段描述符的表结构有三种类型:

        一种称为GDT,全局描述符表。

        一种称为LDT,局部描述符表。

        一种称为LDT,中断描述符表。

        三种类型的表定位不同,分别用于存储符合其定位的段描述符。

2.1.GDT

        对保护模式来说,必须提供一个GDT以便处理器正常开展工作。

        GDT中存储的段,可以是用于描述一段代码区域的段,描述一段数据区域的段(包含描述栈区域的段)。特殊点的每个LDT表占据区域也构成一个段,这样的也须用段描述符来描述,且对应的描述符只能存储到GDT的表中。每个任务允许定义个称为TSS的区域,这个区域也构成一个段,这样的也须用段描述符来描述,且对应的描述符只能存储到GDT的表中。

2.1.1.8字节段描述符

        GDT中存储的段描述符占据8个字节。即64个比特位。我们对这64个比特位按从低到高进行编号,从0开始编号。

        编号[0,15]区域存储                           段长度的[0,15]

        编号[16, 31]区域存储                        段基地址的[0,15]

        编号[32, 39]区域存储                        段基地址的[16,23]

        编号[40,43]区域存储                         Type类型字段

        编号44区域存储                                S标志(系统段标志。1:非系统段,0:系统段)

        编号[45,46]区域存储                         DPL标志(段的特权级)

        编号47区域存储                                P标志(段在内存标志。1:在,0:不在)

        编号[48,51]区域存储                         段长度的[16,19]

        编号52区域存储                                AVL标志(一般为0)

        编号53区域存储                                L标志(保留,0)

        编号54区域存储                                D/B标志

        编号55区域存储                                G标志(尺寸粒度,1:4KB,0:字节)

        编号[56,63]区域存储                         段基地址的[24,31]

        

        D/B标志:

        对可执行代码段。为1时,默认下,段内地址是32位的。操作数是32位或8位的。

        对栈段。为1时,使用ESP作为栈指针。为0时,使用SP作为栈指针。

        对数据段。为1时,上边界为0xFFFF FFFF。为0时,上边界为0xFFFF。

2.1.2.2字节段选择子

        保护模式下,段寄存器内存储的2字节内容称为段选择子。16个比特位。我们对这16个比特位按从低到高进行编号,从0开始编号。

        编号[0,1]区域存储                           RPL(请求特权级)

       编号2区域存储                                 TI(0,GDT;1,LDT)

       编号[3, 15]区域存储                         段选择子索引

2.1.3.代码段

        S标志位为1,且编号43区域为1。此时段描述的类型称为代码段。

        进一步,此时,

        编号42区域称为C(一致性)标志位。为1时,称为一致性代码段。为0时,称为非一致性代码段。

        对一致性代码段有以下机制:

        当前程序(代码段)可执行或跳转到一个一致性代码段,即使该一致性代码段的特权级高于当前。且跳转后CPL不变。

        对非一致性代码段,上述跳转到一个更高特权级代码段是不可行的。

        

        编号41区域称为R(可读)标志位。表示这个段内容是否可被读取。代码段必然是可执行的,不可写的。但是否可读允许通过此位来配置。

        编号40区域称为A(访问)标志位。当代码段被访问时,处理器设置对应段描述符的A标志位为1。

2.1.4.数据段

         S标志位为1,且编号43区域为0。此时段描述的类型称为数据段。

          进一步,此时,

        编号42区域称为E(扩展方向)标志位。为1时,段向下扩展。为0时,段向上扩展。向上与向下扩展可以理解为从段基地址向段存储新数据时,新数据是存储到基地址之上,还是存储到基地址之下。对正常数据区域,是向上的。对栈,一般是向下的。               

        编号41区域称为W(可写)标志位。表示这个段内容是否可写。数据段必然是可可读的。但是否可写允许通过此位来配置。

        编号40区域称为A(访问)标志位。当代码段被访问时,处理器设置对应段描述符的A标志位为1。

2.1.5.系统段

        S标志位为0。此时段描述的类型称为系统段。

        对于系统段,需要结合编号[40,43]区域4个比特位来进一步确定段的类型。

43424140系统段类型
0000保留
000116位TSS段(有效的)
0010LDT段
001116位TSS段(使用中)
010016位调用门
0101任务门
011016位中断门
011116位陷进门
1000保留
100132位TSS段(有效的)
1010保留
101132位TSS(使用中)
110032位调用门
1101保留
111032位中断门
111132位陷阱门

        对于LDT段描述符,用于描述LDT区域。LDT区域作为一个表,D/B标志位对其无意义,一般设置为0。

        对于TSS段描述符,用于描述TSS区域。        

2.1.6.TSS区域

        一个TSS区域的结构可以用如下表格来描述

偏移尺寸描述
0x002上个任务的TSS选择子
0x022保留
0x044ESP0
0x082SS0
0x0A2保留
0x0C4ESP1
0x102SS1
0x122保留
0x144ESP2
0x182SS2
0x1A2保留
0x1C4CR3
0x204EIP
0x244EFLAGS
0x284EAX
0x2C4ECX
0x304EDX
0x344EBX
0x384ESP
0x3C4EBP
0x404ESI
0x444EDI
0x482ES
0x4A2保留
0x4C2CS
0x4E2保留
0x502SS
0x522保留
0x542DS
0x562保留
0x582FS
0x5A2保留
0x5C2GS
0x5E2保留
0x602LDT段选择子
0x622保留
0x642最低比特位是T标志,其余保留
0x662I/O位图基地址

        上面表格中红色区域我们称为动态区域,绿色区域我们称为静态区域。

        TSS结构需要在如下场景中发挥作用:

        1.程序通过JMP/CALL提供的段选择子,定位到GDT中的TSS段描述符时。发生任务切换。

        此时TR所关联的TSS区域中的动态区域用于存储当前程序执行现场。所谓执行现场就是由动态区域中各个对应字段构成的。

        动态区域中"上个任务的TSS选择子"特殊处理,使用目标TSS区域中的"上个任务的TSS选择子"来记录上个程序的TSS选择子。

        同时会使用目标TSS区域中的静态区域来设置新任务的CR3,LDT,根据新任务的特权级相应设置SS,ESP为目标TSS区域中静态区域内对应值。

        2.程序通过JMP/CALL提供的段选择子,定位到GDT/LDT中的任务门描述符时。发生任务切换。

        具体当前程序的TSS区域的动态区域,目标程序的TSS区域的静态区域如何起作用参考1。

        3.触发中段或异常,且对应的处理表项是任务门描述符。发生任务切换。

        具体当前程序的TSS区域的动态区域,目标程序的TSS区域的静态区域如何起作用参考1。

        4.EFLAGS.NT设置为1时,执行IRET。发生任务切换。

        具体当前程序的TSS区域的动态区域,目标程序的TSS区域的静态区域如何起作用参考1。

        综上所述,TSS机制为任务切换提供的一种支持机制。借助TSS机制实现的任务切换可以让处理器帮应用自动处理执行现场保留,新任务必要执行环境设置等工作。

2.1.7.如何告知处理器GDT的位置信息

        处理器存在GDTR寄存器,用于存储GDT尺寸,GDT起始位置。

        可使用 "LGDT [SrcAddr]"告知。

        实模式下,默认操作数大小是16位。保护模式下,操作数大小需结合数据段的D/B标志位确定。IA-32e模式下默认64位。

2.2.LDT

        LDT表也用于存储保护模式下的8字节段描述符。不过无法存储描述LDT区域的描述符,描述TSS区域的描述符。

2.2.1.如何告知处理器LDT的位置信息        

        处理器存在LDTR寄存器。用于存储描述LDT区域的段选择子。

        使用 "LLDT LDT段的选择子" 告知。

2.3.如何从实模式切换到保护模式

        1.系统进入保护模式前,需创建一个拥有代码段描述符,数据段描述符的GDT(首个表项需为NULL描述符)。然后通过LGDT告知处理器GDT表尺寸,位置。

        2.LDT表的使用是可选的,如使用,则需准备LDT表。然后通过LIDT告知处理器LDT的段选择子。

        3.保护模式需开启分页机制下,开启分页机制前,需要准备好页目录表,页表。并将页目录表的物理地址加载到CR3控制寄存器。进入保护模式后,再置位CR0.PG可开启分页机制。

        4.进入保护模式前,需创建一个IDT。IDT可用于存储中断门描述符,陷阱门描述符,任务门描述符。然后通过LIDT告知处理器IDT表尺寸,位置。

        5.进入保护模式后,如果需要使用基于TSS区域的任务切换机制,则需在执行任务切换前,创建对应的TSS区域,TSS段描述符。使用LTR汇编指令将TSS段选择子加载到TR寄存器。以便处理器知道当前任务的TSS区域。

        如何进入保护模式?

        通过MOV指令置位CR0.PE后即进入保护模式。进入保护模式后,将从特权级0开始执行。

        一般推荐的实践方式为:

        1.CLI禁止可屏蔽硬件中断

        2.MOV 设置CR0.PE为1

        3.远跳转

        进入保护模式后,数据段寄存器仍保留着实模式的段数据,需重新加载数据段选择子或用JMP/CALL执行新任务来更新。

        使用STI使能可屏蔽硬件中断前,需用LIDT告知处理器IDT表的基地址和长度。

2.4.寻址能力

        实模式下,我们通过段寄存器,段内偏移,支持的寻址范围可用20个比特位来表示。

        保护模式下,我们的段基础地址,段偏移都是32位的,相应的寻址范围也变为32位比特位。

        但要让处理器允许我们寻址到超过20个比特位的地址空间,需要开启A20地址线才可以。

        以下是一种开启A20地址线的方法:

in	al,	92h
or	al,	00000010b
out	92h,	al

        即从io端口0x92先读取1字节,将读取1字节的比特位1(从0开始编号)设置为1后,再写入0x92端口即可。

2.5.实模式下进行4GB寻址的方法

        默认实模式下,通过16位段寄存器,16位段内偏移,支持的寻址范围是20个比特位。

        通过以下方法,可在实模式下进行4GB寻址:

        1.cli禁止中断

        2.准备GDT,通过LGDT告知处理器GDT尺寸,位置

        3.通过MOV置位CR0.PE进入保护模式

        4.通过MOV为希望具备4GB寻址的段寄存器p设置为保护模式GDT中支持4GB寻址数据段描述符的段选择子。

        5.通过MOV复位CR0.PE回到实模式

        这样操作后,实模式下使用p作为段寄存器,计算p:off的线性地址时,不再采用

        线性地址=p>>4+off的方式。而是采用

        线性地址=p对应数据段的32位Base+off

        值得注意的是,实模式下,搭配不具备p特征的段寄存器时,段内偏移只能使用16个比特位。搭配具备p特征的段寄存器时,段内偏移可以使用32个比特位。

mov	byte	[fs:edi],	al

2.6.IA-32e模式及其下的兼容模式,64位模式。

        IA-32e模式是Intel为64位处理器设计的新模式,也称长模式。包含兼容模式,64位模式两种子运行模式。

2.6.1.检测处理器是否支持IA-32e模式

        CPUID.80000001h:EDX[29].LM

2.6.2.IA-32e下地址空间

        线性地址位宽64位。有效地址是低48位用于线性地址寻址,高16位作为符号位扩展的地址。也称为Canonical地址。

        相应的Canonical型地址区间0x0000 0000, 0000 0000~0x0000 7FFF, FFFF FFFF和0xFFFF 8000, 0000 0000~0xFFFF FFFF, FFFF FFFF是程序可用区域。

2.6.3.IA-32e下段机制

        IA-32e下段机制继承自保护模式,又有较大改进。

        存放段描述符的表结构有三种类型:

        一种称为GDT,全局描述符表。

        一种称为LDT,局部描述符表。

        一种称为LDT,中断描述符表。

        三种类型的表定位不同,分别用于存储符合其定位的段描述符。

2.6.4.8字节代码段,数据段描述符

        IA-32e模式下,代码段,数据段的段基地址强制为0x00,段尺寸强制为无限制。

        我们对这64个比特位按从低到高进行编号,从0开始编号。

        编号[0,15]区域存储                           段长度的[0,15]

        编号[16, 31]区域存储                        段基地址的[0,15]

        编号[32, 39]区域存储                        段基地址的[16,23]

        编号[40,43]区域存储                         Type类型字段

        编号44区域存储                                S标志(系统段标志。1:非系统段,0:系统段)

        编号[45,46]区域存储                         DPL标志(段的特权级)

        编号47区域存储                                P标志(段在内存标志。1:在,0:不在)

        编号[48,51]区域存储                         段长度的[16,19]

        编号52区域存储                                AVL标志(一般为0)

        编号53区域存储                                L标志

        编号54区域存储                                D/B标志

        编号55区域存储                                G标志(尺寸粒度,1:4KB,0:字节)

        编号[56,63]区域存储                         段基地址的[24,31]

        

        上述是保护模式下8字节段描述符解析。

        IA-32e模式下(IA32_EFER.LMA=1),依然对代码段,数据段依然采用8字节段描述符。依然可按上述去解析。但不同之处在于。

        1.对代码段,L标志位为0时,处理器将运行在IA-32e的兼容子模式。此时完全按照和保护模式一致的方式去解释段描述符。

        2.对代码段,L标志位为1时,处理器将运行在IA-32e的64位子模式。此时D/B标志位必须是0。此时代码段的默认操作数位宽是32位。地址位宽是64位。 

        3.对数据段,

2.6.5.16字节系统段描述符

        IA-32e模式下,对系统段采用16字节段描述符。低8字节依然沿用保护模式下8字节段描述符格式。具体细节为:

        1.IA-32e模式下,系统段描述符类型

43424140功能
000016B描述符的高8B
0001保留
0010LDT段描述符
0011保留
0100保留
0101保留
0110保留
0111保留
1000保留
100164位TSS段描述符(有效的)
1010保留
101164位TSS段描述符(使用中)
110064位调用门描述符
1101保留
111064位中断门描述符
111164位陷阱门描述符

        2.对LDT段描述符,TSS段描述符

        多出来的高8字节,最高4字节保留,低4字节存储段基地址63:32。

        低8字节按保护模式下8字节解释。Type字段以1中为准。

        对于TSS段所描述的TSS区域,使用场景发生了较大改变。由于IA-32e模式不支持任务门机制。相应的,IA-32e模式下,TSS区域无需用来提供对任务切换时现场保存与恢复的支持。只需负责为不同特权级间的栈切换提供支持即可。

        相应的TSS区域结构变为如下

偏移尺寸描述
0x04保留
0x44RSP0的低32位
0x84RSP0的高32位
0xC4RSP1的低32位
0x104RSP1的高32位
0x144RSP2的低32位
0x184RSP2的高32位
0x1C4保留
0x204保留
0x244IST1低32位
0x284IST1高32位
0x2C4IST2低32位
0x304IST2高32位
0x344IST3低32位
0x384IST3高32位
0x3C4IST4低32位
0x404IST4高32位
0x444IST5低32位
0x484IST5高32位
0x4C4IST6低32位
0x504IST6高32位
0x544IST7低32位
0x584IST7高32位
0x5C4保留
0x604保留
0x642保留
0x662I/O位图基地址

        IA-32e下,针对特权级0,1,2的SS段寄存器,支持加载NULL段选择子(GDT的0项)。

        IA-32e下,发生特权级切换时,新的SS段寄存器强制加载一个NULL段选择子。RSP将根据特权级被赋值为RSPn(n=0~2)。旧的SS,RSP将被保存到新栈中。

2.6.6.IA-32e模式下的调用门描述符

        IA-32e下调用门描述符从原来的8B扩充到16B.

        我们对这128个比特位按从低到高进行编号,从0开始编号。

        编号[0,15]区域存储                           段内偏移的[0,15]

        编号[16, 31]区域存储                        段选择子

        编号[32, 39]区域存储                        0

        编号[40,43]区域存储                         Type类型字段(1100)

        编号44区域存储                                S标志(系统段标志。1:非系统段,0:系统段)

        编号[45,46]区域存储                         DPL标志(段的特权级)

        编号47区域存储                                P标志(段在内存标志。1:在,0:不在)

        编号[48,63]区域存储                         段内偏移[16, 31]

        编号[64, 95]区域存储                        段内偏移[32, 63]

        编号[96, 127]区域存储                      保留       

        处理器在执行IA-32e模式的调用门时,将以8B的数据位宽向栈中压入数据。

        RETF指令的默认操作数是32位,若要返回到64位程序,需在RETF前额外加上前缀0x48。

2.6.7.IA-32e模式下的中断和异常处理

        IA-32e模式的中断/异常处理机制与保护模式的异常处理机制相似。

        不过中断发生时,栈空间的保存(SS, RSP)由选择性保存(特权级CPL变化时),改为无条件保存。

        IA-32e模式还引入了一种全新的中断栈切换机制。

        IA-32e模式的系统段描述符不再支持任务门描述符,只剩下陷阱门描述符,中断门描述符。

        

        我们对这128个比特位按从低到高进行编号,从0开始编号。

        编号[0,15]区域存储                           段内偏移的[0,15]

        编号[16, 31]区域存储                        段选择子[0,15]

        编号[32, 34]区域存储                        IST

        编号[35]区域存储                              0

        编号36区域存储                                S标志(系统段标志。1:非系统段,0:系统段)

        编号[37,39]区域存储                         0

        编号[40, 43]区域存储                        Type

        编号[44]区域存储                              0

        编号[45, 46]区域存储                        DPL

        编号47区域存储                                P

        编号[48, 63]区域存储                        段内偏移的[16, 31]

        编号[64, 95]区域存储                        段内偏移的[32, 63]

        编号[96,127]区域存储                       保留

        在IDT的任意一个门描述符都可使用IST机制或原有栈切换机制。当IST=0时,使用原有栈切换机制。否则,使用IST机制,此时处理器无条件进行栈切换。

        使用IST机制下,

        处理器强制将SS赋值为NULL段选择子,并将中断栈地址加载到RSP寄存器中。

        最后,将原SS,RSP,RFLAGS,CS和RIP寄存器值压入新栈中。

2.7.IA32e下分页机制

        IA-32e模式需伴随页管理机制的开启(置位CR0.PG,CR4.PAE,IA32_EFER.LME)。

        IA-32e模式的页管理机制可将Canonical型的线性地址映射到52位物理地址空间(由处理器最高物理可寻址位宽值MAXPHYADDR决定)。

        处理器通过CR3保存的物理地址,可将线性地址转换成一个多层级页表结构,IA-32e模式的页管理机制共支持4KB,2MB,1GB(CPUID.80000001h:EDX[26].1G-Page位可检测是否支持1GB物理页)三种规格的物理页容量。

        IA-32e模式的页管理机制使用多层级页表来结构化线性地址空间,CR3负责定位顶层页表PML4的物理基地址。

        PCIDs功能支持检测:

        CPUID.01h:ECX[17].PCID

        支持下,置位CR4.PCIDE标志位时开启PCID功能。

        开启PCID功能前提下,使用MOV指令操作CR3的第63位,将会影响TLB的有效性(全局页除外)。

       1.CR3寄存器解析

        处理器使能PCIDs功能时:

        编号[0,11]区域存储                           PCID

        编号[12, M-1]区域存储                     PML4页表的物理基地址

        编号[M, 63]区域存储                        保留       

        处理器使能PCIDs功能时:

        编号[0,2]区域存储                           保留

        编号[3]区域存储                              PWT标志位

        编号[4]区域存储                              PCD标志位

        编号[5, 11]区域存储                        保留

        编号[12, M-1]区域存储                    PML4页表的物理基地址

        编号[M, 63]区域存储                       保留

        

        2.对于PML4页表(容量4KB)的页表项的解析

        若页表项是无效的

        编号[0]区域                                         0

        编号[1, 63]区域                                   保留

       

        若页表项是有效的

        编号[0]区域                                        1

        编号[1]区域                                        R/W

        编号[2]区域                                        U/S

        编号[3]区域                                        PWT

        编号[4]区域                                        PCD

        编号[5]区域                                        A

        编号[6, 11]区域                                  保留

        编号[12, M-1]区域                              PDPT页表的物理基地址

        编号[M, 62]区域                                 保留

        编号[63]区域                                      XD标志位

        

        3.对于PDPT页表(容量4KB)的页表项的解析

        若页表项是无效的

        编号[0]区域                                        0

        编号[1, 63]区域                                  保存

        若物理页是1GB的

        编号[0]区域                                        1

        编号[1]区域                                        R/W

        编号[2]区域                                        U/S

        编号[3]区域                                        PWT

        编号[4]区域                                        PCD

        编号[5]区域                                        A

        编号[6]区域                                        D

        编号[7]区域                                        1(可作为1GB物理页的依据)

        编号[8]区域                                        G

        编号[9, 11]区域                                  保留

        编号[12]区域                                      PAT

        编号[13, 29]区域                                保留

        编号[30, M-1]区域                             1GB物理页的基地址

        编号[M, 62]区域                                保留

        编号[63]区域                                     XD标志位

       

        若物理页不是1G的

        编号[0]区域                                        1

        编号[1]区域                                        R/W

        编号[2]区域                                        U/S

        编号[3]区域                                        PWT

        编号[4]区域                                        PCD

        编号[5]区域                                        A

        编号[6]区域                                        保留

        编号[7]区域                                        0(可作为非1GB物理页的依据)

        编号[8, 11]区域                                  保留

        编号[12, M-1]区域                              页目录表的物理基地址

        编号[M, 62]区域                                保留

        编号[63]区域                                     XD标志位

      

        4.对PDT表(容量4KB)的页表项的解析

        若页表项是无效的

        编号[0]区域                                        0

        编号[1, 63]区域                                  保存

        若物理页是2MB的

        编号[0]区域                                        1

        编号[1]区域                                        R/W

        编号[2]区域                                        U/S

        编号[3]区域                                        PWT

        编号[4]区域                                        PCD

        编号[5]区域                                        A

        编号[6]区域                                        D

        编号[7]区域                                        1(可作为2MB物理页的依据)

        编号[8]区域                                        G

        编号[9, 11]区域                                  保留

        编号[12]区域                                      PAT

        编号[13, 20]区域                                保留

        编号[31, M-1]区域                             2MB物理页的基地址

        编号[M, 62]区域                                保留

        编号[63]区域                                     XD标志位

       

        若物理页不是2MB的

        编号[0]区域                                        1

        编号[1]区域                                        R/W

        编号[2]区域                                        U/S

        编号[3]区域                                        PWT

        编号[4]区域                                        PCD

        编号[5]区域                                        A

        编号[6]区域                                        保留

        编号[7]区域                                        0(可作为非2MB物理页的依据,那只能是4KB物理页了)

        编号[8, 11]区域                                  保留

        编号[12, M-1]区域                              页目录表的物理基地址

        编号[M, 62]区域                                保留

        编号[63]区域                                     XD标志位

        5.对PT表(容量4KB)的页表项的解析

        若页表项是无效的

        编号[0]区域                                        0

        编号[1, 63]区域                                  保存

        此时物理页只能是4KB的

        编号[0]区域                                        1

        编号[1]区域                                        R/W

        编号[2]区域                                        U/S

        编号[3]区域                                        PWT

        编号[4]区域                                        PCD

        编号[5]区域                                        A

        编号[6]区域                                        D

        编号[7]区域                                        PAT

        编号[8]区域                                        G

        编号[9, 11]区域                                  保留

        编号[12, M-1]区域                              4KB物理页的物理基地址

        编号[M, 62]区域                                保留

        编号[63]区域                                     XD标志位

        6.对1~5中涉及的相关标志位的解释

        P                        物理页存在标志位

        W                       物理页写权限标志位(读权限始终有)

        U/S                     访问模式标志位。0时,特权级3程序不可访问。1时,无限制。

        PWT                   0,回写。1,写穿。

        PCD                   0,页可以缓存。1,页不能缓存。

        A                         访问标志位。0,未访问。1,已访问。

        D                        脏页标志位。0,干净。1,脏页。

        PAT                    页面属性标志位。

        G                        全局页标志位。0,局部页。1,全局页。

        PS                      物理页容量标志位。

        

        CR0.CD为1时,PWT和PCD被忽略。

        7.如何翻译64位线性地址

       对4KB物理页:

        64位线性地址构成=16位符号扩展位+9位PML4表索引+9位PDPT表索引+9位PDT表索引+9位PT表索引+12位段内偏移。

        对2MB物理页:

        64位线性地址构成=16位符号扩展位+9位PML4表索引+9位PDPT表索引+9位PDT表索引+21位段内偏移。

        对1GB物理页:

        64位线性地址构成=16位符号扩展位+9位PML4表索引+9位PDPT表索引+30位段内偏移。

        

2.8.如何从保护模式切换到IA-32e模式     

2.8.1.检测处理器是否支持IA-32e模式

call	support_long_mode
test	eax,	eax
jz	no_support

;=======	test support long mode or not
support_long_mode:
mov	eax,	0x80000000
cpuid
cmp	eax,	0x80000001
setnb	al	
jb	support_long_mode_done
	
mov	eax,	0x80000001
cpuid
bt	edx,	29
setc	al

support_long_mode_done:
	movzx	eax,	al
	ret

;=======	no support
no_support:
	jmp	$

        对上述代码的解释:

        1.通过0x80000000执行cpuid,来查询cpuid支持的最大功能号

        2.向cpuid查询是否支持长模式(IA-32e)依赖0x80000001。所以,

        2.1.cpuid执行结果(存储在eax)大于等于0x80000001,则设置al为1。

        2.1.cpuid执行结果小于0x80000001,用al设置eax并返回。eax将被设置为0。

        3.接下来,必然cpuid大于等于0x80000001

        3.1.通过0x80000001执行cpuid。结果存储在edx。edx第29比特位为1,则支持长模式。为0,则不支持。

        3.2.测试edx第29比特位来设置al,并用al设置eax,返回。

        4.测试eax即可知道是否支持长模式。eax为0时,不支持。不为0时,支持。

 2.8.2.从保护模式切换到IA-32e模式

         处理器只能在开启分页机制的保护模式下才能切换到IA-32e模式。

        1.IA-32e模式激活后,GDTR,LDTR,IDTR,TR依然沿用保护模式的描述符表。IA-32e中,上述描述符表寄存器应重新加载为IA-32e模式的64位描述符表。

        2.IA-32e模式激活后,在将IDTR更新为IA-32e模式下描述符表前,需用CLI禁止可屏蔽硬件中断。对NMI不可屏蔽中断,需借助外部硬件电路来禁止。

        

        激活IA-32e:

        IA32_EFER.LME。

        

        激活步骤:

        1.保护模式下,用MOV CR0复位CR0.PG标志位来关闭分页机制。

        2.置位CR4.PAE,开启物理地址扩展。

        3.将页目录(顶层页表PML4)的物理基地址加载到CR3

        4.置位IA32_EFER.LME开启IA-32e模式

        5.置位CR0.PG开启分页机制。此时处理器会自动置位IA32_EFER.LMA。

        注意,开启分页机制,关闭分页机制前后对附近代码的线性地址的解释是不一样的。但应控制前后线性地址在开启,关闭前后,解释到相同的物理地址。

           

        

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值