Implemented liballoc.

This commit is contained in:
Cody Brocious 2016-05-08 08:27:44 -06:00
parent 0f71775c8f
commit 76d1a6e060
17 changed files with 699 additions and 34 deletions

View file

@ -10,5 +10,5 @@ Box::Box() {
cpu = new Cpu(mem, kmem);
pm = new PageManager();
pm->add_region(0, RAM_SIZE);
pm->add_region(1024*1024, RAM_SIZE - 1024*1024);
}

27
Cpu.cpp
View file

@ -25,6 +25,7 @@ Cpu::Cpu(uint8_t *ram, uint8_t *kram) {
kmem = kram;
bailout(hv_vm_create(HV_VM_DEFAULT));
memset(mem, 0, RAM_SIZE);
bailout(hv_vm_map(mem, 0, RAM_SIZE, HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC));
bailout(hv_vm_map(kmem, 0xc0000000, KRAM_SIZE, HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC));
bailout(hv_vcpu_create(&vcpu, HV_VCPU_DEFAULT));
@ -46,10 +47,10 @@ Cpu::Cpu(uint8_t *ram, uint8_t *kram) {
wvmcs(VMCS_CTRL_EXC_BITMAP, 0);
wvmcs(VMCS_CTRL_CR0_MASK, 0xffffffff);
wvmcs(VMCS_CTRL_CR0_SHADOW, 0xffffffff);
wvmcs(VMCS_CTRL_CR4_MASK, 0);
wvmcs(VMCS_CTRL_CR4_SHADOW, 0);
wvmcs(VMCS_CTRL_CR4_MASK, 0xffffffff);
wvmcs(VMCS_CTRL_CR4_SHADOW, 0xffffffff);
uint32_t directory = 32*1024*1024; // Page directory base
uint32_t directory = 64*1024*1024; // Page directory base
uint32_t *dir = (uint32_t *) (mem + directory);
for(int i = 0; i < 1024; ++i) {
dir[i] = (directory + 4096 + 4096 * i) | 0x7;
@ -61,12 +62,12 @@ Cpu::Cpu(uint8_t *ram, uint8_t *kram) {
wvmcs(VMCS_GUEST_CR3, directory);
wvmcs(VMCS_GUEST_CR0, 0x80000000 | 0x20 | 0x01); // Paging | NE | PE
uint8_t *gdt = ram + 0x10000;
uint8_t *gdt = ram + 96*1024*1024;
gdt_encode(gdt, 0, 0, 0, 0); // Null entry
gdt_encode(gdt, 1, 0, 0xffffffff, 0x9A); // Code
gdt_encode(gdt, 2, 0, 0xffffffff, 0x92); // Data
wvmcs(VMCS_GUEST_GDTR_LIMIT, 0x100);
wvmcs(VMCS_GUEST_GDTR_BASE, 0x10000);
wvmcs(VMCS_GUEST_GDTR_BASE, 96*1024*1024);
wvmcs(VMCS_GUEST_CS, 1 << 3);
wvmcs(VMCS_GUEST_CS_AR, 0xc093);
@ -110,11 +111,11 @@ Cpu::Cpu(uint8_t *ram, uint8_t *kram) {
wvmcs(VMCS_GUEST_CR4, 0x2000);
map_pages(0, 0, 1000);
map_pages(96 * 1024 * 1024, 96 * 1024 * 1024, 1);
}
void Cpu::map_pages(uint32_t virt, uint32_t phys, uint32_t count) {
uint32_t *dir = (uint32_t *) (mem + 32*1024*1024);
uint32_t *dir = (uint32_t *) (mem + 64*1024*1024);
for(int i = 0; i < count; ++i) {
uint32_t *table = (uint32_t *) (mem + (dir[virt >> 22] & ~0xFFF));
table[(virt >> 12) & 0x3ff] = phys | 0x7;
@ -124,10 +125,14 @@ void Cpu::map_pages(uint32_t virt, uint32_t phys, uint32_t count) {
hv_vcpu_invalidate_tlb(vcpu);
}
void Cpu::alloc_stack(uint32_t bottom_virt, uint32_t bottom_phys, uint32_t size) {
wreg(HV_X86_RSP, bottom_virt + size);
wreg(HV_X86_RBP, bottom_virt + size - 0x20);
map_pages(bottom_virt, bottom_phys, size / 4096);
uint32_t Cpu::virt2phys(uint32_t addr) {
uint32_t cr3 = rreg(HV_X86_CR3);
if(cr3 == 0)
return addr;
uint32_t *directory = (uint32_t *) (mem + cr3);
uint32_t *table = (uint32_t *) (mem + (directory[addr >> 22] & ~0xFFF));
return (table[(addr >> 12) & 0x3ff] & ~0xFFF) + (addr & 0xFFF);
}
void Cpu::read_memory(uint32_t addr, uint32_t size, void *buffer) {

View file

@ -13,8 +13,8 @@ public:
~Cpu();
void run(uint32_t eip);
void map_pages(uint32_t virt, uint32_t phys, uint32_t count);
void alloc_stack(uint32_t bottom_virt, uint32_t bottom_phys, uint32_t size);
uint32_t virt2phys(uint32_t addr);
void read_memory(uint32_t addr, uint32_t size, void *buffer);
template<typename T> T read_memory(uint32_t addr) {
T value;

View file

@ -20,10 +20,9 @@ void log(const char *fmt, ...) {
vmcall(VMCALL_LOG, output);
}
void *map(void *virt_base, void *phys_base, uint32_t count) {
void *map(void *virt_base, uint32_t count) {
volatile map_pages_t smap;
smap.virt_base = (uint32_t) virt_base;
smap.phys_base = (uint32_t) phys_base;
smap.count = count;
vmcall(VMCALL_MAP, &smap);

View file

@ -6,5 +6,5 @@
void log(const char *fmt, ...);
#define printf log
void *map(void *virt_base, void *phys_base, uint32_t count);
void *map(void *virt_base, uint32_t count);
void unmap(void *virt_base, uint32_t count);

View file

@ -10,16 +10,16 @@ typedef struct idt_entry {
typedef struct idt_ptr {
uint16_t limit;
uint32_t base;
idt_entry_t *base;
} __attribute__((packed)) idt_ptr_t;
idt_entry_t *real_idt = (idt_entry_t *) 0x1000;
static idt_ptr_t idtp;
void init_idt() {
log("IDT initializing...");
auto real_idt = new idt_entry_t[256];
for(int i = 0; i < 256; ++i) {
uint32_t isr_addr = (uint32_t) all_isrs[i];
auto isr_addr = (uint32_t) all_isrs[i];
real_idt[i].flags = 0x8E;
real_idt[i].sel = 8;
real_idt[i].always0 = 0;
@ -28,7 +28,7 @@ void init_idt() {
}
idtp.limit = (sizeof(idt_entry_t) * 256) - 1;
idtp.base = (uint32_t) real_idt;
idtp.base = real_idt;
asm("lidt (_ZL4idtp)");
asm("sti");

View file

@ -1,7 +1,7 @@
CPP_FILES := $(wildcard *.cpp)
ASM_FILES := $(wildcard *.S)
OBJ_FILES := $(CPP_FILES:.cpp=.o) $(ASM_FILES:.S=.o)
CC_FLAGS := -std=c++11 -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti -I/usr/local/gcc-4.8.1-for-linux32/include -I/usr/local/gcc-4.8.1-for-linux32/include/c++/4.8.1/ -I/usr/local/gcc-4.8.1-for-linux32/include/c++/4.8.1/i586-pc-linux/ -Iinclude
CC_FLAGS := -std=c++11 -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti
LD_FLAGS := -T linker.ld -ffreestanding -fno-use-linker-plugin -O2 -nostdlib
%.o: %.cpp

View file

@ -4,3 +4,8 @@
#include "mini-printf.hpp"
#include "Hypercall.hpp"
#include "Interrupts.hpp"
#include "liballoc.hpp"
inline void *operator new[](unsigned long size) {
return malloc(size);
}

View file

@ -6,8 +6,6 @@ void entrypoint() {
log("Idle.");
log("%08x", (uint32_t) map((void *) 0xdeadbeef, (void *) 0, 10));
while(true) {
}
}

528
NightBeliever/liballoc.cpp Normal file
View file

@ -0,0 +1,528 @@
#include "NightBeliever.hpp"
/** Durand's Ridiculously Amazing Super Duper Memory functions. */
//#define DEBUG
#define LIBALLOC_MAGIC 0xc001c0de
#define MAXCOMPLETE 5
#define MAXEXP 32
#define MINEXP 8
#define MODE_BEST 0
#define MODE_INSTANT 1
#define MODE MODE_BEST
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
#ifdef DEBUG
unsigned int l_allocated = 0; //< The real amount of memory allocated.
unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed).
#endif
static int l_initialized = 0; //< Flag to indicate initialization.
static int l_pageSize = 4096; //< Individual page size
static int l_pageCount = 16; //< Minimum number of pages to allocate.
// *********** HELPER FUNCTIONS *******************************
/** Returns the exponent required to manage 'size' amount of memory.
*
* Returns n where 2^n <= size < 2^(n+1)
*/
static inline int getexp( unsigned int size )
{
if ( size < (1<<MINEXP) )
{
#ifdef DEBUG
printf("getexp returns -1 for %i less than MINEXP\n", size );
#endif
return -1; // Smaller than the quantum.
}
int shift = MINEXP;
while ( shift < MAXEXP )
{
if ( (1<<shift) > size ) break;
shift += 1;
}
#ifdef DEBUG
printf("getexp returns %i (%i bytes) for %i size\n", shift - 1, (1<<(shift -1)), size );
#endif
return shift - 1;
}
static void* liballoc_memset(void* s, int c, size_t n)
{
int i;
for ( i = 0; i < n ; i++)
((char*)s)[i] = c;
return s;
}
static void* liballoc_memcpy(void* s1, const void* s2, size_t n)
{
char *cdest;
char *csrc;
unsigned int *ldest = (unsigned int*)s1;
unsigned int *lsrc = (unsigned int*)s2;
while ( n >= sizeof(unsigned int) )
{
*ldest++ = *lsrc++;
n -= sizeof(unsigned int);
}
cdest = (char*)ldest;
csrc = (char*)lsrc;
while ( n > 0 )
{
*cdest++ = *csrc++;
n -= 1;
}
return s1;
}
#ifdef DEBUG
static void dump_array()
{
int i = 0;
struct boundary_tag *tag = NULL;
printf("------ Free pages array ---------\n");
printf("System memory allocated: %i\n", l_allocated );
printf("Memory in used (malloc'ed): %i\n", l_inuse );
for ( i = 0; i < MAXEXP; i++ )
{
printf("%.2i(%i): ",i, l_completePages[i] );
tag = l_freePages[ i ];
while ( tag != NULL )
{
if ( tag->split_left != NULL ) printf("*");
printf("%i", tag->real_size );
if ( tag->split_right != NULL ) printf("*");
printf(" ");
tag = tag->next;
}
printf("\n");
}
printf("'*' denotes a split to the left/right of a tag\n");
}
#endif
static inline void insert_tag( struct boundary_tag *tag, int index )
{
int realIndex;
if ( index < 0 )
{
realIndex = getexp( tag->real_size - sizeof(struct boundary_tag) );
if ( realIndex < MINEXP ) realIndex = MINEXP;
}
else
realIndex = index;
tag->index = realIndex;
if ( l_freePages[ realIndex ] != NULL )
{
l_freePages[ realIndex ]->prev = tag;
tag->next = l_freePages[ realIndex ];
}
l_freePages[ realIndex ] = tag;
}
static inline void remove_tag( struct boundary_tag *tag )
{
if ( l_freePages[ tag->index ] == tag ) l_freePages[ tag->index ] = tag->next;
if ( tag->prev != NULL ) tag->prev->next = tag->next;
if ( tag->next != NULL ) tag->next->prev = tag->prev;
tag->next = NULL;
tag->prev = NULL;
tag->index = -1;
}
static inline struct boundary_tag* melt_left( struct boundary_tag *tag )
{
struct boundary_tag *left = tag->split_left;
left->real_size += tag->real_size;
left->split_right = tag->split_right;
if ( tag->split_right != NULL ) tag->split_right->split_left = left;
return left;
}
static inline struct boundary_tag* absorb_right( struct boundary_tag *tag )
{
struct boundary_tag *right = tag->split_right;
remove_tag( right ); // Remove right from free pages.
tag->real_size += right->real_size;
tag->split_right = right->split_right;
if ( right->split_right != NULL )
right->split_right->split_left = tag;
return tag;
}
static inline struct boundary_tag* split_tag( struct boundary_tag* tag )
{
unsigned int remainder = tag->real_size - sizeof(struct boundary_tag) - tag->size;
struct boundary_tag *new_tag =
(struct boundary_tag*)((unsigned int)tag + sizeof(struct boundary_tag) + tag->size);
new_tag->magic = LIBALLOC_MAGIC;
new_tag->real_size = remainder;
new_tag->next = NULL;
new_tag->prev = NULL;
new_tag->split_left = tag;
new_tag->split_right = tag->split_right;
if (new_tag->split_right != NULL) new_tag->split_right->split_left = new_tag;
tag->split_right = new_tag;
tag->real_size -= new_tag->real_size;
insert_tag( new_tag, -1 );
return new_tag;
}
// ***************************************************************
static struct boundary_tag* allocate_new_tag( unsigned int size )
{
unsigned int pages;
unsigned int usage;
struct boundary_tag *tag;
// This is how much space is required.
usage = size + sizeof(struct boundary_tag);
// Perfect amount of space
pages = usage / l_pageSize;
if ( (usage % l_pageSize) != 0 ) pages += 1;
// Make sure it's >= the minimum size.
if ( pages < l_pageCount ) pages = l_pageCount;
tag = (struct boundary_tag*)liballoc_alloc( pages );
if ( tag == NULL ) return NULL; // uh oh, we ran out of memory.
tag->magic = LIBALLOC_MAGIC;
tag->size = size;
tag->real_size = pages * l_pageSize;
tag->index = -1;
tag->next = NULL;
tag->prev = NULL;
tag->split_left = NULL;
tag->split_right = NULL;
#ifdef DEBUG
printf("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag, pages, pages * l_pageSize, size );
l_allocated += pages * l_pageSize;
printf("Total memory usage = %i KB\n", (int)((l_allocated / (1024))) );
#endif
return tag;
}
void *malloc(size_t size)
{
int index;
void *ptr;
struct boundary_tag *tag = NULL;
liballoc_lock();
if ( l_initialized == 0 )
{
log("initializing malloc");
#ifdef DEBUG
printf("%s\n","liballoc initializing.");
#endif
for ( index = 0; index < MAXEXP; index++ )
{
l_freePages[index] = NULL;
l_completePages[index] = 0;
}
l_initialized = 1;
}
index = getexp( size ) + MODE;
if ( index < MINEXP ) index = MINEXP;
// Find one big enough.
tag = l_freePages[ index ]; // Start at the front of the list.
while ( tag != NULL )
{
// If there's enough space in this tag.
if ( (tag->real_size - sizeof(struct boundary_tag))
>= (size + sizeof(struct boundary_tag) ) )
{
#ifdef DEBUG
printf("Tag search found %i >= %i\n",(tag->real_size - sizeof(struct boundary_tag)), (size + sizeof(struct boundary_tag) ) );
#endif
break;
}
tag = tag->next;
}
// No page found. Make one.
if ( tag == NULL )
{
if ( (tag = allocate_new_tag( size )) == NULL )
{
liballoc_unlock();
return NULL;
}
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
}
else
{
remove_tag( tag );
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
l_completePages[ index ] -= 1;
}
// We have a free page. Remove it from the free pages list.
tag->size = size;
// Removed... see if we can re-use the excess space.
#ifdef DEBUG
printf("Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n", tag->real_size - sizeof(struct boundary_tag), size, tag->real_size - size - sizeof(struct boundary_tag), index, 1<<index );
#endif
unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder
if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ )
{
int childIndex = getexp( remainder );
if ( childIndex >= 0 )
{
#ifdef DEBUG
printf("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex, (1<<childIndex) );
#endif
struct boundary_tag *new_tag = split_tag( tag );
new_tag = new_tag; // Get around the compiler warning about unused variables.
#ifdef DEBUG
printf("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n", tag->real_size, new_tag->real_size, new_tag->index );
#endif
}
}
ptr = (void*)((unsigned int)tag + sizeof( struct boundary_tag ) );
#ifdef DEBUG
l_inuse += size;
printf("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
dump_array();
#endif
liballoc_unlock();
return ptr;
}
void free(void *ptr)
{
int index;
struct boundary_tag *tag;
if ( ptr == NULL ) return;
liballoc_lock();
tag = (struct boundary_tag*)((unsigned int)ptr - sizeof( struct boundary_tag ));
if ( tag->magic != LIBALLOC_MAGIC )
{
liballoc_unlock(); // release the lock
return;
}
#ifdef DEBUG
l_inuse -= tag->size;
printf("free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
#endif
// MELT LEFT...
while ( (tag->split_left != NULL) && (tag->split_left->index >= 0) )
{
#ifdef DEBUG
printf("Melting tag left into available memory. Left was %i, becomes %i (%i)\n", tag->split_left->real_size, tag->split_left->real_size + tag->real_size, tag->split_left->real_size );
#endif
tag = melt_left( tag );
remove_tag( tag );
}
// MELT RIGHT...
while ( (tag->split_right != NULL) && (tag->split_right->index >= 0) )
{
#ifdef DEBUG
printf("Melting tag right into available memory. This was was %i, becomes %i (%i)\n", tag->real_size, tag->split_right->real_size + tag->real_size, tag->split_right->real_size );
#endif
tag = absorb_right( tag );
}
// Where is it going back to?
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
if ( index < MINEXP ) index = MINEXP;
// A whole, empty block?
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
{
if ( l_completePages[ index ] == MAXCOMPLETE )
{
// Too many standing by to keep. Free this one.
unsigned int pages = tag->real_size / l_pageSize;
if ( (tag->real_size % l_pageSize) != 0 ) pages += 1;
if ( pages < l_pageCount ) pages = l_pageCount;
liballoc_free( tag, pages );
#ifdef DEBUG
l_allocated -= pages * l_pageSize;
printf("Resource freeing %x of %i pages\n", tag, pages );
dump_array();
#endif
liballoc_unlock();
return;
}
l_completePages[ index ] += 1; // Increase the count of complete pages.
}
// ..........
insert_tag( tag, index );
#ifdef DEBUG
printf("Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n", tag->real_size, tag->size, index );
dump_array();
#endif
liballoc_unlock();
}
void* calloc(size_t nobj, size_t size)
{
int real_size;
void *p;
real_size = nobj * size;
p = malloc( real_size );
liballoc_memset( p, 0, real_size );
return p;
}
void* realloc(void *p, size_t size)
{
void *ptr;
struct boundary_tag *tag;
int real_size;
if ( size == 0 )
{
free( p );
return NULL;
}
if ( p == NULL ) return malloc( size );
if ( liballoc_lock != NULL ) liballoc_lock(); // lockit
tag = (struct boundary_tag*)((unsigned int)p - sizeof( struct boundary_tag ));
real_size = tag->size;
if ( liballoc_unlock != NULL ) liballoc_unlock();
if ( real_size > size ) real_size = size;
ptr = malloc( size );
liballoc_memcpy( ptr, p, real_size );
free( p );
return ptr;
}

View file

@ -0,0 +1,97 @@
#ifndef _LIBALLOC_H
#define _LIBALLOC_H
// If we are told to not define our own size_t, then we
// skip the define.
#ifndef _ALLOC_SKIP_DEFINE
#ifndef _HAVE_SIZE_T
#define _HAVE_SIZE_T
typedef unsigned int size_t;
#endif
#ifndef NULL
#define NULL 0
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** This is a boundary tag which is prepended to the
* page or section of a page which we have allocated. It is
* used to identify valid memory blocks that the
* application is trying to free.
*/
struct boundary_tag
{
unsigned int magic; //< It's a kind of ...
unsigned int size; //< Requested size.
unsigned int real_size; //< Actual size.
int index; //< Location in the page table.
struct boundary_tag *split_left; //< Linked-list info for broken pages.
struct boundary_tag *split_right; //< The same.
struct boundary_tag *next; //< Linked list info.
struct boundary_tag *prev; //< Linked list info.
};
/** This function is supposed to lock the memory data structures. It
* could be as simple as disabling interrupts or acquiring a spinlock.
* It's up to you to decide.
*
* \return 0 if the lock was acquired successfully. Anything else is
* failure.
*/
int liballoc_lock();
/** This function unlocks what was previously locked by the liballoc_lock
* function. If it disabled interrupts, it enables interrupts. If it
* had acquiried a spinlock, it releases the spinlock. etc.
*
* \return 0 if the lock was successfully released.
*/
int liballoc_unlock();
/** This is the hook into the local system which allocates pages. It
* accepts an integer parameter which is the number of pages
* required. The page size was set up in the liballoc_init function.
*
* \return NULL if the pages were not allocated.
* \return A pointer to the allocated memory.
*/
void* liballoc_alloc(int);
/** This frees previously allocated memory. The void* parameter passed
* to the function is the exact same value returned from a previous
* liballoc_alloc call.
*
* The integer value is the number of pages to free.
*
* \return 0 if the memory was successfully freed.
*/
int liballoc_free(void*,int);
void *malloc(size_t); //< The standard function.
void *realloc(void *, size_t); //< The standard function.
void *calloc(size_t, size_t); //< The standard function.
void free(void *); //< The standard function.
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,21 @@
#include "NightBeliever.hpp"
int liballoc_lock() {
//pthread_mutex_lock( &mutex );
return 0;
}
int liballoc_unlock() {
//pthread_mutex_unlock( &mutex );
return 0;
}
void* liballoc_alloc(int pages) {
return map((void *) 0, pages);
}
int liballoc_free( void* ptr, int pages )
{
unmap(ptr, pages);
return 0;
}

View file

@ -15,16 +15,28 @@ int vmcall_dispatch(uint32_t call, uint32_t addr) {
break;
}
case VMCALL_MAP: {
map_pages_t smap = box->cpu->read_memory<map_pages_t>(addr);
auto smap = box->cpu->read_memory<map_pages_t>(addr);
cout << "Mapping some pages and shit." << endl;
cout << hex << smap.virt_base << endl;
cout << hex << smap.phys_base << endl;
cout << dec << smap.count << endl;
if(smap.virt_base == 0) {
smap.virt_base = box->pm->alloc_virt(smap.count);
box->cpu->write_memory(addr, smap);
}
for(int i = 0; i < smap.count; ++i)
box->cpu->map_pages(smap.virt_base + i * 4096, box->pm->alloc_phys(), 1);
smap.virt_base = 0xcafebabe;
break;
}
case VMCALL_UNMAP: {
auto smap = box->cpu->read_memory<unmap_pages_t>(addr);
auto addr = smap.virt_base;
for(int i = 0; i < smap.count; ++i) {
box->pm->free_phys(box->cpu->virt2phys(addr));
addr += 4096;
}
box->pm->free_virt(smap.virt_base, smap.count);
box->cpu->write_memory(addr, smap);
break;
}
default:

View file

@ -9,9 +9,9 @@
#include <list>
using namespace std;
#define bailout(expr) do { if(expr) { cout << "Bailout: " << #expr << endl; exit(1); } } while(0)
#define bailout(expr) do { if(expr) { cout << "Bailout: " << #expr << " @ " << __FILE__ << " (" << __LINE__ << ")" << endl; exit(1); } } while(0)
#define RAM_SIZE 64*1024*1024
#define RAM_SIZE 128*1024*1024
#define KRAM_SIZE 128*1024*1024
#include "Xbe.hpp"

View file

@ -11,6 +11,7 @@ uint32_t load_multiboot(Cpu *cpu, uint32_t *header) {
assert(memsize <= KRAM_SIZE);
memcpy(cpu->kmem + (header[4] - 0xC0000000), rel + (header[4] - header[3]), memsize);
memset(cpu->kmem + (header[5] - 0xC0000000), 0, header[6] - header[5]);
cpu->map_pages(0xC0000000, 0xC0000000, memsize / 4096);
return header[7];

View file

@ -2,7 +2,6 @@
typedef struct map_pages {
uint32_t virt_base;
uint32_t phys_base;
uint32_t count;
} map_pages_t;

BIN
zookeeper

Binary file not shown.