Paging: Difference between revisions

1,897 bytes added ,  2 years ago
→‎Enabling: Added section for enabling 64-bit paging
[unchecked revision][unchecked revision]
(→‎Enabling: Added section for enabling 64-bit paging)
Line 89:
 
== Enabling ==
=== 32-bit Paging ===
Enabling paging is actually very simple. All that is needed is to load CR3 with the address of the page directory and to set the paging (PG) and protection (PE) bits of CR0. Note: setting the paging flag when the protection flag is clear causes a general protection exception.
 
<source lang="ASM">
Line 99 ⟶ 100:
mov cr0, eax
</source>
 
Note: setting the paging flag when the protection flag is clear causes a [[Exceptions#General_Protection_Fault|general protection exception]]. Also, once paging has been enabled, any attempt to enable long mode by setting LME (bit 8) of the [[EFER|EFER register]] will trigger a [[Exceptions#General_Protection_Fault|GPF]]. The CR0.PG must first be cleared before EFER.LME can be set.
 
If you want to set pages as read-only for both userspace and supervisor, replace 0x80000001 above with 0x80010001, which also sets the WP bit.
Line 109 ⟶ 112:
mov cr4, eax
</source>
 
=== 64-bit Paging ===
Enabling paging in long mode requires a few more additional steps. Since it is not possible to enter long mode without paging with PAE active, the order in which one enables the bits are important. Firstly, paging must not be active (i.e. CR0.PG must be cleared.) Then, CR4.PAE (bit 5) and EFER.LME (bit 8 of MSR 0xC0000080) are set. If 57-bit virtual addresses are to be enabled, then CR4.LA57 (bit 12) is set. Finally, CR0.PG is set to enable paging.
 
<source lang="ASM">
; Skip these 3 lines if paging is already disabled
mov ebx, cr0
and ebx, ~(1 << 31)
mov cr0, ebx
 
; Enable PAE
mov edx, cr4
or edx, (1 << 5)
mov cr4, edx
 
; Set LME (long mode enable)
mov ecx, 0xC0000080
rdmsr
or eax, (1 << 8)
wrmsr
 
; Replace 'pml4_table' with the appropriate physical address (and flags, if applicable)
mov eax, pml4_table
mov cr3, eax
 
; Enable paging (and protected mode, if it isn't already active)
or ebx, (1 << 31) | (1 << 0)
mov cr0, ebx
 
; Now reload the segment registers (CS, DS, SS, etc.) with 64-bit segment selectors...
 
mov ax, DATA_SEL
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp CODE_SEL:reloadCS
 
[BITS 64]
reloadCS:
hlt ; Done
jmp reloadCS
</source>
 
Once paging has been enabled, you cannot switch from 4-level paging to 5-level paging (and vice-versa) directly. The same is true for switching to legacy 32-bit paging. You must first disable paging by clearing CR0.PG before making changes. Failure to do so will result in a [[Exceptions#General_Protection_Fault|general protection fault]].
 
== Physical Address Extension ==
Anonymous user