Last active
May 1, 2021 21:22
-
-
Save hibariya/9dc9b836e39a04300a410e92368dec7d to your computer and use it in GitHub Desktop.
Trying to get 4KB paging in long-mode...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bits 16 | |
org 0x7c00 | |
k16bits: | |
%define PML4T 0x8000 | |
%define PDPT 0x9000 | |
%define PDT 0xa000 | |
%define PT 0xb000 | |
cli | |
; Set up PML4T | |
mov dword eax, PDPT | |
or dword eax, 011b ; user-mode / R/W / PML4E present | |
mov dword [PML4T], eax | |
mov dword [PML4T + 4], 0 | |
; Set up PDPT | |
mov dword eax, PDT | |
or dword eax, 011b | |
mov dword [PDPT], eax | |
mov dword [PDPT + 4], 0 | |
; Set up PDT | |
mov dword eax, PT | |
or dword eax, 0011b | |
mov dword [PDT], eax | |
mov dword [PDT + 4], 0 | |
; Set up PT | |
mov edi, PT | |
mov ebx, 011b | |
mov ecx, 512 | |
create_pages: | |
mov dword [edi], ebx | |
mov dword [edi + 4], 0 | |
add ebx, 0x1000 | |
add edi, 8 | |
loop create_pages | |
; Set CR4.PAE to 1 to enable 64-bit paging | |
mov eax, cr4 | |
or eax, 1 << 5 | |
mov cr4, eax | |
; CR3 = PML4T | |
mov eax, PML4T | |
mov cr3, eax | |
; Enable 64-bit mode | |
; A logical processor uses IA-32e paging if CR0.PG = 1, CR4.PAE = 1, and IA32_EFER.LME = 1. (intel manual: Vol.3A 4.5 IA-32E PAGING) | |
mov ecx, 0xc0000080 ; It's the argument for rdmsr following / MSR number of EFER is this constant | |
rdmsr ; Read EFER into eax | |
or eax, 1 << 8 ; Set EFER.LME (Long Mode Enable) to 1 | |
wrmsr | |
; Set CR0.PE and CR0.PG to 1 to enable protected-mode and paging | |
mov eax, cr0 | |
or eax, 1 << 31 | 1 << 0 | |
mov cr0, eax | |
lgdt [GDT64.Pointer] | |
jmp GDT64.Code:k64bits | |
bits 64 | |
k64bits: | |
mov rax, 0x123 | |
hlt | |
GDT64: ; Global Descriptor Table (64-bit). | |
.Null: equ $ - GDT64 ; The null descriptor. | |
dw 0 ; Limit (low). | |
dw 0 ; Base (low). | |
db 0 ; Base (middle) | |
db 0 ; Access. | |
db 0 ; Granularity. | |
db 0 ; Base (high). | |
.Code: equ $ - GDT64 ; The code descriptor. | |
dw 0 ; Limit (low). | |
dw 0 ; Base (low). | |
db 0 ; Base (middle) | |
db 10011010b ; Access (exec/read). | |
db 00100000b ; Granularity. | |
db 0 ; Base (high). | |
.Data: equ $ - GDT64 ; The data descriptor. | |
dw 0 ; Limit (low). | |
dw 0 ; Base (low). | |
db 0 ; Base (middle) | |
db 10010010b ; Access (read/write). | |
db 00000000b ; Granularity. | |
db 0 ; Base (high). | |
.Pointer: ; The GDT-pointer. | |
dw $ - GDT64 - 1 ; Limit. | |
dq GDT64 ; Base. | |
times 512 - 2 - ($ - $$) db 0 ; zero-pad the 512-byte sector to the last 2 bytes | |
dw 0xaa55 ; Magic "boot signature" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: bootable.bin | |
bootable.bin: | |
nasm boot.s -o $@ | |
clean: | |
rm -rf *.bin | |
run: bootable.bin | |
qemu-system-x86_64 -monitor stdio bootable.bin |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment