1.获取CPU的最大带宽

要开启PAE,必须要获得CPU的最大带宽,这可以通过CPUID.0x80000_0008指令获得:

在Loader.asm最后一行加上一下指令:

mov eax,0x8000_0008
cpuid
hlt    ;休眠CPU

make调试结果如下:

Next at t=0 (0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b
; ea5be000f0 <bochs:1> c Next at t=6085757593 (0) [0x000000000968]
0008:0000000000000968 (unk. ctxt): mov ebx, 0x00100000 ; bb00001000
<bochs:2> reg *rax: 00000000_00003028* rcx: 00000000_00000000 rdx:
00000000_00000000 rbx: 00000000_00000000 rsp: 00000000_00000900 rbp:
00000000_00007c63 rsi: 00000000_000e0000 rdi: 00000000_0000fdbe r8 :
00000000_00000000 r9 : 00000000_00000000 r10: 00000000_00000000 r11:
00000000_00000000 r12: 00000000_00000000 r13: 00000000_00000000 r14:
00000000_00000000 r15: 00000000_00000000 rip: 00000000_00000968 eflags
0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
<bochs:3> q (0).[6085757593][0x000000000968] 0008:0000000000000968 (unk.
ctxt): mov ebx, 0x00100000 ; bb00001000

可以看到:执行`cpuid`指令后,rax=0x3028=11_0000_0010_1000,其中,前8位=40,因此,虚拟机的最大带宽为40。

2.查看CPU是否支持PAT

将上述代码更改为:

mov eax,0x1
cpuid
hlt

Bochs调试结果如下:

Next at t=0 (0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b
; ea5be000f0 <bochs:1> c Next at t=4236232103 (0) [0x000000000968]
0008:0000000000000968 (unk. ctxt): mov ebx, 0x00100000 ; bb00001000
<bochs:2> reg rax: 00000000_000206a7 rcx: 00000000_079ae3bf *rdx:
00000000_bfebfbff* rbx: 00000000_00010800 rsp: 00000000_00000900 rbp:
00000000_00007c63 rsi: 00000000_000e0000 rdi: 00000000_0000fdbe r8 :
00000000_00000000 r9 : 00000000_00000000 r10: 00000000_00000000 r11:
00000000_00000000 r12: 00000000_00000000 r13: 00000000_00000000 r14:
00000000_00000000 r15: 00000000_00000000 rip: 00000000_00000968 eflags
0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
<bochs:3> q (0).[4236232103][0x000000000968] 0008:0000000000000968 (unk.
ctxt): mov ebx, 0x00100000 ; bb00001000

可以看到,执行CPUID后,rdx.16bits=1,可以看到,模拟器支持PAT。

由于在支持PAT的PAE分页下,PCD和PWT的值来自关联的PDPTE寄存器,所以这里设置为0。

3.开启PAE

实现代码如下:

;---------------保护模式初始化完成--------------------
;下面准备PAE分页
;现在仅映射4G内存
;将PAE放到低端1M空间之上
Paging:
PDPTE_BASE    equ 0x100_000
PDE_BASE    equ 0x101000
PTE_BASE    equ 0x105000    ;四个页目录表占用16KB
    mov ebx,PDPTE_BASE            ;创建页目录指针表
    mov eax,0x8080800    ;第一个页目录表
    mov [ebx+4],eax
    mov [ebx+12],eax
    mov [ebx+20],eax
    mov [ebx+28],eax

    mov ecx,512                ;创建页目录表
    mov ebx,PDE_BASE
    mov eax,PTE_BASE
    add eax,7
    push ebp    ;现在ebp不为0
    mov ebp,0
.create_pde:
    mov [ebx+ebp],eax
    add ebp,8
    add eax,0x40000        ;每个页目录映射2M空间
    loop .create_pde

    mov ecx,0x40000            ;创建页表
    mov ebx,PTE_BASE
    mov eax,7
    mov ebp,0
.create_pte:
    mov [ebx+ebp],eax
    add ebp,8
    add eax,409
    loop .create_pte

    mov eax,0x0200_0000
    mov cr3,eax

    mov eax,cr4
    or  eax,1_00000b
    mov cr4,eax
;EFER.LME=1
    mov ecx,0xc0000080
    rdmsr                ;将EFER读取到EDX:EAX中
    or  eax,1_00000000b
    wrmsr

    mov eax,cr0
    or  eax,0x80000000
    mov cr0,eax

    hlt

其中,rdmsr和wrmsr指令与中断类似,但是使用ecx储存MSR号(EFER的MSR号为`0xc0000080`),并将结果读取到EDX:EAX中。

Bochs调试结果如下:

Next at t=0 (0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b
; ea5be000f0 <bochs:1> show mode show mode switch: ON show mask is: mode
<bochs:2> b 0x9e6 <bochs:3> c 00000362789: switched from ‘real mode’ to
‘protected mode’ 00001713048: switched from ‘protected mode’ to ‘real
mode’ 00001713058: switched from ‘real mode’ to ‘protected mode’
00001901775: switched from ‘protected mode’ to ‘real mode’ 00006122382:
switched from ‘real mode’ to ‘protected mode’ 00007173032: address space
switched. CR3: 0x000002000000 *00007173042: switched from ‘protected
mode’ to ‘compatibility mode’* (0).[7173042] ??? (physical address not
available) Next at t=7173043 (0) [0x0000fffffff0] f000:fff0 (unk. ctxt):
jmpf 0xf000:e05b ; ea5be000f0 <bochs:4> q (0).[7173043][0x0000fffffff0]
f000:fff0 (unk. ctxt): jmpf 0xf000:e05b ; ea5be000f0

可以看到loader已经进入IA32-e模式,但是结果却导致CPU复位:` jmpf 0xf000:e05b`结果有待改进。

在多次调试过程中发现:

当EPER.LME打开时,CPU并没有进入IA-32e模式,只有在PG为打开后才进入。

Last moify: 2024-12-23 07:55:59
Build time:2025-07-18 09:41:42
Powered By asphinx