From af903b190addcfe5c5859419a2869493a707986c Mon Sep 17 00:00:00 2001 From: AfonsoCMSousa Date: Tue, 18 Nov 2025 20:28:27 +0000 Subject: [PATCH] Feat: Finnaly in 32-bits --- SoraOS | Bin 5836 -> 522 bytes boot.asm | 181 ++++++++++++++++++++++++++++++------------------------ build.sh | 16 +++-- kernel.o | Bin 1256 -> 0 bytes linker.ld | 4 +- 5 files changed, 113 insertions(+), 88 deletions(-) delete mode 100644 kernel.o diff --git a/SoraOS b/SoraOS index 79db673e34a56778dee31e6c03f7de60cd8f3c08..01961b6b991fb442f648b025e7378c592e1bff9d 100755 GIT binary patch literal 522 zcmYk1JxBs!7{{Nx{35mYh@!!U7onk{BTSmp5{?$lqYnrR1y3C6BuBWS$<(EY$h}$9P;yC2cN_VW_07u6BgjRR^tS?XO30Ghj623 zXjEB`_#39ZBjN&>b^$FG=pmC-$3yk!A+rNGhl)k*iCsQNWliEkXtVf0iNASU05C|v zi@yeBnoz@w-2(9&Z^O9Yg4pWH4Y@opG>=j`f`S{0Cjb7ivAI@PssiW@-O!u5r9W1K zJb+ZPP0a1Pu|8XP4?dTr(yL@fT5M4|jkB%x~qGr>S%{$PTcDUjxR9ssI20 literal 5836 zcmeHLQEMDk6h5=N$!^+BcZ?MuqOyb_6?EK&tw@#PCfy{$+O(S#`!=1;Om|~;cDB1W zkc#MP5UuS)^fCD4gD+BAq=JGE3)>O}->oRL4;G8`MewN>*6-Xqw^>sWf503#bHDGL z@7_Ce?wx_T?-Wb3hGCGl7{!TMhfK<&{dB*|F_I0Sz!lz$C>^~rd%OvYO&V?3Qme29O0{eS)= zbn?f%urKv~Y7mD}K zY|~;A?M62SxS(JHu&m%PU_rqYU{=9BJK8khVsi8Qo~#Skmuo$D>?HMH-JkZCZan#! zSvTG|GWk`^w0^#jnCv}HTgE@nIAp!HE|Y9Oxs3jUHa9bKIC}siK9fC|x2CLv*{R&r zpGzYET5rz}Aqhlm?~o&hTP76N>}q%2OC0Ir7P8Q1|m z@QWcIiw)C9;C$}IW@3b&(8iJHJwFCcl^_t7)AniAYc;&O-4@RBs$B_$2zJFp(4?kc z&)dSO)I9~ghD%MiDRhjXiam%(UUh}t6fNQwGqi+6tgHu(s_h4^7sl0XSj%MF*a3EN z-kvQNUMt%3N6Tc-l@_K8C3|6ZcCol*FBPUsMH|BP7hkZd9%fj!MQyFIYB}q)>N_h9 zBCCDQ$Ni!eE!EaE^4IEOg&&_RuV$ZVIli}p?3&vmOL*(ZHUi;U)yA4tSzD>Q&#kyB zVg38Wmg@+ItSZXdtfP0O-6m@}@O`f#coqJijYGzJo4+;kgb+)ZmRMc%zJD52>(W@^ zG<2l_o&I*^26Xa_5<30{YSX$S2=I8raNai^=zh~8w4lu^2e1Gyx6lbH8GNUef zJbqvFc)Tw!LZ@@A)X&ilF@H<={n>7!E=wnc|5Mo2%P8C_UxlXH#I@aW3ln= Q4C?mcL%Jz5>Y{aj1Ag{3#Q*>R 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 25eef42e369f2810c0c15d41120968b825013e5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1256 zcma)5&ubG=5T4!qG^Vu{4?+cVP>Dz%X-GxHLz9x^5)3rWdEKVlL}Grh*+41m3h~RxcH6R=rYbly|M&VyRZPB!L{d7Q+x@W`x`UzP zdWWJ|-04^cuHAD)wcWvZh;IH{K7x6Bfz9`sgz`K27I;_G`%vBw-z$Z8$+>IMcejSX z4d_;w_>Kf;&w9K;)?)pKQ10RAC};jUUv#}E2$BCUUJe}YiSrQ18I)&f(e-Kw5R*?i zhw67rpE+tXv@pI*L#vIh=OEy}jW98V&4!pp_izNvJz;xt1Y#rgfhCOtpC uck(!o#aeKsfWQ!T2}%x?`&diQ4p7d))BhoT)}inXEb`ds7e5m$n)e4n+mk#1 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) }