From 77467b77683fcee7ce8a32aeb86defe31bb54165 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Thu, 19 Mar 2015 00:25:01 +0100 Subject: [PATCH] Detect physical memory before initializing the kernel log. --- kernel/include/sortix/kernel/log.h | 6 --- kernel/kernel.cpp | 6 +-- kernel/memorymanagement.cpp | 13 ----- kernel/panic.cpp | 4 ++ kernel/x86-family/memorymanagement.cpp | 71 ++++++++------------------ 5 files changed, 27 insertions(+), 73 deletions(-) diff --git a/kernel/include/sortix/kernel/log.h b/kernel/include/sortix/kernel/log.h index ab07400a..bf6b6889 100644 --- a/kernel/include/sortix/kernel/log.h +++ b/kernel/include/sortix/kernel/log.h @@ -52,8 +52,6 @@ extern void* emergency_device_pointer; inline void Flush() { - if ( !device_callback ) - return; device_callback(device_pointer, NULL, 0); } @@ -79,15 +77,11 @@ inline bool Sync() inline size_t Print(const char* str) { - if ( !device_callback ) - return 0; return device_callback(device_pointer, str, strlen(str)); } inline size_t PrintData(const void* ptr, size_t size) { - if ( !device_callback ) - return 0; return device_callback(device_pointer, (const char*) ptr, size); } diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 94ac0310..774a403c 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -189,6 +189,9 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo) // TODO: Call global constructors using the _init function. + // Detect available physical memory. + Memory::Init(bootinfo); + // Setup a text buffer handle for use by the text terminal. uint16_t* const VGAFB = (uint16_t*) 0xB8000; const size_t VGA_WIDTH = 80; @@ -253,9 +256,6 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo) "Use a 32-bit OS 3) Use another version of qemu."); #endif - // Detect available physical memory. - Memory::Init(bootinfo); - initrd = 0; initrdsize = 0; diff --git a/kernel/memorymanagement.cpp b/kernel/memorymanagement.cpp index d764ecfa..1f933afd 100644 --- a/kernel/memorymanagement.cpp +++ b/kernel/memorymanagement.cpp @@ -459,16 +459,3 @@ void* sys_mmap_wrapper(struct mmap_request* user_request) } } // namespace Sortix - -namespace Sortix { -namespace Memory { - -void InitCPU(multiboot_info_t* bootinfo); - -void Init(multiboot_info_t* bootinfo) -{ - InitCPU(bootinfo); -} - -} // namespace Memory -} // namespace Sortix diff --git a/kernel/panic.cpp b/kernel/panic.cpp index d1721030..2459b7a0 100644 --- a/kernel/panic.cpp +++ b/kernel/panic.cpp @@ -59,6 +59,10 @@ void PanicInit() // and the data protected by them may be inconsistent. Interrupt::Disable(); + // Detect if we are really early and we don't even have a log yet. + if ( !Log::device_callback ) + HaltKernel(); + // Detect whether a panic happened during the log recovery. if ( logrecovering ) { diff --git a/kernel/x86-family/memorymanagement.cpp b/kernel/x86-family/memorymanagement.cpp index 9398483b..5c953d72 100644 --- a/kernel/x86-family/memorymanagement.cpp +++ b/kernel/x86-family/memorymanagement.cpp @@ -63,26 +63,14 @@ kthread_mutex_t pagelock = KTHREAD_MUTEX_INITIALIZER; namespace Sortix { namespace Memory { -void AllocateKernelPMLs(); -int SysMemStat(size_t* memused, size_t* memtotal); addr_t PAT2PMLFlags[PAT_NUM]; -void InitCPU(multiboot_info_t* bootinfo) +void Init(multiboot_info_t* bootinfo) { - const size_t MAXKERNELEND = 0x400000UL; /* 4 MiB */ addr_t kernelend = Page::AlignUp((addr_t) &end); - if ( MAXKERNELEND < kernelend ) - { - Log::PrintF("Warning: The kernel is too big! It ends at 0x%zx, " - "but the highest ending address supported is 0x%zx. " - "The system may not boot correctly.\n", kernelend, - MAXKERNELEND); - } if ( !(bootinfo->flags & MULTIBOOT_INFO_MEM_MAP) ) - Panic("memorymanagement.cpp: The memory map flag was't set in " - "the multiboot structure. Are your bootloader multiboot " - "specification compliant?"); + Panic("The memory map flag was't set in the multiboot structure."); // If supported, setup the Page Attribute Table feature that allows // us to control the memory type (caching) of memory more precisely. @@ -186,15 +174,25 @@ void InitCPU(multiboot_info_t* bootinfo) } } - // If the physical allocator couldn't handle the vast amount of - // physical pages, it may decide to drop some. This shouldn't happen - // until the pebibyte era of RAM. - if ( 0 < Page::pagesnotonstack ) - Log::PrintF("%zu bytes of RAM aren't used due to technical " - "restrictions.\n", (size_t) (Page::pagesnotonstack * 0x1000UL)); + // Prepare the non-forkable kernel PMLs such that forking the kernel address + // space will always keep the kernel mapped. + for ( size_t i = ENTRIES / 2; i < ENTRIES; i++ ) + { + PML* const pml = PMLS[TOPPMLLEVEL]; + if ( pml->entry[i] & PML_PRESENT ) + continue; - // Finish allocating the top level PMLs for the kernels use. - AllocateKernelPMLs(); + addr_t page = Page::Get(PAGE_USAGE_PAGING_OVERHEAD); + if ( !page ) + Panic("Out of memory allocating boot PMLs."); + + pml->entry[i] = page | PML_WRITABLE | PML_PRESENT; + + // Invalidate the new PML and reset it to zeroes. + addr_t pmladdr = (addr_t) (PMLS[TOPPMLLEVEL-1] + i); + InvalidatePage(pmladdr); + memset((void*) pmladdr, 0, sizeof(PML)); + } } void Statistics(size_t* amountused, size_t* totalmem) @@ -207,35 +205,6 @@ void Statistics(size_t* amountused, size_t* totalmem) *totalmem = Page::totalmem; } -// Prepare the non-forkable kernel PMLs such that forking the kernel -// address space will always keep the kernel mapped. -void AllocateKernelPMLs() -{ - const addr_t flags = PML_PRESENT | PML_WRITABLE; - - PML* const pml = PMLS[TOPPMLLEVEL]; - - size_t start = ENTRIES / 2; - size_t end = ENTRIES; - - for ( size_t i = start; i < end; i++ ) - { - if ( pml->entry[i] & PML_PRESENT ) - continue; - - addr_t page = Page::Get(PAGE_USAGE_PAGING_OVERHEAD); - if ( !page ) - Panic("out of memory allocating boot PMLs"); - - pml->entry[i] = page | flags; - - // Invalidate the new PML and reset it to zeroes. - addr_t pmladdr = (addr_t) (PMLS[TOPPMLLEVEL-1] + i); - InvalidatePage(pmladdr); - memset((void*) pmladdr, 0, sizeof(PML)); - } -} - } // namespace Memory } // namespace Sortix