Skip to content

Instantly share code, notes, and snippets.

@hibariya
Last active May 1, 2021 21:22
Show Gist options
  • Save hibariya/9dc9b836e39a04300a410e92368dec7d to your computer and use it in GitHub Desktop.
Save hibariya/9dc9b836e39a04300a410e92368dec7d to your computer and use it in GitHub Desktop.
Trying to get 4KB paging in long-mode...
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"
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