From c6467b8ebcbbfac9e9baa8ce889ca7df86002889 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 10 Jan 2023 17:50:24 +0200 Subject: [PATCH] Kernel: Multiboot data and kernel command lines are now global variables --- kernel/arch/i386/VESA.cpp | 4 +- kernel/arch/i386/boot.S | 105 ++++++++++++++++++++++++++---- kernel/arch/i386/linker.ld | 12 ++-- kernel/arch/i386/make.config | 1 + kernel/include/kernel/multiboot.h | 3 +- kernel/kernel/TTY.cpp | 1 + kernel/kernel/kernel.cpp | 4 +- kernel/kernel/kmalloc.cpp | 11 +++- 8 files changed, 117 insertions(+), 24 deletions(-) diff --git a/kernel/arch/i386/VESA.cpp b/kernel/arch/i386/VESA.cpp index 163bc998..74790617 100644 --- a/kernel/arch/i386/VESA.cpp +++ b/kernel/arch/i386/VESA.cpp @@ -90,13 +90,13 @@ namespace VESA bool Initialize() { - if (!(s_multiboot_info->flags & MULTIBOOT_FLAGS_FRAMEBUFFER)) + if (!(g_multiboot_info->flags & MULTIBOOT_FLAGS_FRAMEBUFFER)) { derrorln("bootloader did not provide a memory map"); return false; } - auto& framebuffer = s_multiboot_info->framebuffer; + auto& framebuffer = g_multiboot_info->framebuffer; s_addr = framebuffer.addr; s_bpp = framebuffer.bpp; s_pitch = framebuffer.pitch; diff --git a/kernel/arch/i386/boot.S b/kernel/arch/i386/boot.S index 09029c9e..080d88ae 100644 --- a/kernel/arch/i386/boot.S +++ b/kernel/arch/i386/boot.S @@ -7,7 +7,7 @@ .set MB_CHECKSUM, -(MB_MAGIC + MB_FLAGS) #checksum of above, to prove we are multiboot # Multiboot header -.section .multiboot +.section .multiboot, "aw" .align 4 .long MB_MAGIC .long MB_FLAGS @@ -19,28 +19,111 @@ .long 600 .long 32 - # Create stack -.section .bss +.section .bss, "aw", @nobits + # Create stack stack_bottom: - .skip 16384 # 16 KiB + .skip 16384 stack_top: + + .global g_kernel_cmdline + g_kernel_cmdline: + .skip 4096 + + # Reserve memory for paging structures, + # we will identity map first 4 MiB + + # 0 MiB -> 2 MiB: kernel + # 2 MiB -> 3 MiB: kmalloc + # 3 MiB -> 4 Mib: kmalloc_eternal + .align 32 + boot_page_directory_pointer_table: + .skip 4 * 8 + .align 4096 + boot_page_directory1: + .skip 512 * 8 + + + +.section .text, "a" + +.global g_multiboot_info +g_multiboot_info: + .skip 4 +.global g_multiboot_magic +g_multiboot_magic: + .skip 4 + +has_cpuid: + pushfl + pushfl + xorl $0x00200000, (%esp) + popfl + pushfl + popl %eax + xorl (%esp), %eax + popfl + andl $0x00200000, %eax + ret + +has_pae: + call has_cpuid + cmpl $0, %eax + jz .exit + movl $0, %eax + cpuid + movl %edx, %eax + andl $0x40, %eax # PAE is bit 6 in edx +.exit: + ret -.section .text .global _start .type _start, @function _start: + # Initialize stack and multiboot info movl $stack_top, %esp + movl %eax, g_multiboot_magic + movl %ebx, g_multiboot_info - pushl %eax - pushl %ebx + # Copy kernel command line to known location + movl %ebx, %esi + addl $16, %esi + movl (%esi), %esi + movl $1024, %ecx + movl $g_kernel_cmdline, %edi + rep movsl + + call has_pae + cmpl $0, %eax + jz system_halt + + # identity map first 4 MiB + movl $(0x00000000 + 0x83), boot_page_directory1 + 0 + movl $(0x00200000 + 0x83), boot_page_directory1 + 8 + movl $(boot_page_directory1 + 0x01), boot_page_directory_pointer_table + + # enable PAE + movl %cr4, %ecx + orl $0x20, %ecx + movl %ecx, %cr4 + + # set address of paging structures + movl $boot_page_directory_pointer_table, %ecx + movl %ecx, %cr3 + + # enable paging + movl %cr0, %ecx + orl $0x80000000, %ecx + movl %ecx, %cr0 + + xchgw %bx, %bx + # call global constuctors call _init + # call to the kernel itself call kernel_main +system_halt: cli -1: - hlt +1: hlt jmp 1b - -.size _start, . - _start diff --git a/kernel/arch/i386/linker.ld b/kernel/arch/i386/linker.ld index 7fd644df..2fb00647 100644 --- a/kernel/arch/i386/linker.ld +++ b/kernel/arch/i386/linker.ld @@ -1,9 +1,9 @@ -ENTRY(_start) - +ENTRY (_start) + SECTIONS { - . = 1M; - + . = 0x00100000; + .text BLOCK(4K) : ALIGN(4K) { *(.multiboot) @@ -22,4 +22,6 @@ SECTIONS *(COMMON) *(.bss) } -} + + g_kernel_end = .; +} \ No newline at end of file diff --git a/kernel/arch/i386/make.config b/kernel/arch/i386/make.config index c1e51d96..160017ec 100644 --- a/kernel/arch/i386/make.config +++ b/kernel/arch/i386/make.config @@ -9,5 +9,6 @@ $(ARCHDIR)/boot.o \ $(ARCHDIR)/CPUID.o \ $(ARCHDIR)/GDT.o \ $(ARCHDIR)/IDT.o \ +$(ARCHDIR)/MMU.o \ $(ARCHDIR)/Paging.o \ $(ARCHDIR)/VESA.o \ diff --git a/kernel/include/kernel/multiboot.h b/kernel/include/kernel/multiboot.h index 143c1a73..44d301f1 100644 --- a/kernel/include/kernel/multiboot.h +++ b/kernel/include/kernel/multiboot.h @@ -48,4 +48,5 @@ struct multiboot_info_t framebuffer_info_t framebuffer; } __attribute__((packed)); -extern multiboot_info_t* s_multiboot_info; +extern "C" multiboot_info_t* g_multiboot_info; +extern "C" uint32_t g_multiboot_magic; diff --git a/kernel/kernel/TTY.cpp b/kernel/kernel/TTY.cpp index afb90c93..f3831028 100644 --- a/kernel/kernel/TTY.cpp +++ b/kernel/kernel/TTY.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 3628d115..6ef10737 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -17,8 +18,7 @@ #define DISABLE_INTERRUPTS() asm volatile("cli") #define ENABLE_INTERRUPTS() asm volatile("sti") - -multiboot_info_t* s_multiboot_info; +extern "C" const char g_kernel_cmdline[]; using namespace BAN; diff --git a/kernel/kernel/kmalloc.cpp b/kernel/kernel/kmalloc.cpp index 61bbc8ea..eb34fa28 100644 --- a/kernel/kernel/kmalloc.cpp +++ b/kernel/kernel/kmalloc.cpp @@ -9,6 +9,8 @@ #define ALIGN (alignof(max_align_t)) +extern "C" uintptr_t g_kernel_end; + /* #### KMALLOC ################ */ @@ -47,14 +49,17 @@ static bool s_initialized = false; void kmalloc_initialize() { - if (!(s_multiboot_info->flags & (1 << 6))) + if (!(g_multiboot_info->flags & (1 << 6))) Kernel::Panic("Kmalloc: Bootloader didn't provide a memory map"); + if (g_kernel_end > s_kmalloc_node_base) + Kernel::Panic("Kmalloc: Kernel end is over kmalloc base"); + // Validate kmalloc memory bool valid = false; - for (size_t i = 0; i < s_multiboot_info->mmap_length;) + for (size_t i = 0; i < g_multiboot_info->mmap_length;) { - multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(s_multiboot_info->mmap_addr + i); + multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(g_multiboot_info->mmap_addr + i); if (mmmt->type == 1) {