diff --git a/kernel/arch/boot.s b/kernel/arch/boot.s index 570146d..dc31dbc 100644 --- a/kernel/arch/boot.s +++ b/kernel/arch/boot.s @@ -1,3 +1,7 @@ +; Here is our entry point to the kernel +; A very simple assembly file +; We set up some parameters and then pass the execution to our kmain + global loader ; entry symbol for ELF extern kmain @@ -6,12 +10,17 @@ FLAGS equ 0x3 CHECKSUM equ -(MAGIC_NUMBER + FLAGS) ; calculate the checksum KERNEL_STACK_SIZE equ 4096 +; The multiboot section is a semi requirement for grub +; All this is doing is placing the required magic number, flags, and the checksum into the file first +; This lets grub know if this is a valid multiboot kernel or not section .multiboot align 4 ; code must be 4 byte aligned dd MAGIC_NUMBER dd FLAGS dd CHECKSUM +; Here we're setting up the stack +; Giving us 4096 bytes (resb) section .bss align 4 kernel_stack: @@ -19,10 +28,12 @@ kernel_stack: section .text loader: - mov esp, kernel_stack + KERNEL_STACK_SIZE + mov esp, kernel_stack + KERNEL_STACK_SIZE ; move the top of the stack into esp - call kmain + call kmain ; pass execution over to our kmain function, where all of the real stuff is done - ;cli + ; Should the system exit, we clear the interrupt flag + ; and do an infinite loop of nothing + cli loop: hlt jmp loop diff --git a/kernel/arch/gdt/gdt_entry.c b/kernel/arch/gdt/gdt_entry.c index 9bf32a4..6da72b5 100644 --- a/kernel/arch/gdt/gdt_entry.c +++ b/kernel/arch/gdt/gdt_entry.c @@ -6,6 +6,25 @@ #include #endif +/** + * What is this file? + * + * Well, to properly set up a lot of the system, we need something called a GDT + * or, a Global Descriptor Table. + * + * This table, establishes a few things. + * + * Mainly it sets 4 segments, + * A kernel code segment, with RING 0 permissions + * A kernel data segment, with RING 0 permissions + * A user code segment, with RING 3 permissions + * A user data segment, with RING 3 permissions + * + * This allows for future userspace to properly segment code and data, + * anything in userspace shouldn't have access to hardware like the kernel does + * So by passing through this GDT, we can dish out authority to access certain data, functions, + * etc, by going through the CPU permission system (RING 0 - 3) + */ uint64_t gdt[GDT_SIZE]; @@ -26,12 +45,14 @@ uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag) return descriptor; } +#ifdef __TESTING__ void dump_gdt(void) { for (int i = 0; i < GDT_SIZE; i++) { printf("GDT_ENTRY %d: %4 | %2\n", i, gdt[i], gdt[i]); } } +#endif void gdt_init(void) diff --git a/kernel/arch/link.ld b/kernel/arch/link.ld index a1ad6b1..cf4ae48 100644 --- a/kernel/arch/link.ld +++ b/kernel/arch/link.ld @@ -1,25 +1,41 @@ -ENTRY(loader) +/** + * This is the linker file. + * + * This file tells the linker (ld) how we want to arrange the code into the output file. + */ +ENTRY(loader) /* This is the first entry point, defined in boot.s */ SECTIONS { - . = 1M; + /* + * This is telling the linker that anything after here should be loaded at 2M onwards + * The reason for 2M, is that we want to give room for the BIOS, (and UEFI), 2M is generally regarded as a safe spot + * to place the memory offset + * */ + . = 2M; - .text BLOCK(4K) : ALIGN(4K) + /* + * BLOCK is an alias for ALIGN, we're telling the linker that we want each section to be aligned at 4K + */ + .text BLOCK(4K) : ALIGN(4K) /* The first section we want is the text section, this is where most code is */ { - *(.multiboot) - *(.text) + *(.multiboot) /* Multiboot needs to be early in the file, required by grub */ + *(.text) /* The text section */ } + /* R/O data */ .rodata BLOCK(4K) : ALIGN(4K) { *(.rodata) } + /* Data */ .data BLOCK(4K) : ALIGN(4K) { *(.data) } + /* BSS */ .bss BLOCK(4K) : ALIGN(4K) { *(COMMON)