Feat: FULLY IN 64-BIT MODE

This commit is contained in:
AfonsoCMSousa 2025-11-18 21:45:22 +00:00
parent c5cc6a0d8d
commit c1068d34e2

214
boot.asm
View File

@ -3,10 +3,15 @@
[bits 16] ; We start in 16-bit Real Mode [bits 16] ; We start in 16-bit Real Mode
start: start:
mov bp, 0x7c00 xor ax, ax
mov sp, bp 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 mov si, real_msg
call print_string call print_string
@ -36,116 +41,169 @@ print_string:
popa popa
ret 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 real_msg: db '[REAL] - Loaded successfully.', 0x0D, 0x0A, 0
; --- GDT (Global Descriptor Table) ---
align 8
gdt_start: gdt_start:
gdt_null: ; 8 bytes of zeros gdt_null:
dd 0x0 dq 0x0
dd 0x0
gdt_code: ; Code Segment (0x08) gdt_code32: ; 32-bit code segment (selector 0x08)
; Base=0, Limit=0xFFFFF, Access=0x9A, Flags=0xC dw 0xffff ; Limit 0:15
dw 0xffff ; Limit (bits 0-15) dw 0x0000 ; Base 0:15
dw 0x0 ; Base (bits 0-15) db 0x00 ; Base 16:23
db 0x0 ; Base (bits 16-23) db 10011010b ; Access: present, ring 0, code, executable, readable
db 10011010b ; Access Byte (0x9A) db 11001111b ; Flags: 4KB granularity, 32-bit | Limit 16:19
db 11001111b ; Flags (0xC) + Limit (bits 16-19) db 0x00 ; Base 24:31
db 0x0 ; Base (bits 24-31)
gdt_data: ; Data Segment (0x10) gdt_data32: ; 32-bit data segment (selector 0x10)
; Base=0, Limit=0xFFFFF, Access=0x92, Flags=0xC
dw 0xffff dw 0xffff
dw 0x0 dw 0x0000
db 0x0 db 0x00
db 10010010b ; Access Byte (0x92) db 10010010b ; Access: present, ring 0, data, writable
db 11001111b ; Flags (0xC) + Limit db 11001111b
db 0x0 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_end:
gdt_descriptor: gdt_descriptor:
dw gdt_end - gdt_start - 1 ; Size (Limit) dw gdt_end - gdt_start - 1
dd gdt_start ; Start Address dd gdt_start
; ================================================== ; ==================================================
; 32-BIT PROTECTED MODE ; 32-BIT PROTECTED MODE
; ================================================== ; ==================================================
[bits 32] [bits 32]
init_pm: init_pm:
; 5. Update Segment Registers ; Set up segments
; Now that we are in 32-bit, we must point all segment registers
; to our new Data Segment (0x10)
mov ax, 0x10 mov ax, 0x10
mov ds, ax mov ds, ax
mov ss, ax
mov es, ax mov es, ax
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
mov ss, ax
mov esp, 0x90000
mov ebp, 0x90000 ; Update stack to a safe 32-bit area ; Print message in Protected Mode
mov esp, ebp ; 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 ; Set up page tables for identity mapping first 2MB
mov eax, pml4_table ; 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 mov cr3, eax
; Link PML4 -> PDPT ; Enable PAE (Physical Address Extension)
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
mov eax, cr4 mov eax, cr4
or eax, 0x20 or eax, 0x20
mov cr4, eax mov cr4, eax
; 4. Enable Long Mode in EFER ; Enable Long Mode in EFER MSR
mov ecx, 0xC0000080 mov ecx, 0xC0000080
rdmsr rdmsr
or eax, 0x00000100 or eax, 0x100
wrmsr wrmsr
; 5. Enable Paging ; Enable Paging (activates Long Mode)
mov eax, cr0 mov eax, cr0
or eax, 0x80000000 or eax, 0x80000000
mov cr0, eax mov cr0, eax
; 6. Print "SoraOS Protected" directly to Video Memory ; Far jump to 64-bit code
; We can't use BIOS interrupts anymore! We must write to 0xB8000. jmp 0x18:long_mode_start
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
jmp $ 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 --- ; --- The Magic Boot Sector Footer ---
; Fill the rest of the 512 bytes with zeros ; Fill the rest of the 512 bytes with zeros
times 510-($-$$) db 0 times 510-($-$$) db 0
@ -161,13 +219,3 @@ pdpt_table:
pd_table: pd_table:
resb 4096 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: