memory.h
Code: Select all
#ifndef _MEMORY_H_
#define _MEMORY_H_
#include "_bool.h"
#include "types.h"
#define PAGE_SIZE 4096
struct mem_block
{
unsigned int* start;
unsigned int* end;
size_t size;
struct mem_block* next;
struct mem_block* prev;
};
unsigned int* mem_start;
unsigned int* mem_end;
struct mem_block* mem_firstblock;
struct mem_block* mem_lastblock;
struct mem_block* mem_dead_firstblock;
struct mem_block* mem_dead_lastblock;
unsigned char *memcpy(void *dest, void *src, int count);
unsigned char *memset(void *dest, unsigned char val, int count);
unsigned short *memsetw(void *dest, unsigned short val, int count);
void memman_setup(unsigned int startaddr, unsigned int endaddr);
struct mem_block* memman_alloc(size_t size);
void memman_dealloc(struct mem_block* block);
#endif
Code: Select all
#include "memory.h"
#include "io.h"
unsigned int* mem_start;
unsigned int* mem_end;
struct mem_block* mem_firstblock = NULL;
struct mem_block* mem_lastblock = NULL;
struct mem_block* mem_dead_firstblock = NULL;
struct mem_block* mem_dead_lastblock = NULL;
unsigned char *memcpy(void *dest, void *src, int count)
{
char* dest8 = dest;
char* src8 = src;
while(count--)
{
*dest8++ = *src8++;
}
return dest;
}
unsigned char *memset(void *dest, unsigned char val, int count)
{
char* dest8 = dest;
while(count--)
{
*dest8++ = val;
}
return dest;
}
unsigned short *memsetw(void *dest, unsigned short val, int count)
{
char* dest8 = dest;
while(count--)
{
*dest8++ = val;
}
return dest;
}
void memman_setup(unsigned int startaddr, unsigned int endaddr)
{
mem_start = (unsigned int*)startaddr;
mem_end = (unsigned int*)endaddr;
//Setup a dummy block
mem_firstblock->start = mem_start;
mem_firstblock->end = mem_start;
mem_firstblock->size = 0;
mem_firstblock->next = NULL;
mem_firstblock->prev = NULL;
mem_lastblock = mem_firstblock;
panic("%p = %p", mem_lastblock, mem_firstblock);
//Setup a dead dummy block
mem_dead_firstblock->start = (unsigned int*)0;
mem_dead_firstblock->end = (unsigned int*)0;
mem_dead_firstblock->size = 0;
mem_dead_firstblock->next = NULL;
mem_dead_firstblock->prev = NULL;
mem_dead_lastblock = mem_dead_firstblock;
}
struct mem_block* memman_alloc(size_t size)
{
//Are there any dead block we can use instead?
/*struct mem_block* this_dead = mem_dead_firstblock->next;
while(this_dead != NULL)
{
//Is the block large enough?
if(size <= (unsigned int)(this_dead->end - this_dead->start))
{
unsigned int dead = size - (this_dead->end - this_dead->start);
//We can use the dead block
//Resize the block
this_dead->end = this_dead->start + size;
this_dead->size = size;
this_dead->prev = mem_lastblock;
this_dead->next = NULL;
this_dead->prev->next = this_dead->next;
this_dead->next->prev = this_dead->prev;
mem_lastblock = this_dead;
//If the block was resized, we have another dead one
struct mem_block* new_dead = NULL;
new_dead->start = this_dead->end + 1;
new_dead->end = new_dead->start + dead;
new_dead->size = dead;
new_dead->prev = mem_dead_lastblock;
new_dead->next = NULL;
mem_dead_lastblock = new_dead;
return this_dead;
}
this_dead = this_dead->next;
}*/
panic("%p", mem_lastblock->end);
struct mem_block* newblock = NULL;
newblock->start = mem_lastblock->end + 1;
newblock->end = newblock->start + size - 1;
newblock->size = size;
newblock->next = NULL;
newblock->prev = mem_lastblock;
mem_lastblock = newblock;
return newblock;
}
void memman_dealloc(struct mem_block* block)
{
//Remove the block from the list
block->next->prev = block->prev;
block->prev->next = block->next;
//Now we have a dead block.
mem_dead_lastblock->next = block;
block->prev = mem_dead_lastblock;
block->next = NULL;
mem_dead_lastblock = block;
}
I have a problem as well. What i do in memman_setup() like setting the mem_firstblock->end is not stored when the function is exited. Shouldn't the values be "permanently" stored as the variable is global?