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 #ifdef SORTIX_KERNEL
addr_t GetHeapStart() addr_t GetHeapStart()
{ {
return Sortix::Memory::HEAPUPPER; return Sortix::Memory::GetHeapUpper();
} }
size_t GetHeapMaxSize() 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) void FreeMemory(addr_t where, size_t bytes)

View File

@ -27,6 +27,7 @@
#include <libmaxsi/memory.h> #include <libmaxsi/memory.h>
#include <libmaxsi/string.h> #include <libmaxsi/string.h>
#include "syscall.h" #include "syscall.h"
#include "memorymanagement.h"
#include "log.h" // DEBUG #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; initrdsize = size;
if ( size < sizeof(Header) ) { PanicF("initrd.cpp: initrd is too small"); } if ( size < sizeof(Header) ) { PanicF("initrd.cpp: initrd is too small"); }
Header* header = (Header*) initrd; Header* header = (Header*) initrd;

View File

@ -55,7 +55,7 @@ namespace Sortix
}; };
#ifdef SORTIX_KERNEL #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); byte* Open(const char* filepath, size_t* size);
const char* GetFilename(size_t index); const char* GetFilename(size_t index);
size_t GetNumFiles(); 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?"); } 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; size_t initrdsize = 0;
#ifndef JSSORTIX #ifndef JSSORTIX
@ -192,18 +192,20 @@ namespace Sortix
for ( uint32_t I = 0; I < BootInfo->mods_count; I++ ) for ( uint32_t I = 0; I < BootInfo->mods_count; I++ )
{ {
initrdsize = modules[2*I+1] - modules[2*I+0]; initrdsize = modules[2*I+1] - modules[2*I+0];
initrd = (uint8_t*) modules[2*I+0]; initrd = (addr_t) modules[2*I+0];
break; break;
} }
if ( initrd == NULL ) { PanicF("No init ramdisk provided"); } if ( !initrd ) { PanicF("No init ramdisk provided"); }
#else #else
// TODO: UGLY HACK because JSVM doesn't support multiboot yet! // TODO: UGLY HACK because JSVM doesn't support multiboot yet!
initrd = (uint8_t*) 0x180000UL; initrd = (addr_t) 0x180000UL;
initrdsize = 0x280000; // 2 MiB 512 KiB initrdsize = 0x280000; // 2 MiB 512 KiB
#endif #endif
Memory::RegisterInitRDSize(initrdsize);
#ifndef JSSORTIX #ifndef JSSORTIX
// Search for PCI devices and load their drivers. // Search for PCI devices and load their drivers.
PCI::Init(); PCI::Init();

View File

@ -59,14 +59,13 @@ namespace Sortix
addr_t UnmapKernel(addr_t mapto); addr_t UnmapKernel(addr_t mapto);
addr_t UnmapUser(addr_t mapto); addr_t UnmapUser(addr_t mapto);
void Statistics(size_t* amountused, size_t* totalmem); void Statistics(size_t* amountused, size_t* totalmem);
addr_t GetKernelStack();
#if defined(PLATFORM_X86) size_t GetKernelStackSize();
const addr_t HEAPLOWER = 0x80000000UL; addr_t GetInitRD();
const addr_t HEAPUPPER = 0xFF400000UL; size_t GetInitRDSize();
#elif defined(PLATFORM_X64) void RegisterInitRDSize(size_t size);
const addr_t HEAPLOWER = 0xFFFF800000000000UL; addr_t GetHeapLower();
const addr_t HEAPUPPER = 0xFFFFFE8000000000UL; addr_t GetHeapUpper();
#endif
} }
} }

View File

@ -31,6 +31,7 @@
#include "memorymanagement.h" #include "memorymanagement.h"
#include "syscall.h" #include "syscall.h"
#include "sound.h" // HACK FOR SIGINT #include "sound.h" // HACK FOR SIGINT
#include "descriptor_tables.h"
namespace Sortix namespace Sortix
{ {
@ -39,7 +40,6 @@ namespace Sortix
// Internal forward-declarations. // Internal forward-declarations.
namespace Scheduler namespace Scheduler
{ {
void InitCPU();
Thread* PopNextThread(); Thread* PopNextThread();
void WakeSleeping(); void WakeSleeping();
void LogBeginContextSwitch(Thread* current, const CPU::InterruptRegisters* state); void LogBeginContextSwitch(Thread* current, const CPU::InterruptRegisters* state);
@ -76,7 +76,16 @@ namespace Sortix
Syscall::Register(SYSCALL_SLEEP, (void*) SysSleep); Syscall::Register(SYSCALL_SLEEP, (void*) SysSleep);
Syscall::Register(SYSCALL_USLEEP, (void*) SysUSleep); 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 // 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; PML* const BOOTPML4 = (PML* const) 0x01000UL;
SwitchAddressSpace((addr_t) BOOTPML4); 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 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() 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 namespace Sortix
{ {
const addr_t KERNELEND = 0x400000UL; const addr_t KERNELEND = 0x200000UL;
namespace Page namespace Page
{ {
@ -98,17 +98,52 @@ namespace Sortix
// Count the amount of usable RAM (even if reserved for kernel). // Count the amount of usable RAM (even if reserved for kernel).
Page::totalmem += length; Page::totalmem += length;
// Detect if this memory is completely covered by the kernel. // Give all the physical memory to the physical memory allocator
if ( base + length <= KERNELEND ) { continue; } // but make sure not to give it things we already use.
addr_t regionstart = mmap->addr;
// Detect if this memory is partially covered by the kernel. addr_t regionend = mmap->addr + mmap->len;
if ( base <= KERNELEND && KERNELEND <= base + length ) addr_t processed = regionstart;
while ( processed < regionend )
{ {
length = (base + length) - KERNELEND; addr_t lowest = processed;
base = KERNELEND; 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 // 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; PML* const BOOTPML2 = (PML* const) 0x01000UL;
SwitchAddressSpace((addr_t) BOOTPML2); 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 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);
}
} }
} }