The initial ramdisk is now mapped onto a special location.

This fixes issues where it did not fit into the first few MiB,
or that GRUB loaded it someplace weird.

The kernel heap is now also protected against growing into the
ramdisk and the kernel stack.
This commit is contained in:
Jonas 'Sortie' Termansen 2011-12-22 14:13:18 +01:00
parent a623b1b07e
commit 0515111314
11 changed files with 173 additions and 60 deletions

View File

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

View File

@ -27,6 +27,7 @@
#include <libmaxsi/memory.h>
#include <libmaxsi/string.h>
#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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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