6

我在 xv6 https://github.com/chrisdew/xv6/blob/master/bootasm.S中找到了一些不错的程序集,它向我展示了如何从 16 位保护模式转移到 32 位保护模式。

有谁知道进入 64 位模式的类似示例?(通过或不使用 32 位模式。)

4

3 回答 3

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.
于 2014-04-09T12:44:20.113 回答
3

如果你想直接进入 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.

上面的代码要求你已经设置了页表和全局描述符表。

于 2014-04-11T07:37:57.727 回答
2

OSDev是 x86 (以及其他架构的一些)低级信息的好资源。例如,这篇文章是一篇关于长模式以及如何从保护模式和直接从实模式进入它的很好的文章:

进入长模式

可以从实模式和保护模式进入长模式,但是 Intel 和 AMD64 手册中只介绍了保护模式。早期的 AMD 文档解释了这个过程也适用于实模式。

于 2014-04-09T13:15:10.003 回答