diff --git a/SoraOS b/SoraOS index 79db673..01961b6 100755 Binary files a/SoraOS and b/SoraOS differ diff --git a/boot.asm b/boot.asm index 933bccd..4311289 100644 --- a/boot.asm +++ b/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 diff --git a/build.sh b/build.sh index 1e54115..be6b741 100755 --- a/build.sh +++ b/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!" diff --git a/kernel.o b/kernel.o deleted file mode 100644 index 25eef42..0000000 Binary files a/kernel.o and /dev/null differ diff --git a/linker.ld b/linker.ld index 28df9ed..d077ac7 100644 --- a/linker.ld +++ b/linker.ld @@ -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) }