我们正在开发一个名为 Pintos 的教育操作系统,试图将其设置为支持虚拟化。我们从运行 32 位的版本开始,第一步是切换到 64 位模式并从那里继续。我们通过 Bochs 运行 Pintos。
我们在英特尔程序员手册(第 9.8.5 章,第 3 卷)中查找了执行此操作的步骤,当我们要将 IA32 EFER.LME 位设置为 1 以启用 IA32e 模式时,系统会生成三重故障并再次从头开始工作。
这是我们一直在处理的代码。
#Step 1: Disable paging CR0_PG = 0. Use MOV CR0 instr. to disable paging (instr. must be located in an identity-mapped page.
movl %cr0, %eax
andl $0x7fffffff, %eax
movl %eax, %cr0
#Step 2: Enable physical-address extensions by setting CR4_PAE = 1
movl %cr4, %eax
orl $CR4_PAE, %eax
movl %eax, %cr4
#Step 3: Load CR3 with the physical base address of the level 4 page map table PML4
movl $0xe000, %eax
movl %eax, %cr3
xchg %bx, %bx
#Step 4: Enable IA-32e mode by setting IA32_EFER_LME = 1
movl $0xc0000080, %ecx
rdmsr
or $IA32_EFER_LME, %eax
wrmsr
#Step 5: Enable paging CR0_PG = 1.
movl %cr0, %eax
orl $CR0_PG, %eax
movl %eax, %cr0
我们已尝试设置自己的 TSS,因为在英特尔建议的所有可能产生三重故障的情况中,这似乎是唯一合理的原因。
任何想法为什么会产生三重故障?一切似乎都很清楚,并且遵循了步骤,但内核恐慌攻击仍然发生。