add terrible, janky memory manager
This commit is contained in:
parent
624ffbe738
commit
4c6c4a0150
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@ ISO := hhhos.iso
|
|||
|
||||
CC = x86_64-elf-gcc
|
||||
NASM = nasm
|
||||
|
||||
|
||||
# User controllable CFLAGS.
|
||||
CFLAGS = -Wall -Wextra -O2 -pipe
|
||||
NASMFLAGS = -felf64
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <framebuffer.h>
|
||||
#include <psf.h>
|
||||
#include <paging.h>
|
||||
#include <mem/mem.h>
|
||||
|
||||
static u8 stack[16384];
|
||||
|
||||
|
@ -88,6 +89,11 @@ framebuffer_t *framebuffer;
|
|||
extern usize _kernel_start;
|
||||
extern usize _kernel_end;
|
||||
|
||||
struct test_struct {
|
||||
unsigned int something;
|
||||
int hello;
|
||||
};
|
||||
|
||||
void _start(struct stivale2_struct *stivale2_struct) {
|
||||
struct stivale2_struct_tag_framebuffer *tag_fb = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID);
|
||||
struct stivale2_struct_tag_memmap *tag_mmap = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_MEMMAP_ID);
|
||||
|
@ -153,7 +159,16 @@ void _start(struct stivale2_struct *stivale2_struct) {
|
|||
printf("no\n");
|
||||
}
|
||||
|
||||
printf("_start memory address: %#lX\n", (usize)_start);
|
||||
usize start_mem_addr = (usize)_start;
|
||||
printf("_start memory address: %#lX\n", start_mem_addr);
|
||||
|
||||
mem_populate_blocks(start_mem_addr + 0x42069);
|
||||
|
||||
/* TODO: only enable this in debug (or just handle testing in a better way) */
|
||||
if (mem_test_mm()) {
|
||||
printf("memory manager test passed\n");
|
||||
}
|
||||
|
||||
printf("----------\n");
|
||||
printf("hello yes");
|
||||
|
||||
|
|
88
arch/x86_64/mem/mem.c
Normal file
88
arch/x86_64/mem/mem.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include <mem/mem.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct mem_block mem_blocks[MEM_BLOCK_LIST_SIZE];
|
||||
usize last_free_index = 0;
|
||||
|
||||
void mem_populate_blocks(usize starting_addr) {
|
||||
usize last_addr = starting_addr;
|
||||
unsigned int last_size = 1;
|
||||
|
||||
for (int i = 0; i < MEM_BLOCK_LIST_SIZE; i++) {
|
||||
mem_blocks[i].addr = last_addr;
|
||||
mem_blocks[i].size = last_size;
|
||||
last_addr += mem_blocks[i].size;
|
||||
last_size += MEM_BLOCK_INCREASE_SIZE;
|
||||
//printf("-- POPULATED BLOCK: addr = %#lX; size = %#lX\n", mem_blocks[i].addr, mem_blocks[i].size);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int find_available_block(usize start_index, usize size) {
|
||||
struct mem_block block = mem_blocks[start_index];
|
||||
if (!block.is_used) {
|
||||
if ((block.addr - mem_blocks[last_free_index].addr) >= size)
|
||||
return start_index; /* we found a free block */
|
||||
else
|
||||
return find_available_block(start_index + 1, size);
|
||||
} else {
|
||||
return find_available_block(start_index + 1, size);
|
||||
}
|
||||
}
|
||||
|
||||
void* malloc(usize size) {
|
||||
unsigned int block_index = find_available_block(last_free_index, size);
|
||||
mem_blocks[block_index].is_used = true;
|
||||
|
||||
return mem_blocks[block_index].addr;
|
||||
}
|
||||
|
||||
void free(void* memory) {
|
||||
for (int i = 0; i < MEM_BLOCK_LIST_SIZE; i++) {
|
||||
if (mem_blocks[i].addr == (usize)memory) {
|
||||
mem_blocks[i].is_used = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct test_struct {
|
||||
int hello;
|
||||
};
|
||||
|
||||
/* terrible function to test the really bad memory manager i've made - it's not great at all (only checks if the last element has the same address) */
|
||||
bool mem_test_mm() {
|
||||
unsigned int count = 42;
|
||||
usize last_addr = 1;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
struct test_struct* test_allocated = (struct test_struct*) malloc(sizeof(struct test_struct));
|
||||
if ((usize)test_allocated == 0) {
|
||||
printf("test_struct #%d: FAIL: malloc() -> 0", i);
|
||||
return false;
|
||||
}
|
||||
if ((usize)test_allocated == last_addr) {
|
||||
printf("test_struct #%d: FAIL: new allocated struct address is the same as the last one", i);
|
||||
return false;
|
||||
}
|
||||
last_addr = (usize)test_allocated;
|
||||
//printf("test_struct #%d memory address: %#lX\n", i, (usize)test_allocated);
|
||||
test_allocated->hello = i;
|
||||
if (test_allocated->hello != i) {
|
||||
printf("test_struct #%d: FAIL: test_allocated->hello(%d) != i(%d)", i, test_allocated->hello, i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct test_struct* will_be_freed = (struct test_struct*) malloc(sizeof(struct test_struct));
|
||||
will_be_freed->hello = 76;
|
||||
free(will_be_freed);
|
||||
|
||||
//printf("test_struct will_be_freed memory address: %#lX\n", (usize)will_be_freed);
|
||||
|
||||
if ((usize)malloc(sizeof(struct test_struct)) != (usize)will_be_freed) {
|
||||
printf("test_struct will_be_freed: FAIL: next allocation address is not equal to the freed struct's address");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
18
include/mem/mem.h
Normal file
18
include/mem/mem.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <types.h>
|
||||
|
||||
#define MEM_BLOCK_LIST_SIZE 4096
|
||||
#define MEM_BLOCK_INCREASE_SIZE 4
|
||||
|
||||
struct mem_block {
|
||||
bool is_used;
|
||||
bool is_end;
|
||||
usize size;
|
||||
usize addr;
|
||||
};
|
||||
|
||||
void* malloc(usize size);
|
||||
void mem_populate_blocks(usize starting_addr);
|
||||
bool mem_test_mm();
|
|
@ -5,8 +5,6 @@
|
|||
#define LOW_16(address) (u16)((address) & 0xFFFF)
|
||||
#define HIGH_16(address) (u16)(((address) >> 16) & 0xFFFF)
|
||||
|
||||
void* malloc(usize amount);
|
||||
|
||||
int rand(void);
|
||||
void srand(usize seed);
|
||||
char* itoa(int res);
|
||||
|
|
Loading…
Reference in a new issue