diff --git a/libmaxsi/heap.cpp b/libmaxsi/heap.cpp index 30189b8f..92498966 100644 --- a/libmaxsi/heap.cpp +++ b/libmaxsi/heap.cpp @@ -68,12 +68,12 @@ namespace Maxsi #ifdef SORTIX_KERNEL addr_t GetHeapStart() { - return Sortix::Memory::HEAPUPPER; + return Sortix::Memory::GetHeapUpper(); } size_t GetHeapMaxSize() { - return Sortix::Memory::HEAPUPPER - Sortix::Memory::HEAPLOWER; + return Sortix::Memory::GetHeapUpper() - Sortix::Memory::GetHeapLower(); } void FreeMemory(addr_t where, size_t bytes) diff --git a/sortix/initrd.cpp b/sortix/initrd.cpp index 2b24da50..426d2756 100644 --- a/sortix/initrd.cpp +++ b/sortix/initrd.cpp @@ -27,6 +27,7 @@ #include #include #include "syscall.h" +#include "memorymanagement.h" #include "log.h" // DEBUG @@ -82,9 +83,23 @@ namespace Sortix } } - void Init(byte* theinitrd, size_t size) + void Init(addr_t phys, size_t size) { - initrd = theinitrd; + // First up, map the initrd onto the kernel's address space. + addr_t virt = Memory::GetInitRD(); + size_t amount = 0; + while ( amount < size ) + { + if ( !Memory::MapKernel(phys + amount, virt + amount) ) + { + Panic("Unable to map the init ramdisk into virtual memory"); + } + amount += 0x1000UL; + } + + Memory::Flush(); + + initrd = (byte*) virt; initrdsize = size; if ( size < sizeof(Header) ) { PanicF("initrd.cpp: initrd is too small"); } Header* header = (Header*) initrd; diff --git a/sortix/initrd.h b/sortix/initrd.h index 771d87a5..a1ee26f1 100644 --- a/sortix/initrd.h +++ b/sortix/initrd.h @@ -55,7 +55,7 @@ namespace Sortix }; #ifdef SORTIX_KERNEL - void Init(byte* initrd, size_t size); + void Init(addr_t phys, size_t size); byte* Open(const char* filepath, size_t* size); const char* GetFilename(size_t index); size_t GetNumFiles(); diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index 0ef97d24..ecee8f6f 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -184,7 +184,7 @@ namespace Sortix if ( BootInfo == NULL ) { Panic("kernel.cpp: The bootinfo structure was NULL. Are your bootloader multiboot compliant?"); } - uint8_t* initrd = NULL; + addr_t initrd = NULL; size_t initrdsize = 0; #ifndef JSSORTIX @@ -192,18 +192,20 @@ namespace Sortix for ( uint32_t I = 0; I < BootInfo->mods_count; I++ ) { initrdsize = modules[2*I+1] - modules[2*I+0]; - initrd = (uint8_t*) modules[2*I+0]; + initrd = (addr_t) modules[2*I+0]; break; } - if ( initrd == NULL ) { PanicF("No init ramdisk provided"); } + if ( !initrd ) { PanicF("No init ramdisk provided"); } #else // TODO: UGLY HACK because JSVM doesn't support multiboot yet! - initrd = (uint8_t*) 0x180000UL; + initrd = (addr_t) 0x180000UL; initrdsize = 0x280000; // 2 MiB 512 KiB #endif + Memory::RegisterInitRDSize(initrdsize); + #ifndef JSSORTIX // Search for PCI devices and load their drivers. PCI::Init(); diff --git a/sortix/memorymanagement.h b/sortix/memorymanagement.h index 86d0371c..0c185955 100644 --- a/sortix/memorymanagement.h +++ b/sortix/memorymanagement.h @@ -59,14 +59,13 @@ namespace Sortix addr_t UnmapKernel(addr_t mapto); addr_t UnmapUser(addr_t mapto); void Statistics(size_t* amountused, size_t* totalmem); - -#if defined(PLATFORM_X86) - const addr_t HEAPLOWER = 0x80000000UL; - const addr_t HEAPUPPER = 0xFF400000UL; -#elif defined(PLATFORM_X64) - const addr_t HEAPLOWER = 0xFFFF800000000000UL; - const addr_t HEAPUPPER = 0xFFFFFE8000000000UL; -#endif + addr_t GetKernelStack(); + size_t GetKernelStackSize(); + addr_t GetInitRD(); + size_t GetInitRDSize(); + void RegisterInitRDSize(size_t size); + addr_t GetHeapLower(); + addr_t GetHeapUpper(); } } diff --git a/sortix/scheduler.cpp b/sortix/scheduler.cpp index 14636ce6..089c6cb7 100644 --- a/sortix/scheduler.cpp +++ b/sortix/scheduler.cpp @@ -31,6 +31,7 @@ #include "memorymanagement.h" #include "syscall.h" #include "sound.h" // HACK FOR SIGINT +#include "descriptor_tables.h" namespace Sortix { @@ -39,7 +40,6 @@ namespace Sortix // Internal forward-declarations. namespace Scheduler { - void InitCPU(); Thread* PopNextThread(); void WakeSleeping(); void LogBeginContextSwitch(Thread* current, const CPU::InterruptRegisters* state); @@ -76,7 +76,16 @@ namespace Sortix Syscall::Register(SYSCALL_SLEEP, (void*) SysSleep); Syscall::Register(SYSCALL_USLEEP, (void*) SysUSleep); - InitCPU(); + addr_t stackstart = Memory::GetKernelStack(); + size_t stacksize = Memory::GetKernelStackSize(); + addr_t stackend = stackstart - stacksize; + if ( !Memory::MapRangeKernel(stackend, stacksize) ) + { + PanicF("could not create kernel stack (%zx to %zx)", + stackend, stackstart); + } + + GDT::SetKernelStack((size_t*) stackstart); } // The no operating thread is a thread stuck in an infinite loop that diff --git a/sortix/x64/memorymanagement.cpp b/sortix/x64/memorymanagement.cpp index bacd2050..74daa302 100644 --- a/sortix/x64/memorymanagement.cpp +++ b/sortix/x64/memorymanagement.cpp @@ -143,5 +143,47 @@ namespace Sortix PML* const BOOTPML4 = (PML* const) 0x01000UL; SwitchAddressSpace((addr_t) BOOTPML4); } + + const size_t KERNEL_STACK_SIZE = 256UL * 1024UL; + const addr_t KERNEL_STACK_END = 0xFFFF800000001000UL; + const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE; + addr_t INITRD = KERNEL_STACK_START; + size_t initrdsize = 0; + const addr_t HEAPUPPER = 0xFFFFFE8000000000UL; + + addr_t GetInitRD() + { + return INITRD; + } + + size_t GetInitRDSize() + { + return initrdsize; + } + + void RegisterInitRDSize(size_t size) + { + initrdsize = size; + } + + addr_t GetHeapLower() + { + return Page::AlignUp(INITRD + initrdsize); + } + + addr_t GetHeapUpper() + { + return HEAPUPPER; + } + + addr_t GetKernelStack() + { + return KERNEL_STACK_START; + } + + size_t GetKernelStackSize() + { + return KERNEL_STACK_SIZE; + } } } diff --git a/sortix/x64/scheduler.cpp b/sortix/x64/scheduler.cpp index 49b08b89..25dedf89 100644 --- a/sortix/x64/scheduler.cpp +++ b/sortix/x64/scheduler.cpp @@ -31,22 +31,8 @@ namespace Sortix { namespace Scheduler { - const size_t KERNEL_STACK_SIZE = 256UL * 1024UL; - const addr_t KERNEL_STACK_END = 0xFFFF800000001000UL; - const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE; - void InitCPU() { - // TODO: Prevent the kernel heap and other stuff from accidentally - // also allocating this virtual memory region! - - if ( !Memory::MapRangeKernel(KERNEL_STACK_END, KERNEL_STACK_SIZE) ) - { - PanicF("could not create kernel stack (%zx to %zx)", - KERNEL_STACK_END, KERNEL_STACK_START); - } - - GDT::SetKernelStack((size_t*) KERNEL_STACK_START); } } } diff --git a/sortix/x86-family/memorymanagement.cpp b/sortix/x86-family/memorymanagement.cpp index 0a694bb0..a998678d 100644 --- a/sortix/x86-family/memorymanagement.cpp +++ b/sortix/x86-family/memorymanagement.cpp @@ -35,7 +35,7 @@ using namespace Maxsi; namespace Sortix { - const addr_t KERNELEND = 0x400000UL; + const addr_t KERNELEND = 0x200000UL; namespace Page { @@ -98,17 +98,52 @@ namespace Sortix // Count the amount of usable RAM (even if reserved for kernel). Page::totalmem += length; - // Detect if this memory is completely covered by the kernel. - if ( base + length <= KERNELEND ) { continue; } - - // Detect if this memory is partially covered by the kernel. - if ( base <= KERNELEND && KERNELEND <= base + length ) + // Give all the physical memory to the physical memory allocator + // but make sure not to give it things we already use. + addr_t regionstart = mmap->addr; + addr_t regionend = mmap->addr + mmap->len; + addr_t processed = regionstart; + while ( processed < regionend ) { - length = (base + length) - KERNELEND; - base = KERNELEND; - } + addr_t lowest = processed; + addr_t highest = regionend; - Page::InitPushRegion(base, length); + // Don't allocate the kernel. + if ( lowest < KERNELEND ) { processed = KERNELEND; continue; } + + // Don't give any of our modules to the physical page + // allocator, we'll need them. + bool continuing = false; + uint32_t* modules = (uint32_t*) bootinfo->mods_addr; + for ( uint32_t i = 0; i < bootinfo->mods_count; i++ ) + { + size_t modsize = (size_t) (modules[2*i+1] - modules[2*i+0]); + addr_t modstart = (addr_t) modules[2*i+0]; + addr_t modend = modstart + modsize; + if ( modstart <= processed && processed < modend ) + { + processed = modend; + continuing = true; + break; + } + if ( lowest <= modstart && modstart < highest ) + { + highest = modstart; + } + } + + if ( continuing ) { continue; } + + if ( highest <= lowest ) { break; } + + // Now that we have a continious area not used by anything, + // let's forward it to the physical page allocator. + lowest = Page::AlignUp(lowest); + highest = Page::AlignUp(highest); + size_t size = highest - lowest; + Page::InitPushRegion(lowest, size); + processed = highest; + } } // If the physical allocator couldn't handle the vast amount of diff --git a/sortix/x86/memorymanagement.cpp b/sortix/x86/memorymanagement.cpp index 37fdddf9..6ec94507 100644 --- a/sortix/x86/memorymanagement.cpp +++ b/sortix/x86/memorymanagement.cpp @@ -153,5 +153,47 @@ namespace Sortix PML* const BOOTPML2 = (PML* const) 0x01000UL; SwitchAddressSpace((addr_t) BOOTPML2); } + + const size_t KERNEL_STACK_SIZE = 256UL * 1024UL; + const addr_t KERNEL_STACK_END = 0x80001000UL; + const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE; + addr_t INITRD = KERNEL_STACK_START; + size_t initrdsize = 0; + const addr_t HEAPUPPER = 0xFF400000UL; + + addr_t GetInitRD() + { + return INITRD; + } + + size_t GetInitRDSize() + { + return initrdsize; + } + + void RegisterInitRDSize(size_t size) + { + initrdsize = size; + } + + addr_t GetHeapLower() + { + return Page::AlignUp(INITRD + initrdsize); + } + + addr_t GetHeapUpper() + { + return HEAPUPPER; + } + + addr_t GetKernelStack() + { + return KERNEL_STACK_START; + } + + size_t GetKernelStackSize() + { + return KERNEL_STACK_SIZE; + } } } diff --git a/sortix/x86/scheduler.cpp b/sortix/x86/scheduler.cpp index ab4c4c9f..1525e47a 100644 --- a/sortix/x86/scheduler.cpp +++ b/sortix/x86/scheduler.cpp @@ -31,22 +31,5 @@ namespace Sortix { namespace Scheduler { - const size_t KERNEL_STACK_SIZE = 256UL * 1024UL; - const addr_t KERNEL_STACK_END = 0x80001000UL; - const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE; - - void InitCPU() - { - // TODO: Prevent the kernel heap and other stuff from accidentally - // also allocating this virtual memory region! - - if ( !Memory::MapRangeKernel(KERNEL_STACK_END, KERNEL_STACK_SIZE) ) - { - PanicF("could not create kernel stack (%zx to %zx)", - KERNEL_STACK_END, KERNEL_STACK_START); - } - - GDT::SetKernelStack((size_t*) KERNEL_STACK_START); - } } }