Refactor kernel address space allocation.
This commit is contained in:
parent
5ce53a2a30
commit
54da838c79
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@
|
||||||
#include <sortix/kernel/log.h> // DEBUG
|
#include <sortix/kernel/log.h> // DEBUG
|
||||||
#include <sortix/kernel/memorymanagement.h>
|
#include <sortix/kernel/memorymanagement.h>
|
||||||
#include <sortix/kernel/panic.h>
|
#include <sortix/kernel/panic.h>
|
||||||
|
#include <sortix/kernel/addralloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _ADDR_T_DECLARED
|
#ifndef _ADDR_T_DECLARED
|
||||||
|
@ -76,12 +77,7 @@ extern addr_t wilderness;
|
||||||
#ifdef SORTIX_KERNEL
|
#ifdef SORTIX_KERNEL
|
||||||
static addr_t GetHeapStart()
|
static addr_t GetHeapStart()
|
||||||
{
|
{
|
||||||
return Sortix::Memory::GetHeapUpper();
|
return Sortix::GetHeapUpper();
|
||||||
}
|
|
||||||
|
|
||||||
static size_t GetHeapMaxSize()
|
|
||||||
{
|
|
||||||
return Sortix::Memory::GetHeapUpper() - Sortix::Memory::GetHeapLower();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FreeMemory(addr_t where, size_t bytes)
|
static void FreeMemory(addr_t where, size_t bytes)
|
||||||
|
@ -129,13 +125,24 @@ static bool AllocateMemory(addr_t where, size_t bytes)
|
||||||
|
|
||||||
static bool ExtendHeap(size_t bytesneeded)
|
static bool ExtendHeap(size_t bytesneeded)
|
||||||
{
|
{
|
||||||
|
size_t got_bytes = Sortix::ExpandHeap(bytesneeded);
|
||||||
|
if ( !got_bytes )
|
||||||
|
return false;
|
||||||
|
assert(bytesneeded <= got_bytes);
|
||||||
|
|
||||||
#ifdef HEAP_GROWS_DOWNWARDS
|
#ifdef HEAP_GROWS_DOWNWARDS
|
||||||
addr_t newwilderness = wilderness - bytesneeded;
|
addr_t newwilderness = wilderness - got_bytes;
|
||||||
#else
|
#else
|
||||||
addr_t newwilderness = wilderness + bytesneeded;
|
addr_t newwilderness = wilderness + got_bytes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return AllocateMemory(newwilderness, bytesneeded);
|
if ( !AllocateMemory(newwilderness, got_bytes) )
|
||||||
|
{
|
||||||
|
Sortix::ShrinkHeap(got_bytes);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static addr_t GetHeapStart()
|
static addr_t GetHeapStart()
|
||||||
|
@ -150,12 +157,6 @@ static addr_t GetHeapStart()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t GetHeapMaxSize()
|
|
||||||
{
|
|
||||||
// TODO: A bit of a hack!
|
|
||||||
return SIZE_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ExtendHeap(size_t bytesneeded)
|
static bool ExtendHeap(size_t bytesneeded)
|
||||||
{
|
{
|
||||||
void* newheapend = sbrk(bytesneeded);
|
void* newheapend = sbrk(bytesneeded);
|
||||||
|
@ -422,7 +423,7 @@ static bool ValidateHeap()
|
||||||
extern "C" void _init_heap()
|
extern "C" void _init_heap()
|
||||||
{
|
{
|
||||||
heapstart = GetHeapStart();
|
heapstart = GetHeapStart();
|
||||||
heapmaxsize = GetHeapMaxSize();
|
heapmaxsize = SIZE_MAX;
|
||||||
heapsize = 0;
|
heapsize = 0;
|
||||||
wilderness = heapstart;
|
wilderness = heapstart;
|
||||||
wildernesssize = 0;
|
wildernesssize = 0;
|
||||||
|
@ -450,10 +451,7 @@ static bool ExpandWilderness(size_t bytesneeded)
|
||||||
|
|
||||||
// TODO: Overflow MAY happen here!
|
// TODO: Overflow MAY happen here!
|
||||||
if ( heapmaxsize <= heapsize + wildernesssize + bytesneeded )
|
if ( heapmaxsize <= heapsize + wildernesssize + bytesneeded )
|
||||||
{
|
return errno = ENOMEM, true;
|
||||||
errno = ENOMEM;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HEAP_GROWS_DOWNWARDS
|
#ifdef HEAP_GROWS_DOWNWARDS
|
||||||
addr_t newwilderness = wilderness - bytesneeded;
|
addr_t newwilderness = wilderness - bytesneeded;
|
||||||
|
@ -462,7 +460,8 @@ static bool ExpandWilderness(size_t bytesneeded)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Attempt to map pages so our wilderness grows.
|
// Attempt to map pages so our wilderness grows.
|
||||||
if ( !ExtendHeap(bytesneeded) ) { return false; }
|
if ( !ExtendHeap(bytesneeded) )
|
||||||
|
return false;
|
||||||
|
|
||||||
wildernesssize += bytesneeded;
|
wildernesssize += bytesneeded;
|
||||||
wilderness = newwilderness;
|
wilderness = newwilderness;
|
||||||
|
|
|
@ -70,6 +70,7 @@ LIBS=\
|
||||||
|
|
||||||
OBJS=\
|
OBJS=\
|
||||||
$(CPUOBJS) \
|
$(CPUOBJS) \
|
||||||
|
addralloc.o \
|
||||||
ata.o \
|
ata.o \
|
||||||
bga.o \
|
bga.o \
|
||||||
calltrace.o \
|
calltrace.o \
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix is free software: you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
addralloc.cpp
|
||||||
|
Class to keep track of mount points.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <sortix/kernel/platform.h>
|
||||||
|
#include <sortix/kernel/addralloc.h>
|
||||||
|
#include <sortix/kernel/kthread.h>
|
||||||
|
#include <sortix/kernel/memorymanagement.h>
|
||||||
|
|
||||||
|
namespace Sortix {
|
||||||
|
|
||||||
|
size_t aux_allocated = 0;
|
||||||
|
size_t heap_allocated = 0;
|
||||||
|
kthread_mutex_t alloc_lock = KTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
// TODO: Kernel address space is allocated simply by increasing the pointer,
|
||||||
|
// with no support for freeing it. This is not that big a problem at this point,
|
||||||
|
// since address space is consumed at boot and then used forever. When it
|
||||||
|
// becomes normal for devices to come and go, just recode these functions and
|
||||||
|
// everyone should do the right thing.
|
||||||
|
|
||||||
|
bool AllocateKernelAddress(addralloc_t* ret, size_t size)
|
||||||
|
{
|
||||||
|
size = Page::AlignUp(size);
|
||||||
|
ScopedLock lock(&alloc_lock);
|
||||||
|
addr_t kmem_from;
|
||||||
|
size_t kmem_size;
|
||||||
|
Memory::GetKernelVirtualArea(&kmem_from, &kmem_size);
|
||||||
|
addr_t aux_reached = kmem_from + aux_allocated;
|
||||||
|
size_t heap_reached = kmem_from + kmem_size - heap_allocated;
|
||||||
|
size_t unused_left = heap_reached - aux_reached;
|
||||||
|
if ( unused_left < size )
|
||||||
|
return errno = ENOMEM, false;
|
||||||
|
aux_allocated += size;
|
||||||
|
ret->from = aux_reached;
|
||||||
|
ret->size = size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeKernelAddress(addralloc_t* alloc)
|
||||||
|
{
|
||||||
|
if ( !alloc->from )
|
||||||
|
return;
|
||||||
|
// Currently, nothing to do here.
|
||||||
|
alloc->from = 0;
|
||||||
|
alloc->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ExpandHeap(size_t increase)
|
||||||
|
{
|
||||||
|
increase = Page::AlignUp(increase);
|
||||||
|
ScopedLock lock(&alloc_lock);
|
||||||
|
addr_t kmem_from;
|
||||||
|
size_t kmem_size;
|
||||||
|
Memory::GetKernelVirtualArea(&kmem_from, &kmem_size);
|
||||||
|
addr_t aux_reached = kmem_from + aux_allocated;
|
||||||
|
size_t heap_reached = kmem_from + kmem_size - heap_allocated;
|
||||||
|
size_t unused_left = heap_reached - aux_reached;
|
||||||
|
if ( unused_left < increase )
|
||||||
|
return errno = ENOMEM, 0;
|
||||||
|
heap_allocated += increase;
|
||||||
|
return increase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShrinkHeap(size_t decrease)
|
||||||
|
{
|
||||||
|
assert(decrease == Page::AlignUp(decrease));
|
||||||
|
ScopedLock lock(&alloc_lock);
|
||||||
|
assert(decrease <= heap_allocated);
|
||||||
|
heap_allocated -= decrease;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need for locks in these three functions, since only the heap calls these
|
||||||
|
// and it already uses an internal lock, and heap_allocated will not change
|
||||||
|
// unless the heap calls ExpandHeap.
|
||||||
|
|
||||||
|
addr_t GetHeapLower()
|
||||||
|
{
|
||||||
|
addr_t kmem_from;
|
||||||
|
size_t kmem_size;
|
||||||
|
Memory::GetKernelVirtualArea(&kmem_from, &kmem_size);
|
||||||
|
return kmem_from + kmem_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_t GetHeapUpper()
|
||||||
|
{
|
||||||
|
addr_t kmem_from;
|
||||||
|
size_t kmem_size;
|
||||||
|
Memory::GetKernelVirtualArea(&kmem_from, &kmem_size);
|
||||||
|
return kmem_from + kmem_size - heap_allocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetHeapSize()
|
||||||
|
{
|
||||||
|
return heap_allocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Sortix
|
113
sortix/bga.cpp
113
sortix/bga.cpp
|
@ -22,18 +22,23 @@
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <sortix/kernel/platform.h>
|
#include <sortix/kernel/platform.h>
|
||||||
|
#include <sortix/kernel/addralloc.h>
|
||||||
#include <sortix/kernel/refcount.h>
|
#include <sortix/kernel/refcount.h>
|
||||||
#include <sortix/kernel/textbuffer.h>
|
#include <sortix/kernel/textbuffer.h>
|
||||||
#include <sortix/kernel/video.h>
|
#include <sortix/kernel/video.h>
|
||||||
#include <sortix/kernel/memorymanagement.h>
|
#include <sortix/kernel/memorymanagement.h>
|
||||||
#include <sortix/kernel/pci.h>
|
#include <sortix/kernel/pci.h>
|
||||||
#include <sortix/kernel/string.h>
|
#include <sortix/kernel/string.h>
|
||||||
|
|
||||||
#include <sortix/mman.h>
|
#include <sortix/mman.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "x86-family/memorymanagement.h"
|
#include "x86-family/memorymanagement.h"
|
||||||
#include "lfbtextbuffer.h"
|
#include "lfbtextbuffer.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
@ -202,6 +207,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool MapVideoMemory(size_t size);
|
bool MapVideoMemory(size_t size);
|
||||||
|
bool MapVideoMemoryRange(addr_t mapat, size_t from, size_t to);
|
||||||
|
bool IncreaseVirtual(size_t new_size);
|
||||||
bool DetectModes() const;
|
bool DetectModes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -210,6 +217,7 @@ private:
|
||||||
char* curmode;
|
char* curmode;
|
||||||
size_t lfbmapped;
|
size_t lfbmapped;
|
||||||
size_t framesize;
|
size_t framesize;
|
||||||
|
addralloc_t addr_allocation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,11 +228,13 @@ BGADriver::BGADriver()
|
||||||
curmode = NULL;
|
curmode = NULL;
|
||||||
lfbmapped = 0;
|
lfbmapped = 0;
|
||||||
framesize = 0;
|
framesize = 0;
|
||||||
|
memset(&addr_allocation, 0, sizeof(addr_allocation));
|
||||||
}
|
}
|
||||||
|
|
||||||
BGADriver::~BGADriver()
|
BGADriver::~BGADriver()
|
||||||
{
|
{
|
||||||
MapVideoMemory(0);
|
MapVideoMemory(0);
|
||||||
|
FreeKernelAddress(&addr_allocation);
|
||||||
for ( size_t i = 0; i < nummodes; i++ )
|
for ( size_t i = 0; i < nummodes; i++ )
|
||||||
{
|
{
|
||||||
delete[] modes[i];
|
delete[] modes[i];
|
||||||
|
@ -233,45 +243,78 @@ BGADriver::~BGADriver()
|
||||||
delete[] curmode;
|
delete[] curmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BGADriver::MapVideoMemory(size_t size)
|
bool BGADriver::MapVideoMemoryRange(addr_t mapat, size_t from, size_t to)
|
||||||
{
|
{
|
||||||
size = Page::AlignUp(size);
|
|
||||||
addr_t phys = bgaframebuffer;
|
addr_t phys = bgaframebuffer;
|
||||||
addr_t mapat = Memory::GetVideoMemory();
|
|
||||||
|
|
||||||
if ( size == lfbmapped )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if ( size < lfbmapped )
|
|
||||||
{
|
|
||||||
for ( size_t i = size; i < size; i += Page::Size() )
|
|
||||||
Memory::Unmap(phys + i);
|
|
||||||
Memory::Flush();
|
|
||||||
lfbmapped = size;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t maxsize = Memory::GetMaxVideoMemorySize();
|
|
||||||
if ( maxsize < size )
|
|
||||||
{
|
|
||||||
Log::PrintF("Error: Insufficient virtual address space for BGA frame "
|
|
||||||
"of size 0x%zx bytes, only 0x%zx was available.\n", size,
|
|
||||||
maxsize);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const addr_t mtype = Memory::PAT_WC;
|
const addr_t mtype = Memory::PAT_WC;
|
||||||
for ( size_t i = lfbmapped; i < size; i += Page::Size() )
|
for ( size_t i = from; i < to; i += Page::Size() )
|
||||||
if ( !Memory::MapPAT(phys+i, mapat+i, PROT_KWRITE | PROT_KREAD, mtype) )
|
if ( !Memory::MapPAT(phys+i, mapat+i, PROT_KWRITE | PROT_KREAD, mtype) )
|
||||||
{
|
{
|
||||||
Log::PrintF("Error: Insufficient memory to map BGA framebuffer "
|
Log::PrintF("Error: Insufficient memory to map BGA framebuffer "
|
||||||
"onto kernel address space: needed 0x%zx bytes but "
|
"onto kernel address space: needed 0x%zx bytes but "
|
||||||
"only 0x%zx was available at this point.\n", size, i);
|
"only 0x%zx was available at this point.\n", to, i);
|
||||||
MapVideoMemory(lfbmapped); // Unmap what we added.
|
for ( size_t n = from; n < i; n += Page::Size() )
|
||||||
|
Memory::Unmap(mapat + n);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BGADriver::IncreaseVirtual(size_t new_size)
|
||||||
|
{
|
||||||
|
new_size = Page::AlignUp(new_size);
|
||||||
|
assert(addr_allocation.size < new_size);
|
||||||
|
|
||||||
|
addralloc_t new_addralloc;
|
||||||
|
if ( !AllocateKernelAddress(&new_addralloc, new_size) )
|
||||||
|
{
|
||||||
|
Log::PrintF("Error: Insufficient virtual address space for BGA "
|
||||||
|
"frame of size 0x%zx bytes, only 0x%zx was available.\n",
|
||||||
|
new_size, addr_allocation.size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_t old_mapat = addr_allocation.from;
|
||||||
|
addr_t new_mapat = new_addralloc.from;
|
||||||
|
|
||||||
|
if ( !MapVideoMemoryRange(new_mapat, 0, new_size) )
|
||||||
|
{
|
||||||
|
FreeKernelAddress(&addr_allocation);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < lfbmapped; i += Page::Size() )
|
||||||
|
Memory::Unmap(old_mapat + i);
|
||||||
|
|
||||||
|
FreeKernelAddress(&addr_allocation);
|
||||||
|
|
||||||
|
lfbmapped = new_size;
|
||||||
|
addr_allocation = new_addralloc;
|
||||||
|
|
||||||
Memory::Flush();
|
Memory::Flush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BGADriver::MapVideoMemory(size_t size)
|
||||||
|
{
|
||||||
|
size = Page::AlignUp(size);
|
||||||
|
|
||||||
|
if ( size == lfbmapped )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( addr_allocation.size < size )
|
||||||
|
return IncreaseVirtual(size);
|
||||||
|
|
||||||
|
addr_t mapat = addr_allocation.from;
|
||||||
|
for ( size_t i = size; i < lfbmapped; i+= Page::Size() )
|
||||||
|
Memory::Unmap(mapat + i);
|
||||||
|
|
||||||
lfbmapped = size;
|
lfbmapped = size;
|
||||||
|
Memory::Flush();
|
||||||
|
|
||||||
|
if ( !size )
|
||||||
|
FreeKernelAddress(&addr_allocation);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +425,7 @@ off_t BGADriver::FrameSize() const
|
||||||
|
|
||||||
ssize_t BGADriver::WriteAt(off_t off, const void* buf, size_t count)
|
ssize_t BGADriver::WriteAt(off_t off, const void* buf, size_t count)
|
||||||
{
|
{
|
||||||
uint8_t* frame = (uint8_t*) Memory::GetVideoMemory();
|
uint8_t* frame = (uint8_t*) addr_allocation.from;
|
||||||
if ( (off_t) framesize <= off )
|
if ( (off_t) framesize <= off )
|
||||||
return 0;
|
return 0;
|
||||||
if ( framesize < off + count )
|
if ( framesize < off + count )
|
||||||
|
@ -393,7 +436,7 @@ ssize_t BGADriver::WriteAt(off_t off, const void* buf, size_t count)
|
||||||
|
|
||||||
ssize_t BGADriver::ReadAt(off_t off, void* buf, size_t count)
|
ssize_t BGADriver::ReadAt(off_t off, void* buf, size_t count)
|
||||||
{
|
{
|
||||||
const uint8_t* frame = (const uint8_t*) Memory::GetVideoMemory();
|
const uint8_t* frame = (const uint8_t*) addr_allocation.from;
|
||||||
if ( (off_t) framesize <= off )
|
if ( (off_t) framesize <= off )
|
||||||
return 0;
|
return 0;
|
||||||
if ( framesize < off + count )
|
if ( framesize < off + count )
|
||||||
|
@ -442,7 +485,7 @@ bool BGADriver::DetectModes() const
|
||||||
|
|
||||||
TextBuffer* BGADriver::CreateTextBuffer()
|
TextBuffer* BGADriver::CreateTextBuffer()
|
||||||
{
|
{
|
||||||
uint8_t* lfb = (uint8_t*) Memory::GetVideoMemory();
|
uint8_t* lfb = (uint8_t*) addr_allocation.from;
|
||||||
uint32_t lfbformat = curbpp;
|
uint32_t lfbformat = curbpp;
|
||||||
size_t scansize = curxres * curbpp / 8UL;
|
size_t scansize = curxres * curbpp / 8UL;
|
||||||
return CreateLFBTextBuffer(lfb, lfbformat, curxres, curyres, scansize);
|
return CreateLFBTextBuffer(lfb, lfbformat, curxres, curyres, scansize);
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix is free software: you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
sortix/kernel/addralloc.h
|
||||||
|
Class to keep track of mount points.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef INCLUDE_SORTIX_KERNEL_ADDRALLOC_H
|
||||||
|
#define INCLUDE_SORTIX_KERNEL_ADDRALLOC_H
|
||||||
|
|
||||||
|
#include <sortix/kernel/decl.h>
|
||||||
|
|
||||||
|
namespace Sortix {
|
||||||
|
|
||||||
|
struct addralloc_t
|
||||||
|
{
|
||||||
|
addr_t from;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool AllocateKernelAddress(addralloc_t* ret, size_t size);
|
||||||
|
void FreeKernelAddress(addralloc_t* alloc);
|
||||||
|
size_t ExpandHeap(size_t increase);
|
||||||
|
void ShrinkHeap(size_t decrease);
|
||||||
|
addr_t GetHeapLower();
|
||||||
|
addr_t GetHeapUpper();
|
||||||
|
size_t GetHeapSize();
|
||||||
|
|
||||||
|
} // namespace Sortix
|
||||||
|
|
||||||
|
#endif
|
|
@ -82,13 +82,7 @@ namespace Sortix
|
||||||
void Statistics(size_t* amountused, size_t* totalmem);
|
void Statistics(size_t* amountused, size_t* totalmem);
|
||||||
addr_t GetKernelStack();
|
addr_t GetKernelStack();
|
||||||
size_t GetKernelStackSize();
|
size_t GetKernelStackSize();
|
||||||
addr_t GetInitRD();
|
void GetKernelVirtualArea(addr_t* from, size_t* size);
|
||||||
size_t GetInitRDSize();
|
|
||||||
void RegisterInitRDSize(size_t size);
|
|
||||||
addr_t GetHeapLower();
|
|
||||||
addr_t GetHeapUpper();
|
|
||||||
addr_t GetVideoMemory();
|
|
||||||
size_t GetMaxVideoMemorySize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <sortix/kernel/platform.h>
|
#include <sortix/kernel/platform.h>
|
||||||
|
#include <sortix/kernel/addralloc.h>
|
||||||
#include <sortix/kernel/vnode.h>
|
#include <sortix/kernel/vnode.h>
|
||||||
#include <sortix/kernel/descriptor.h>
|
#include <sortix/kernel/descriptor.h>
|
||||||
#include <sortix/kernel/memorymanagement.h>
|
#include <sortix/kernel/memorymanagement.h>
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
namespace Sortix {
|
namespace Sortix {
|
||||||
namespace InitRD {
|
namespace InitRD {
|
||||||
|
|
||||||
|
addralloc_t initrd_addr_alloc;
|
||||||
uint8_t* initrd = NULL;
|
uint8_t* initrd = NULL;
|
||||||
size_t initrdsize;
|
size_t initrdsize;
|
||||||
const initrd_superblock_t* sb;
|
const initrd_superblock_t* sb;
|
||||||
|
@ -204,21 +206,20 @@ void CheckSum()
|
||||||
void Init(addr_t phys, size_t size)
|
void Init(addr_t phys, size_t size)
|
||||||
{
|
{
|
||||||
assert(!initrd);
|
assert(!initrd);
|
||||||
// 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::Map(phys + amount, virt + amount, PROT_KREAD) )
|
|
||||||
{
|
|
||||||
Panic("Unable to map the init ramdisk into virtual memory");
|
|
||||||
}
|
|
||||||
amount += 0x1000UL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Allocate the needed kernel virtual address space.
|
||||||
|
if ( !AllocateKernelAddress(&initrd_addr_alloc, size) )
|
||||||
|
PanicF("Can't allocate 0x%zx bytes of kernel address space for the "
|
||||||
|
"init ramdisk", size );
|
||||||
|
|
||||||
|
// Map the physical frames onto our address space.
|
||||||
|
addr_t mapat = initrd_addr_alloc.from;
|
||||||
|
for ( size_t i = 0; i < size; i += Page::Size() )
|
||||||
|
if ( !Memory::Map(phys + i, mapat + i, PROT_KREAD) )
|
||||||
|
Panic("Unable to map the init ramdisk into virtual memory");
|
||||||
Memory::Flush();
|
Memory::Flush();
|
||||||
|
|
||||||
initrd = (uint8_t*) virt;
|
initrd = (uint8_t*) mapat;
|
||||||
initrdsize = size;
|
initrdsize = size;
|
||||||
|
|
||||||
if ( size < sizeof(*sb) ) { PanicF("initrd is too small"); }
|
if ( size < sizeof(*sb) ) { PanicF("initrd is too small"); }
|
||||||
|
|
|
@ -224,8 +224,6 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
|
||||||
|
|
||||||
if ( !initrd ) { PanicF("No init ramdisk provided"); }
|
if ( !initrd ) { PanicF("No init ramdisk provided"); }
|
||||||
|
|
||||||
Memory::RegisterInitRDSize(initrdsize);
|
|
||||||
|
|
||||||
// Initialize paging and virtual memory.
|
// Initialize paging and virtual memory.
|
||||||
Memory::Init(bootinfo);
|
Memory::Init(bootinfo);
|
||||||
|
|
||||||
|
|
|
@ -182,35 +182,14 @@ namespace Sortix
|
||||||
const size_t KERNEL_STACK_SIZE = 256UL * 1024UL;
|
const size_t KERNEL_STACK_SIZE = 256UL * 1024UL;
|
||||||
const addr_t KERNEL_STACK_END = 0xFFFF800000001000UL;
|
const addr_t KERNEL_STACK_END = 0xFFFF800000001000UL;
|
||||||
const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE;
|
const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE;
|
||||||
const addr_t VIDEO_MEMORY = KERNEL_STACK_START;
|
|
||||||
const size_t VIDEO_MEMORY_MAX_SIZE = 4UL * 1024UL * 1024UL * 1024UL;
|
|
||||||
const addr_t INITRD = VIDEO_MEMORY + VIDEO_MEMORY_MAX_SIZE;
|
|
||||||
size_t initrdsize = 0;
|
|
||||||
const addr_t HEAPUPPER = 0xFFFFFE8000000000UL;
|
|
||||||
|
|
||||||
addr_t GetInitRD()
|
const addr_t VIRTUAL_AREA_LOWER = KERNEL_STACK_START;
|
||||||
{
|
const addr_t VIRTUAL_AREA_UPPER = 0xFFFFFE8000000000UL;
|
||||||
return INITRD;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetInitRDSize()
|
void GetKernelVirtualArea(addr_t* from, size_t* size)
|
||||||
{
|
{
|
||||||
return initrdsize;
|
*from = KERNEL_STACK_END;
|
||||||
}
|
*size = VIRTUAL_AREA_UPPER - VIRTUAL_AREA_LOWER;
|
||||||
|
|
||||||
void RegisterInitRDSize(size_t size)
|
|
||||||
{
|
|
||||||
initrdsize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_t GetHeapLower()
|
|
||||||
{
|
|
||||||
return Page::AlignUp(INITRD + initrdsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_t GetHeapUpper()
|
|
||||||
{
|
|
||||||
return HEAPUPPER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t GetKernelStack()
|
addr_t GetKernelStack()
|
||||||
|
@ -222,15 +201,5 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
return KERNEL_STACK_SIZE;
|
return KERNEL_STACK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t GetVideoMemory()
|
|
||||||
{
|
|
||||||
return VIDEO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetMaxVideoMemorySize()
|
|
||||||
{
|
|
||||||
return VIDEO_MEMORY_MAX_SIZE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,35 +166,14 @@ namespace Sortix
|
||||||
const size_t KERNEL_STACK_SIZE = 256UL * 1024UL;
|
const size_t KERNEL_STACK_SIZE = 256UL * 1024UL;
|
||||||
const addr_t KERNEL_STACK_END = 0x80001000UL;
|
const addr_t KERNEL_STACK_END = 0x80001000UL;
|
||||||
const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE;
|
const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE;
|
||||||
const addr_t VIDEO_MEMORY = KERNEL_STACK_START;
|
|
||||||
const size_t VIDEO_MEMORY_MAX_SIZE = 384UL * 1024UL * 1024UL;
|
|
||||||
const addr_t INITRD = VIDEO_MEMORY + VIDEO_MEMORY_MAX_SIZE;
|
|
||||||
size_t initrdsize = 0;
|
|
||||||
const addr_t HEAPUPPER = 0xFF400000UL;
|
|
||||||
|
|
||||||
addr_t GetInitRD()
|
const addr_t VIRTUAL_AREA_LOWER = KERNEL_STACK_START;
|
||||||
{
|
const addr_t VIRTUAL_AREA_UPPER = 0xFF400000UL;
|
||||||
return INITRD;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetInitRDSize()
|
void GetKernelVirtualArea(addr_t* from, size_t* size)
|
||||||
{
|
{
|
||||||
return initrdsize;
|
*from = KERNEL_STACK_END;
|
||||||
}
|
*size = VIRTUAL_AREA_UPPER - VIRTUAL_AREA_LOWER;
|
||||||
|
|
||||||
void RegisterInitRDSize(size_t size)
|
|
||||||
{
|
|
||||||
initrdsize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_t GetHeapLower()
|
|
||||||
{
|
|
||||||
return Page::AlignUp(INITRD + initrdsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_t GetHeapUpper()
|
|
||||||
{
|
|
||||||
return HEAPUPPER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t GetKernelStack()
|
addr_t GetKernelStack()
|
||||||
|
@ -206,15 +185,5 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
return KERNEL_STACK_SIZE;
|
return KERNEL_STACK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t GetVideoMemory()
|
|
||||||
{
|
|
||||||
return VIDEO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetMaxVideoMemorySize()
|
|
||||||
{
|
|
||||||
return VIDEO_MEMORY_MAX_SIZE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue