Feat: Finnaly in 32-bits
This commit is contained in:
parent
751c1f527d
commit
af903b190a
181
boot.asm
181
boot.asm
@ -1,101 +1,122 @@
|
||||
; File: boot.asm
|
||||
global _start
|
||||
extern kmain
|
||||
[org 0x7c00] ; BIOS loads us at 0x7C00
|
||||
[bits 16] ; We start in 16-bit Real Mode
|
||||
|
||||
section .multiboot
|
||||
; Multiboot header
|
||||
dd 0x1BADB002 ; magic number
|
||||
dd 0x00000003 ; flags
|
||||
dd -(0x1BADB002 + 0x00000003) ; checksum
|
||||
start:
|
||||
mov bp, 0x7c00
|
||||
mov sp, bp
|
||||
|
||||
call clear_screen
|
||||
|
||||
section .text
|
||||
[bits 32]
|
||||
_start:
|
||||
mov esp, kernel_stack_top
|
||||
cli ; Clear interrupts
|
||||
mov si, real_msg
|
||||
call print_string
|
||||
|
||||
; Load the gdt_ptr
|
||||
lgdt [gdt_ptr]
|
||||
cli
|
||||
|
||||
mov eax, pml4_table
|
||||
mov cr3, eax ; Load the PML4 table into CR3
|
||||
|
||||
; 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
|
||||
|
||||
mov eax, cr4
|
||||
or eax, 0x20 ; Enable PAE
|
||||
mov cr4, eax
|
||||
|
||||
mov ecx, 0xC0000080 ; IA32_EFER MSR
|
||||
rdmsr
|
||||
or eax, 0x00000100 ; Set LME (Long Mode Enable) bit
|
||||
wrmsr
|
||||
|
||||
; Enable long mode
|
||||
mov eax, cr0
|
||||
or eax, 0x80000000 ; Set the Long Mode Enable (LME) bit
|
||||
lgdt [gdt_descriptor]
|
||||
|
||||
mov eax, cr0
|
||||
or eax, 0x1
|
||||
mov cr0, eax
|
||||
|
||||
; Jump to 64-bit code Segment
|
||||
jmp 0x08:long_mode_start
|
||||
; Far jump into 32-bit mode.
|
||||
jmp 0x08:init_pm
|
||||
|
||||
section .bss
|
||||
; We define the stack size and labels in the uninitialized data section (.bss)
|
||||
kernel_stack_bottom:
|
||||
; Reserve 16 KB for the stack
|
||||
resb 16 * 1024
|
||||
kernel_stack_top:
|
||||
; --- 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
|
||||
|
||||
; --- Helper: Clear Screen ---
|
||||
clear_screen:
|
||||
pusha
|
||||
mov ah, 0x00 ; Set Video Mode function
|
||||
mov al, 0x03 ; 80x25 Text Mode
|
||||
int 0x10
|
||||
popa
|
||||
ret
|
||||
|
||||
pml4_table:
|
||||
; Define a simple PML4 table here (identity mapping for simplicity)
|
||||
; In a real kernel, you would set up proper paging structures
|
||||
resb 4096 ; Reserve 4 KB for the PML4 table
|
||||
pml4_end:
|
||||
real_msg: db '[REAL] - Loaded successfully.', 0x0D, 0x0A, 0
|
||||
|
||||
pdpt_table:
|
||||
resb 4096 ; Reserve 4 KB for the PDPT table
|
||||
pdpt_end:
|
||||
gdt_start:
|
||||
|
||||
pd_table:
|
||||
resb 4096 ; Reserve 4 KB for the PD table
|
||||
pd_end:
|
||||
gdt_null: ; 8 bytes of zeros
|
||||
dd 0x0
|
||||
dd 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_data: ; Data Segment (0x10)
|
||||
; Base=0, Limit=0xFFFFF, Access=0x92, Flags=0xC
|
||||
dw 0xffff
|
||||
dw 0x0
|
||||
db 0x0
|
||||
db 10010010b ; Access Byte (0x92)
|
||||
db 11001111b ; Flags (0xC) + Limit
|
||||
db 0x0
|
||||
|
||||
section .data
|
||||
gdt_ptr:
|
||||
dw (gdt_end - gdt_start - 1) ; Limit (set by linker/code later)
|
||||
dq gdt_start ; Base Address (set by linker/code later)
|
||||
gdt_start: ; Start of the actual GDT entries
|
||||
; Entry 0: Null Descriptor
|
||||
dq 0x0000000000000000
|
||||
dq 0x00AF9A000000FFFF
|
||||
dq 0x00AF92000000FFFF
|
||||
gdt_end:
|
||||
|
||||
section .text
|
||||
[bits 64] ; Tell NASM to assemble in 64-bit mode
|
||||
gdt_descriptor:
|
||||
dw gdt_end - gdt_start - 1 ; Size (Limit)
|
||||
dd gdt_start ; Start Address
|
||||
|
||||
long_mode_start:
|
||||
; 1. Pass GRUB's Multiboot info (in ebx) as the first C argument (in rdi)
|
||||
; We must use the 64-bit register RDI, but the data is in the 32-bit EBX.
|
||||
; Moving ebx to rdi automatically clears the upper 32 bits of rdi.
|
||||
mov rdi, rbx
|
||||
; ==================================================
|
||||
; 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)
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov ss, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
; 2. Call the C kernel's main function
|
||||
call kmain
|
||||
mov ebp, 0x90000 ; Update stack to a safe 32-bit area
|
||||
mov esp, ebp
|
||||
|
||||
; 3. If kmain ever returns, halt the CPU
|
||||
hlt
|
||||
; 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
|
||||
|
||||
jmp $
|
||||
|
||||
; --- 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
|
||||
|
||||
16
build.sh
16
build.sh
@ -1,8 +1,12 @@
|
||||
echo ">>> Compiling bootloader"
|
||||
nasm boot.asm -o boot.o -f elf32
|
||||
#!/bin/sh
|
||||
export PATH=/usr/local/cross/bin:$PATH
|
||||
|
||||
echo ">>> Compiling kernel"
|
||||
gcc kernel.c -o kernel.o -c -m32 -ffreestanding -nostdlib -no-pie
|
||||
# 1. Assemble raw binary
|
||||
echo ">>> Assembling boot.asm to boot.bin..."
|
||||
nasm -f bin boot.asm -o boot.bin
|
||||
|
||||
echo ">>> Linking kernel"
|
||||
gcc -m32 -nostdlib -no-pie -T linker.ld -o SoraOS boot.o kernel.o
|
||||
# 2. Run QEMU as a raw disk drive
|
||||
echo ">>> Running QEMU with boot.bin..."
|
||||
qemu-system-x86_64 -drive format=raw,file=boot.bin
|
||||
|
||||
echo "Done!"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
OUTPUT_FORMAT(binary)
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
@ -21,7 +21,7 @@ SECTIONS
|
||||
/* Define the .data section immediately after .text */
|
||||
.data :
|
||||
{
|
||||
/* Put all .data sections from all input files here */
|
||||
/* Put all .data sections §from all input files here */
|
||||
*(.data)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user