From c1068d34e2600db6aec3ec21c45053b72931c589 Mon Sep 17 00:00:00 2001 From: AfonsoCMSousa Date: Tue, 18 Nov 2025 21:45:22 +0000 Subject: [PATCH] Feat: FULLY IN 64-BIT MODE --- boot.asm | 214 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 83 deletions(-) diff --git a/boot.asm b/boot.asm index a3b735b..0a3f2ba 100644 --- a/boot.asm +++ b/boot.asm @@ -3,10 +3,15 @@ [bits 16] ; We start in 16-bit Real Mode start: - mov bp, 0x7c00 - mov sp, bp + xor ax, ax + mov ds, ax + mov es, ax + mov ss, ax + mov sp, 0x7c00 - call clear_screen + mov ah, 0x00 + mov al, 0x03 + int 0x10 mov si, real_msg call print_string @@ -36,116 +41,169 @@ print_string: popa ret -; --- Helper: Clear Screen --- -clear_screen: - pusha - mov ah, 0x00 ; Set Video Mode function - mov al, 0x03 ; 80x25 Text Mode - int 0x10 - popa - ret - real_msg: db '[REAL] - Loaded successfully.', 0x0D, 0x0A, 0 +; --- GDT (Global Descriptor Table) --- +align 8 gdt_start: -gdt_null: ; 8 bytes of zeros - dd 0x0 - dd 0x0 +gdt_null: + dq 0x0 -gdt_code: ; Code Segment (0x08) - ; Base=0, Limit=0xFFFFF, Access=0x9A, Flags=0xC - dw 0xffff ; Limit (bits 0-15) - dw 0x0 ; Base (bits 0-15) - db 0x0 ; Base (bits 16-23) - db 10011010b ; Access Byte (0x9A) - db 11001111b ; Flags (0xC) + Limit (bits 16-19) - db 0x0 ; Base (bits 24-31) +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_data: ; Data Segment (0x10) - ; Base=0, Limit=0xFFFFF, Access=0x92, Flags=0xC +gdt_data32: ; 32-bit data segment (selector 0x10) dw 0xffff - dw 0x0 - db 0x0 - db 10010010b ; Access Byte (0x92) - db 11001111b ; Flags (0xC) + Limit - db 0x0 + 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 ; Size (Limit) - dd gdt_start ; Start Address + dw gdt_end - gdt_start - 1 + dd gdt_start ; ================================================== ; 32-BIT PROTECTED MODE ; ================================================== [bits 32] init_pm: - ; 5. Update Segment Registers - ; Now that we are in 32-bit, we must point all segment registers - ; to our new Data Segment (0x10) + ; Set up segments mov ax, 0x10 mov ds, ax - mov ss, ax mov es, ax mov fs, ax mov gs, ax + mov ss, ax + mov esp, 0x90000 - mov ebp, 0x90000 ; Update stack to a safe 32-bit area - mov esp, ebp + ; 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 - ; 2. Set up Paging - mov eax, pml4_table + ; 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 - ; Link PML4 -> PDPT - mov dword [pml4_table], pdpt_table + 0x3 - mov dword [pml4_table + 4], 0x0 - - ; Link PDPT -> PD - mov dword [pdpt_table], pd_table + 0x3 - mov dword [pdpt_table + 4], 0x0 - - ; Link PD -> 2MB Physical Page 0 - mov dword [pd_table], 0x83 - mov dword [pd_table + 4], 0x0 - - ; 3. Enable PAE + ; Enable PAE (Physical Address Extension) mov eax, cr4 or eax, 0x20 mov cr4, eax - ; 4. Enable Long Mode in EFER + ; Enable Long Mode in EFER MSR mov ecx, 0xC0000080 rdmsr - or eax, 0x00000100 + or eax, 0x100 wrmsr - ; 5. Enable Paging + ; Enable Paging (activates Long Mode) mov eax, cr0 or eax, 0x80000000 mov cr0, eax - ; 6. Print "SoraOS Protected" directly to Video Memory - ; We can't use BIOS interrupts anymore! We must write to 0xB8000. - mov ebx, 0xb8000 - mov byte [ebx], 'S' - mov byte [ebx+1], 0x0f ; White on Black - mov byte [ebx+2], 'O' - mov byte [ebx+3], 0x0f - mov byte [ebx+4], 'R' - mov byte [ebx+5], 0x0f - mov byte [ebx+6], 'A' - mov byte [ebx+7], 0x0f - mov byte [ebx+8], ' ' - mov byte [ebx+9], 0x0f - mov byte [ebx+10], 'P' - mov byte [ebx+11], 0x0f - mov byte [ebx+12], 'M' - mov byte [ebx+13], 0x0f + ; 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 @@ -161,13 +219,3 @@ pdpt_table: pd_table: resb 4096 -section .data -gdt_ptr: - dw (gdt_end - gdt_start - 1) - dq gdt_start -gdt_start: - dq 0x0000000000000000 - dq 0x00AF9A000000FFFF ; Code - dq 0x00AF92000000FFFF ; Data -gdt_end: -