How to enter 64-bit mode on a x86_64

孤街醉人 提交于 2019-12-04 23:06:43

问题


I've found a nice bit of assembly in xv6 https://github.com/chrisdew/xv6/blob/master/bootasm.S which shows me how to move from 16 bit to 32 bit protected mode.

Does anyone know of a similar example for entering the 64-bit mode? (Either through or without using 32 bit mode.)


回答1:


In order to enable 64 bit capabillities, you must switch the CPU to Long Mode.

To enter Long Mode on a 64-bit x86 processor (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.



回答2:


OSDev is a good resource for low-level info on x86 (and a bit on other architectures). For example, this article is a pretty good writeup on the Long mode and how to enter it, both from protected mode and directly from real mode:

Entering Long Mode

Entering long mode can be both done from real mode and protected mode, however only protected mode is covered in the Intel and AMD64 manuals. Early AMD documentation explains this process works from real mode as well.




回答3:


If you want to go directly to 64-bit mode, you can do something like this:

%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.

Above code requires that you have already setup page tables and Global Descriptor Table.



来源:https://stackoverflow.com/questions/22962251/how-to-enter-64-bit-mode-on-a-x86-64

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!