assembly x86_64在长模式64位子模式下运行

bzzcjhmw  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(97)

我想澄清一下x86_64处理器如何知道它处于IA-32 e 64位子模式。
据我所知,EFER MSR0xC0000080)中的LM位必须设置。此外,当前代码段描述符中的L位(当前缓存在CS描述符缓存中)必须设置(1)。
还有其他需要配置的部分吗?

sczxawaw

sczxawaw1#

根据英特尔10.8.5 "初始化IA-32e模式" 部分:
在英特尔64处理器上,IA32_EFER MSR在系统复位时被清除。在尝试初始化IA-32e模式之前,操作系统必须处于启用分页的保护模式。IA-32e模式操作还需要具有四个或五个增强分页结构级别的物理地址扩展(请参见第4.5节"4级分页和5级分页")。
操作系统应按照以下顺序初始化IA-32e模式:
1.从保护模式开始,通过设置CR0.PG = 0禁用分页。使用MOV CR0指令禁用分页(该指令必须位于标识Map页中)。
1.通过设置CR4.PAE = 1启用物理地址扩展(PAE)。尝试初始化IA-32e模式时,如果无法启用PAE,将导致#GP故障。
1.用4级页Map表(PML4)或5级页Map表(PML5)的物理基地址加载CR3。
1.通过设置IA32_EFER.LME = 1启用IA-32e模式。
1.通过设置CR0.PG = 1来启用分页。这将导致处理器将IA32_EFER.LMA位设置为1。启用分页的MOV CR0指令和后续指令必须位于标识Map页中(直到可以实现到非标识Map页的分支)。
因此,您首先需要准备 * 4/5级页表 *,接下来您必须启用PAE(物理地址扩展),然后才能启用LME位。一旦启用LME位,您就可以启用 * 分页 *(如果您在设置LME位之前启用它,处理器将认为您使用32位分页,即2/3级页表,并产生错误的转换)。
下图说明了分页模式转换的工作原理:

在切换到IA-32e 64位子模式后,您必须重新加载系统数据结构(GDT,IDT,TSS等)。特别是为了能够跳转到64位代码,您必须打开GDT代码描述符的L位。重新加载所有这些结构后,您可以在64位模式下照常工作。

相关问题