Detect physical memory before initializing the kernel log.
This commit is contained in:
parent
218875eb79
commit
77467b7768
|
@ -52,8 +52,6 @@ extern void* emergency_device_pointer;
|
||||||
|
|
||||||
inline void Flush()
|
inline void Flush()
|
||||||
{
|
{
|
||||||
if ( !device_callback )
|
|
||||||
return;
|
|
||||||
device_callback(device_pointer, NULL, 0);
|
device_callback(device_pointer, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,15 +77,11 @@ inline bool Sync()
|
||||||
|
|
||||||
inline size_t Print(const char* str)
|
inline size_t Print(const char* str)
|
||||||
{
|
{
|
||||||
if ( !device_callback )
|
|
||||||
return 0;
|
|
||||||
return device_callback(device_pointer, str, strlen(str));
|
return device_callback(device_pointer, str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t PrintData(const void* ptr, size_t size)
|
inline size_t PrintData(const void* ptr, size_t size)
|
||||||
{
|
{
|
||||||
if ( !device_callback )
|
|
||||||
return 0;
|
|
||||||
return device_callback(device_pointer, (const char*) ptr, size);
|
return device_callback(device_pointer, (const char*) ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,9 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
|
||||||
|
|
||||||
// TODO: Call global constructors using the _init function.
|
// 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.
|
// Setup a text buffer handle for use by the text terminal.
|
||||||
uint16_t* const VGAFB = (uint16_t*) 0xB8000;
|
uint16_t* const VGAFB = (uint16_t*) 0xB8000;
|
||||||
const size_t VGA_WIDTH = 80;
|
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.");
|
"Use a 32-bit OS 3) Use another version of qemu.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Detect available physical memory.
|
|
||||||
Memory::Init(bootinfo);
|
|
||||||
|
|
||||||
initrd = 0;
|
initrd = 0;
|
||||||
initrdsize = 0;
|
initrdsize = 0;
|
||||||
|
|
||||||
|
|
|
@ -459,16 +459,3 @@ void* sys_mmap_wrapper(struct mmap_request* user_request)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
||||||
namespace Sortix {
|
|
||||||
namespace Memory {
|
|
||||||
|
|
||||||
void InitCPU(multiboot_info_t* bootinfo);
|
|
||||||
|
|
||||||
void Init(multiboot_info_t* bootinfo)
|
|
||||||
{
|
|
||||||
InitCPU(bootinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Memory
|
|
||||||
} // namespace Sortix
|
|
||||||
|
|
|
@ -59,6 +59,10 @@ void PanicInit()
|
||||||
// and the data protected by them may be inconsistent.
|
// and the data protected by them may be inconsistent.
|
||||||
Interrupt::Disable();
|
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.
|
// Detect whether a panic happened during the log recovery.
|
||||||
if ( logrecovering )
|
if ( logrecovering )
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,26 +63,14 @@ kthread_mutex_t pagelock = KTHREAD_MUTEX_INITIALIZER;
|
||||||
namespace Sortix {
|
namespace Sortix {
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
|
|
||||||
void AllocateKernelPMLs();
|
|
||||||
int SysMemStat(size_t* memused, size_t* memtotal);
|
|
||||||
addr_t PAT2PMLFlags[PAT_NUM];
|
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);
|
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) )
|
if ( !(bootinfo->flags & MULTIBOOT_INFO_MEM_MAP) )
|
||||||
Panic("memorymanagement.cpp: The memory map flag was't set in "
|
Panic("The memory map flag was't set in the multiboot structure.");
|
||||||
"the multiboot structure. Are your bootloader multiboot "
|
|
||||||
"specification compliant?");
|
|
||||||
|
|
||||||
// If supported, setup the Page Attribute Table feature that allows
|
// If supported, setup the Page Attribute Table feature that allows
|
||||||
// us to control the memory type (caching) of memory more precisely.
|
// 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
|
// Prepare the non-forkable kernel PMLs such that forking the kernel address
|
||||||
// physical pages, it may decide to drop some. This shouldn't happen
|
// space will always keep the kernel mapped.
|
||||||
// until the pebibyte era of RAM.
|
for ( size_t i = ENTRIES / 2; i < ENTRIES; i++ )
|
||||||
if ( 0 < Page::pagesnotonstack )
|
{
|
||||||
Log::PrintF("%zu bytes of RAM aren't used due to technical "
|
PML* const pml = PMLS[TOPPMLLEVEL];
|
||||||
"restrictions.\n", (size_t) (Page::pagesnotonstack * 0x1000UL));
|
if ( pml->entry[i] & PML_PRESENT )
|
||||||
|
continue;
|
||||||
|
|
||||||
// Finish allocating the top level PMLs for the kernels use.
|
addr_t page = Page::Get(PAGE_USAGE_PAGING_OVERHEAD);
|
||||||
AllocateKernelPMLs();
|
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)
|
void Statistics(size_t* amountused, size_t* totalmem)
|
||||||
|
@ -207,35 +205,6 @@ void Statistics(size_t* amountused, size_t* totalmem)
|
||||||
*totalmem = Page::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 Memory
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue