add terrible, janky memory manager

This commit is contained in:
hippoz 2021-08-23 14:05:04 +03:00
parent 624ffbe738
commit 4c6c4a0150
Signed by untrusted user who does not match committer: hippoz
GPG key ID: 7C52899193467641
5 changed files with 123 additions and 4 deletions

View file

@ -3,7 +3,7 @@ ISO := hhhos.iso
CC = x86_64-elf-gcc
NASM = nasm
# User controllable CFLAGS.
CFLAGS = -Wall -Wextra -O2 -pipe
NASMFLAGS = -felf64

View file

@ -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
View 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
View 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();

View file

@ -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);