If I add 1 small printf, something will mess up. For example, without that call my WIP font drawing engine is working normal, except for some drawing errors: But if I call it, it'll mess all up: This is my memory.c:
Code: Select all
//Memory management.
#include "../include/memory.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "../include/fio.h"
#define isBitSet(var, n) ((var & (1 << n)))
// Struct page is only for internal usage and should not be used anywhere else
#define PAGE_SIZE 4096
#define PAGE_MAX 4092 // (PAGE_SIZE - 2 * sizeof(uint16_t))
typedef struct
{
uint16_t free_bytes;
uint16_t free_offset;
uint8_t memory[PAGE_MAX];
} page;
size_t page_count;
page* pages;
void* memcpy(void* dst, const void* src, size_t n)
{
size_t i;
if((uint8_t*)(dst) < (uint8_t*)(src))
{
for(i = 0; i < n; ++i)
{
((uint8_t*)(dst))[i] = ((uint8_t*)(src))[i];
}
}
else
{
for(i = 0; i < n; ++i)
{
((uint8_t*)(dst))[n - i - 1] = ((uint8_t*)(src))[n - i - 1];
}
}
return dst;
}
void* memset(void* ptr, uint8_t val, size_t n)
{
size_t i;
for(i = 0; i < n; ++i)
{
((uint8_t*)(ptr))[i] = val;
}
return ptr;
}
void* memmove(void* dst, void* src, size_t n)
{
if(dst != src)
{
memcpy(dst, src, n);
free(src);
}
return dst;
}
/*
* malloc function.
* Allocating num bytes of memory and returning pointer to it.
* Memory is located at the end of the kernel memory.
*/
extern uint16_t kernel_heap_start;
void* malloc(size_t num)
{
size_t i;
if(num < PAGE_MAX)
{
for(i = 0; i < page_count; ++i)
{
if(pages[i].free_bytes >= num + sizeof(uint16_t))
{
void* free_space = (void*)((size_t)(pages + i) + pages[i].free_offset);
*((uint16_t*)(free_space)) = num;
pages[i].free_bytes -= num + sizeof(uint16_t);
pages[i].free_offset += num + sizeof(uint16_t);
return (void*)((uint16_t*)(free_space) + 1);
}
}
perr("malloc: no free pages left");
return 0;
}
else
{
perr("malloc: more than one page requested");
return 0;
}
}
void* calloc(size_t num, size_t size)
{
size *= num;
void* result = malloc(size);
memset(result, 0, size);
return result;
}
void *realloc(void* memblock, size_t size)
{
if(memblock < (void*)(pages))
{
return malloc(size);
}
else
{
uint16_t oldsize = *((uint16_t*)(memblock) - 1);
void* newmem = malloc(size);
memmove(newmem, memblock, oldsize);
}
return memblock;
}
void free(void* ptr)
{
uint16_t size = *((uint16_t*)(ptr) - 1);
page* pg = (page*)((size_t)(ptr) - (size_t)(ptr) % PAGE_SIZE);
pg->free_bytes -= size;
if(pg->free_offset == (uint16_t)((size_t)(ptr) - (size_t)(pg) + size))
{
pg->free_offset -= size;
}
}
uint8_t init_page(page* this)
{
this->free_bytes = PAGE_MAX;
this->free_offset = 2;
if(*(uint16_t*)(this) != PAGE_MAX || *((uint16_t*)(this) + 1) != 2)
{
return 0; // false
}
return 1; // true
}
size_t init_memory()
{
size_t pgptr = (size_t)&kernel_heap_start;
pgptr += (PAGE_SIZE - pgptr % PAGE_SIZE);
page_count = 0;
pages = (page*)(pgptr);
while(init_page(pages + page_count) && page_count < 2048) ++page_count;
return page_count;
}