; 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