From 1934e66796e6abc27f7209f2a8d528d1db0792b6 Mon Sep 17 00:00:00 2001 From: AfonsoCMSousa Date: Fri, 14 Nov 2025 22:20:27 +0000 Subject: [PATCH] Initial commit: kernel source and build scripts --- .gitignore | 5 ++++ boot.asm | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ build.sh | 8 ++++++ kernel.c | 15 +++++++++++ kernel.o | Bin 0 -> 1312 bytes linker.ld | 31 +++++++++++++++++++++ 6 files changed, 136 insertions(+) create mode 100644 .gitignore create mode 100644 boot.asm create mode 100755 build.sh create mode 100644 kernel.c create mode 100644 kernel.o create mode 100644 linker.ld diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..819a294 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +*.bin +*.elf +*.map + diff --git a/boot.asm b/boot.asm new file mode 100644 index 0000000..e204bce --- /dev/null +++ b/boot.asm @@ -0,0 +1,77 @@ +; File: boot.asm +global _start +extern kmain + +section .multiboot + ; Multiboot header + dd 0x1BADB002 ; magic number + dd 0x00000003 ; flags + dd -(0x1BADB002 + 0x00000003) ; checksum + + +section .text +[bits 32] +_start: + mov esp, kernel_stack_top + + ; Load the gdt_ptr + lgdt [gdt_ptr] + + mov cr3, pml4_table + + mov rax, cr4 + or rax, 0x20 ; Enable PAE + mov cr4, rax + + mov ecx, 0xC0000080 ; IA32_EFER MSR + rdmsr + or rax, 0x00000100 ; Set LME (Long Mode Enable) bit + wrmsr + + ; Enable long mode + mov rax, cr0 + or rax, 0x80000000 ; Set the Long Mode Enable (LME) bit + mov cr0, rax + + ; Jump to 64-bit code Segment + jmp 0x08:long_mode_start + +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: + +gdt_ptr: + dw 0 ; Limit (set by linker/code later) + dq 0 ; Base Address (set by linker/code later) +gdt_start: ; Start of the actual GDT entries + ; Entry 0: Null Descriptor + dq 0x0000000000000000 + ; Entry 1: 64-bit Code Segment Descriptor + ; Entry 2: 64-bit Data Segment Descriptor +gdt_end: + +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: + +section .text +[bits 64] ; Tell NASM to assemble in 64-bit mode + +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 + + ; 2. Call the C kernel's main function + call kmain + + ; 3. If kmain ever returns, halt the CPU + hlt + + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..e6b90e2 --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +echo ">>> Compiling bootloader" +nasm boot.asm -o boot.o -f elf64 + +echo ">>> Compiling kernel" +gcc kernel.c -o kernel.o -c -m64 -ffreestanding -nostdlib + +echo ">>> Linking kernel" +ld -T linker.ld -o SoraOS boot.o kernel.o diff --git a/kernel.c b/kernel.c new file mode 100644 index 0000000..b248273 --- /dev/null +++ b/kernel.c @@ -0,0 +1,15 @@ +// file: kerlnel.c + +void kmain(void) { + // Kernel main function + // Set VGA memory address + unsigned short *VGA_mem = (unsigned short *)0xB8000; + + VGA_mem[0] = (0x07 << 8) | 'S'; + VGA_mem[1] = (0x07 << 8) | 'O'; + VGA_mem[2] = (0x07 << 8) | 'R'; + VGA_mem[3] = (0x07 << 8) | 'A'; + VGA_mem[4] = (0x07 << 8) | ' '; + VGA_mem[5] = (0x07 << 8) | 'O'; + VGA_mem[6] = (0x07 << 8) | 'S'; +} diff --git a/kernel.o b/kernel.o new file mode 100644 index 0000000000000000000000000000000000000000..ddcc3d6b75e48d513c72de155a55b9364c958546 GIT binary patch literal 1312 zcmbtTK`#SA6n?v^ElNrpBplWW36s@SA`Vh%N)JLpBrd|LDN?&_wkuH=5{X1y`~)Yz z!BIHyNBjV{-gvK_w_TH-c**R0-}l}(Z)Ruas<6Il8V0Z#unZl^ ztm(Clof&IBD>7o<%Gj9&J8LhfWyR22IC^nl8JJ+a5XXBlG(3tqGUIX!jEl4}o=PMi zuy_JF8f0bqtPG`Z&HP~8bg+Vm?nZrL@b%p-+Y_#$lkLZFB*M3PQMw|1Po9YqR9xrO zYwd|>`u&k301)+t8#ssP1HbK0I11!N0OH6A91w@~I*3x$b)|=#R}G}V-!oSaoKi*M zWA9wl{Ax}5K?8&@&m197_RGHGO6vSS8%H_)o47VjPT_Fh3R7*=CJ_+V6D2Wz(lA3^ zKZOZ8w!i9UQA=~$IHJb=`L1w|`?II}$uZZEe~p4jtk)JWm%#Ds>=Az`jlM4Zitb?@ z&8h2~O24Q)J6*qv33^94E>QkaEp$xbKJ>Is)-&I&H%V-zKOlfc?}5%p*VDZE*&zk= aR>{(B7k(8T;$e)s>7P~Maah?7bo~#tL~ZW? literal 0 HcmV?d00001 diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..28e2a91 --- /dev/null +++ b/linker.ld @@ -0,0 +1,31 @@ +ENTRY(_start); +FORMAT(elf64-x86-64); + +SECTIONS +{ +/* Set the location counter to 0x100000 (1MB) */ +. = 0x100000; + +/* Define the .text section at the current location */ +.text : +{ + /* Put all .text sections from all input files here */ + *(.text) +} + +/* Define the .data section immediately after .text */ +.data : +{ + /* Put all .data sections from all input files here */ + *(.data) +} + +/* Define the .bss section immediately after .data */ +.bss : +{ + /* Put all .bss sections from all input files here */ + *(.bss) +} + +/* End of the linker script */ +}