我在xv6 https://github.com/chrisdew/xv6/blob/master/bootasm.S中发现了很多装配,它向我展示了如何从16位移动到32位保护模式。
是否有人知道进入64位模式的类似示例? (通过或不使用32位模式。)
答案 0 :(得分:7)
为了启用64位功能,必须将CPU切换到长模式。
在64位x86处理器(x86-64)上进入长模式:
If paging is enabled, disable paging.
If CR4.PAE is not already set, set it.
Set IA32_EFER.LME = 1.
Load CR3 with a valid PML4 table.
Enable paging.
At this point you will be in compatibility mode. A far jump may be executed to switch to long mode. However, the offset must not exceed 32-bit.
答案 1 :(得分:2)
OSDev是x86上的低级信息(以及其他架构上的一点)的良好资源。例如,this article在Long模式下是一个非常好的写入,以及如何从保护模式和直接从实模式输入它:
进入长模式
进入长模式可以从实模式和保护模式完成, 但是,英特尔和AMD64手册中仅涵盖了保护模式。 早期的AMD文档解释了此过程在实模式下工作 好。
答案 2 :(得分:2)
如果您想直接进入64位模式,可以执行以下操作:
%xdefine PML4_BASE 0x70000 ; Address of PML4-table.
%xdefine CR0_PE 1 << 0
%xdefine CR0_PG 1 << 31
%xdefine CR4_PAE 1 << 5
%xdefine CR4_PGE 1 << 7
%xdefine EFER_LME 1 << 8
mov eax, CR4_PAE | CR4_PGE ; Set PAE- (Physical Address Extensions) and
mov cr4, eax ; PGE- (Page Global Enable).
mov eax, PML4_BASE ; Address of PML4.
mov cr3, eax ; Point CR3 to PML4.
mov ecx, 0xC0000080 ; EFER MSR selector.
rdmsr ; Read from model specific register.
or eax, EFER_LME ; Set LME (Long Mode Enable).
wrmsr ; Write to model specific register.
mov ebx, cr0 ; Get CR0.
or ebx, CR0_PG | CR0_PE ; Set PG (Paging) and PE (Protection Enabled).
mov cr0, ebx ; Set flags to CR0.
lgdt [GDT.ptr] ; Load global descriptor table.
jmp GDT.code_0:long_mode_entry ; Jump to long mode.
以上代码要求您已经设置了页面表和全局描述符表。