222 lines
4.3 KiB
NASM
222 lines
4.3 KiB
NASM
; File: boot.asm
|
|
[org 0x7c00] ; BIOS loads us at 0x7C00
|
|
[bits 16] ; We start in 16-bit Real Mode
|
|
|
|
start:
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov ss, ax
|
|
mov sp, 0x7c00
|
|
|
|
mov ah, 0x00
|
|
mov al, 0x03
|
|
int 0x10
|
|
|
|
mov si, real_msg
|
|
call print_string
|
|
|
|
cli
|
|
|
|
lgdt [gdt_descriptor]
|
|
|
|
mov eax, cr0
|
|
or eax, 0x1
|
|
mov cr0, eax
|
|
|
|
; Far jump into 32-bit mode.
|
|
jmp 0x08:init_pm
|
|
|
|
; --- Helper: Print String (BIOS INT 0x10) ---
|
|
print_string:
|
|
pusha
|
|
mov ah, 0x0e ; INT 0x10 "Teletype Output" function
|
|
.loop:
|
|
lodsb ; Load byte at [SI] into AL, increment SI
|
|
cmp al, 0 ; Check for null terminator
|
|
je .done
|
|
int 0x10 ; Call BIOS video interrupt
|
|
jmp .loop
|
|
.done:
|
|
popa
|
|
ret
|
|
|
|
real_msg: db '[REAL] - Loaded successfully.', 0x0D, 0x0A, 0
|
|
|
|
; --- GDT (Global Descriptor Table) ---
|
|
align 8
|
|
gdt_start:
|
|
|
|
gdt_null:
|
|
dq 0x0
|
|
|
|
gdt_code32: ; 32-bit code segment (selector 0x08)
|
|
dw 0xffff ; Limit 0:15
|
|
dw 0x0000 ; Base 0:15
|
|
db 0x00 ; Base 16:23
|
|
db 10011010b ; Access: present, ring 0, code, executable, readable
|
|
db 11001111b ; Flags: 4KB granularity, 32-bit | Limit 16:19
|
|
db 0x00 ; Base 24:31
|
|
|
|
gdt_data32: ; 32-bit data segment (selector 0x10)
|
|
dw 0xffff
|
|
dw 0x0000
|
|
db 0x00
|
|
db 10010010b ; Access: present, ring 0, data, writable
|
|
db 11001111b
|
|
db 0x00
|
|
|
|
gdt_code64: ; 64-bit code segment (selector 0x18)
|
|
dw 0xffff
|
|
dw 0x0000
|
|
db 0x00
|
|
db 10011010b ; Access: present, ring 0, code, executable, readable
|
|
db 10101111b ; Flags: 4KB granularity, 64-bit, limit 16:19
|
|
db 0x00
|
|
|
|
gdt_data64: ; 64-bit data segment (selector 0x20)
|
|
dw 0xffff
|
|
dw 0x0000
|
|
db 0x00
|
|
db 10010010b
|
|
db 10101111b
|
|
db 0x00
|
|
|
|
gdt_end:
|
|
|
|
gdt_descriptor:
|
|
dw gdt_end - gdt_start - 1
|
|
dd gdt_start
|
|
|
|
; ==================================================
|
|
; 32-BIT PROTECTED MODE
|
|
; ==================================================
|
|
[bits 32]
|
|
init_pm:
|
|
; Set up segments
|
|
mov ax, 0x10
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov ss, ax
|
|
mov esp, 0x90000
|
|
|
|
; Print message in Protected Mode
|
|
; Print to VGA memory
|
|
mov edi, 0xb8000
|
|
mov al, 'P'
|
|
mov ah, 0x0f
|
|
mov [edi], ax
|
|
add edi, 2
|
|
mov al, 'M'
|
|
mov [edi], ax
|
|
add edi, 2
|
|
mov al, '3'
|
|
mov [edi], ax
|
|
add edi, 2
|
|
mov al, '2'
|
|
mov [edi], ax
|
|
|
|
; Set up page tables for identity mapping first 2MB
|
|
; PML4[0] -> PDPT
|
|
mov edi, 0x1000
|
|
mov dword [edi], 0x2003 ; Present, Writable, points to 0x2000
|
|
add edi, 4
|
|
mov dword [edi], 0
|
|
|
|
; PDPT[0] -> PD
|
|
mov edi, 0x2000
|
|
mov dword [edi], 0x3003 ; Present, Writable, points to 0x3000
|
|
add edi, 4
|
|
mov dword [edi], 0
|
|
|
|
; PD[0] -> 2MB page at physical 0x0
|
|
mov edi, 0x3000
|
|
mov dword [edi], 0x83 ; Present, Writable, Page Size (2MB)
|
|
add edi, 4
|
|
mov dword [edi], 0
|
|
|
|
; Load CR3 with PML4 address
|
|
mov eax, 0x1000
|
|
mov cr3, eax
|
|
|
|
; Enable PAE (Physical Address Extension)
|
|
mov eax, cr4
|
|
or eax, 0x20
|
|
mov cr4, eax
|
|
|
|
; Enable Long Mode in EFER MSR
|
|
mov ecx, 0xC0000080
|
|
rdmsr
|
|
or eax, 0x100
|
|
wrmsr
|
|
|
|
; Enable Paging (activates Long Mode)
|
|
mov eax, cr0
|
|
or eax, 0x80000000
|
|
mov cr0, eax
|
|
|
|
; Far jump to 64-bit code
|
|
jmp 0x18:long_mode_start
|
|
|
|
jmp $
|
|
|
|
; --- 64-bit Long Mode ---
|
|
[bits 64]
|
|
long_mode_start:
|
|
; Set up segments (most are ignored in 64-bit mode)
|
|
mov ax, 0x20
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov ss, ax
|
|
|
|
; Set up stack
|
|
mov rsp, 0x90000
|
|
|
|
; Clear screen and print "SORA OS 64"
|
|
mov rdi, 0xb8000
|
|
mov rcx, 80*25
|
|
mov ax, 0x0f20 ; White space
|
|
rep stosw
|
|
|
|
; Print message
|
|
mov rdi, 0xb8000
|
|
mov rsi, long_msg
|
|
call print_string_64
|
|
|
|
; Hang
|
|
jmp $
|
|
|
|
; --- 64-bit Print String ---
|
|
print_string_64:
|
|
mov ah, 0x0f ; White on black
|
|
.loop:
|
|
lodsb
|
|
test al, al
|
|
jz .done
|
|
stosw ; Write character + attribute
|
|
jmp .loop
|
|
.done:
|
|
ret
|
|
|
|
long_msg: db 'SoraOS 64-BIT', 0
|
|
|
|
; --- The Magic Boot Sector Footer ---
|
|
; Fill the rest of the 512 bytes with zeros
|
|
times 510-($-$$) db 0
|
|
; The BIOS signature (must be at the very end)
|
|
dw 0xAA55
|
|
|
|
section .bss
|
|
align 4096
|
|
pml4_table:
|
|
resb 4096
|
|
pdpt_table:
|
|
resb 4096
|
|
pd_table:
|
|
resb 4096
|
|
|