Detect physical memory before initializing the kernel log.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-03-19 00:25:01 +01:00
parent 218875eb79
commit 77467b7768
5 changed files with 27 additions and 73 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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 )
{

View File

@ -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