wip: memory change

This commit is contained in:
0x35c 2024-10-18 14:45:37 +02:00
parent 9e85807a09
commit 7128f2640a
21 changed files with 121 additions and 76 deletions

View File

@ -8,12 +8,10 @@
// Remove this and replace it with <assert.h> header
// for debugging purposes
/* #include <assert.h> */
#define assert(bool)
// BPZ = Blocks Per Zone, which is the max
// number of blocks for a new zone
enum { BPZ = 128, PAGES_TINY = 16, PAGES_SMALL = 64, MEM_ALIGN = 8 };
enum { BPZ = 128, PAGES_TINY = 16, PAGES_SMALL = 64, MEM_ALIGN = 4 };
typedef enum { TINY, SMALL, LARGE } block_type_t;
@ -34,7 +32,6 @@ typedef enum { TINY, SMALL, LARGE } block_type_t;
* available blocks (Block *free in struct Zone)
*/
typedef struct Block {
void *ptr;
size_t size;
size_t sub_size;
@ -54,12 +51,12 @@ typedef struct Block {
* in_use
*/
typedef struct Zone {
Block *free;
Block *used;
size_t size;
struct Zone *prev;
struct Zone *next;
block_type_t type;
Block *free;
Block *used;
} Zone;
/* Linked list to store all the zones (pages) mapped.
@ -89,5 +86,5 @@ void vfree(void *ptr);
void *vrealloc(void *ptr, size_t size);
void show_kalloc_mem(void);
void show_valloc_mem(void);
size_t ksize(void* virt_addr);
size_t vsize(void* virt_addr);
size_t ksize(void *virt_addr);
size_t vsize(void *virt_addr);

View File

@ -1,9 +1,18 @@
#pragma once
#include "kpanic.h"
#include "kprintf.h"
#include <stdint.h>
#define PRINT_VAR(var) kprintf("%s: %d\n", #var, var)
#define PRINT_PTR(X) kprintf("%s: %p\n", #X, X)
#define PRINT_INT(X) kprintf("%s: %d\n", #X, X)
#define assert(X) \
do { \
if (!(X)) { \
kpanic("ASSERT_FAIL %s:%u %s\n", __FILE__, __LINE__, \
#X); \
} \
} while (0)
struct function_entry {
uint32_t addr;

View File

@ -1,3 +1,3 @@
#pragma once
void kpanic(const char *format, ...);
void kpanic(const char *format, ...);

View File

@ -8,7 +8,7 @@
#define ACCESSED (1 << 4)
#define INIT_FLAGS (PRESENT | RW | SUPERVISOR)
#define PAGE_SIZE 4096
#define KERN_START 0xC0000000
#define HEAP_END 0xC0000000
void init_memory(void);
void *alloc_frames(size_t size);

View File

@ -31,13 +31,13 @@ void kernel_main(void)
init_idt();
init_memory();
load_drivers();
memset((void *)0x10001, 'a', 10);
kprintf(KERN_ALERT
"I see no way to confuse an array of 256 seg:off pairs with a "
"complex 8*unknown quantity -byte descriptor table. -- Troy "
"Martin 03:50, 22 March 2009 (UTC)\n");
/* vmalloc(10); */
/* while (!vmalloc(10)) */
/* ; */
/* kprintf("%p\n", vmalloc(10)); */
int i = 0;
while (vmalloc(10))
kprintf("%d\n", i++);
shell_init();
}

View File

@ -1,9 +1,13 @@
#include "alloc.h"
#include "debug.h"
#include "keyboard.h"
#include "kprintf.h"
#include "memory.h"
#include "power.h"
#include "terminal.h"
extern uint32_t page_table1[1024];
void kpanic(const char *format, ...)
{
va_list va;
@ -16,6 +20,9 @@ void kpanic(const char *format, ...)
uint32_t faulting_address;
__asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address));
kprintf("fault at address: %p\n", faulting_address);
/* for (int i = 16; i < 32; i++) */
/* kprintf("%p\n", page_table1[i]); */
show_valloc_mem();
/* kprintf("\n\n"); */
/* print_stack(); */
/* kprintf("\n\n"); */

View File

@ -2,11 +2,12 @@
#include <stddef.h>
#include <stdint.h>
#include "debug.h"
#include "kprintf.h"
#include "memory.h"
#include "utils.h"
#define MAX_FRAMES (0xC0000000 / PAGE_SIZE)
#define MAX_FRAMES (HEAP_END / PAGE_SIZE)
static uint8_t frame_table[MAX_FRAMES];
static uint32_t remaining_frames = MAX_FRAMES;
@ -37,16 +38,19 @@ void *alloc_frames(size_t size)
MAX_FRAMES);
return NULL;
}
for (size_t j = 0; j < nb_frames; j++)
for (size_t j = 0; j < nb_frames; j++) {
assert(j + i < MAX_FRAMES);
frame_table[j + i] = 1;
}
assert(remaining_frames >= nb_frames);
remaining_frames -= nb_frames;
return (void *)(i * PAGE_SIZE);
return (void *)(i * PAGE_SIZE); // WARNING: address translation cramptés
}
int free_frames(void *frame_ptr, size_t size)
{
const uint32_t nb_frames = CEIL(size, PAGE_SIZE);
const uint32_t start = (uint32_t)frame_ptr / PAGE_SIZE;
const uint32_t start = (uint32_t)(frame_ptr + HEAP_END) / PAGE_SIZE;
if (start > MAX_FRAMES) {
kprintf(KERN_WARNING "Address out of range\n");

View File

@ -1,4 +1,5 @@
#include "memory.h"
#include "debug.h"
#include "kprintf.h"
#include "string.h"
@ -7,13 +8,13 @@
extern uint32_t boot_page_directory;
uint32_t *page_directory = &boot_page_directory;
uint32_t page_table1[1024] __attribute__((aligned(4096)));
uint32_t page_table_entries[1024] __attribute__((aligned(4096)));
void init_memory(void)
{
assert(page_directory);
for (int16_t i = 0; i < 0x300; i++)
page_directory[i] = 0x02;
for (int16_t i = 0; i < 1024; i++)
page_table1[i] = i << 12 | 0x03;
page_directory[0] = (uint32_t)page_table1 | 0x03;
page_table1[i] = (i << 12) | 0x03;
page_directory[0] = ((uint32_t)page_table1 - HEAP_END) | 0x03;
}

View File

@ -2,6 +2,7 @@
#include <stddef.h>
#include <stdint.h>
#include "debug.h"
#include "kprintf.h"
#include "memory.h"
#include "utils.h"
@ -9,14 +10,13 @@
#define PT_SIZE 1024
#define MAX_TLB_ENTRIES 32
extern uint32_t page_table_entries[PT_SIZE];
extern uint32_t page_table1[PT_SIZE];
static int16_t find_next_block(size_t nb_pages)
{
for (uint16_t i = 1; i < PT_SIZE; i++) {
for (uint16_t i = 1; i < PT_SIZE - 1; i++) {
uint16_t j;
for (j = 0;
page_table_entries[i + j] >> 12 == 0 && j < nb_pages;
for (j = 0; page_table1[i + j] >> 12 == i + j && j < nb_pages;
j++)
;
if (j == nb_pages)
@ -39,14 +39,15 @@ void *alloc_pages(size_t size)
void *frame = alloc_frames(PAGE_SIZE);
if (!frame) {
for (size_t j = index; j < i; j++)
free_frames(
(void *)(page_table_entries[j] >> 12),
PAGE_SIZE);
free_frames((void *)(page_table1[j] >> 12),
PAGE_SIZE);
return NULL;
}
page_table_entries[i] = (uint32_t)frame << 12 | INIT_FLAGS;
assert(page_table1[i] >> 12 == i);
page_table1[i] = (uint32_t)frame << 12 | INIT_FLAGS;
}
return (void *)(index * PAGE_SIZE);
PRINT_PTR(page_table1[index]);
return (void *)(page_table1[index] >> 12);
}
int free_pages(void *page_ptr, size_t size)
@ -65,8 +66,8 @@ int free_pages(void *page_ptr, size_t size)
return -1;
}
for (size_t i = page_index; i < page_index + nb_pages; i++) {
free_frames((void *)(page_table_entries[i] >> 12), PAGE_SIZE);
page_table_entries[i] = INIT_FLAGS;
free_frames((void *)(page_table1[i] >> 12), PAGE_SIZE);
page_table1[i] = i << 12 | INIT_FLAGS;
}
return 0;
}

View File

@ -1,6 +1,7 @@
#include "alloc.h"
#include "kprintf.h"
#include "memory.h"
#include <stdint.h>
Zone *kzones[3];
@ -14,15 +15,15 @@ static void add_zone(Zone *zone, block_type_t type)
kzones[type] = zone;
}
static void new_block(Zone *zone, size_t zone_size)
static void new_block(Zone *zone, uint32_t zone_size)
{
Block *new_block = (Block *)align_mem((size_t)zone + sizeof(Zone));
Block *new_block = (Block *)align_mem((uint32_t)zone + sizeof(Zone));
// Metadata
new_block->in_use = false;
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
new_block->sub_size = new_block->size;
new_block->ptr = (Block *)((size_t)new_block + sizeof(Block));
new_block->ptr = (Block *)((uint32_t)new_block + sizeof(Block));
new_block->zone = zone;
// Init future linked lists
@ -42,7 +43,7 @@ static void new_block(Zone *zone, size_t zone_size)
zone->free = new_block;
}
int new_kzone(block_type_t type, size_t size)
int new_kzone(block_type_t type, uint32_t size)
{
void *heap = alloc_frames(size);
if (heap == NULL) {

View File

@ -1,5 +1,6 @@
#include "alloc.h"
#include "kprintf.h"
#include <stdint.h>
// FULL_INFO is to display (or not) both used and unused blocks
#define FULL_INFO 1
@ -7,7 +8,7 @@
void show_kalloc_mem(void)
{
char *const kzones_name[3] = {"TINY", "SMALL", "LARGE"};
size_t total_size = 0;
uint32_t total_size = 0;
for (block_type_t type = 0; type < 3; ++type) {
int count = 0;
@ -21,7 +22,7 @@ void show_kalloc_mem(void)
for (Block *block_it = zone_it->free; block_it != NULL;
block_it = block_it->next_free) {
kprintf("%p - %p : %u bytes\n", block_it->ptr,
(size_t)block_it->ptr +
(uint32_t)block_it->ptr +
block_it->sub_size + sizeof(Block),
block_it->sub_size);
}
@ -35,7 +36,7 @@ void show_kalloc_mem(void)
for (Block *block_it = zone_it->used; block_it != NULL;
block_it = block_it->next_used) {
kprintf("%p - %p : %u bytes\n", block_it->ptr,
(size_t)block_it->ptr +
(uint32_t)block_it->ptr +
block_it->sub_size + sizeof(Block),
block_it->sub_size);
total_size += block_it->sub_size;

View File

@ -1,6 +1,7 @@
#include "alloc.h"
#include "kprintf.h"
#include "memory.h"
#include <stdint.h>
static void remove_used(Block *to_free)
{
@ -97,7 +98,7 @@ void kfree(void *ptr)
{
if (ptr == NULL)
return;
Block *to_free = (Block *)((size_t)ptr - sizeof(Block));
Block *to_free = (Block *)((uint32_t)ptr - sizeof(Block));
Block *to_merge = NULL;
to_free->in_use = false;
remove_used(to_free);

View File

@ -1,11 +1,13 @@
#include "alloc.h"
#include "debug.h"
#include "kprintf.h"
#include <stdint.h>
/*
* Find first available (not in_use) block
* in a zone matching the size we need
*/
static Block *find_block(Zone *head, size_t size)
static Block *find_block(Zone *head, uint32_t size)
{
for (Zone *zone_it = head; zone_it != NULL; zone_it = zone_it->next) {
for (Block *block_it = zone_it->free; block_it != NULL;
@ -42,17 +44,17 @@ static Block *find_block(Zone *head, size_t size)
* We can see that it now has its own metadata and available
* data and it points towards [6]
*/
static void frag_block(Zone *zone, Block *old_block, size_t size)
static void frag_block(Zone *zone, Block *old_block, uint32_t size)
{
Block *new_block = (Block *)align_mem((size_t)old_block + size);
Block *new_block = (Block *)align_mem((uint32_t)old_block + size);
assert(!(new_block >=
(Block *)((size_t)zone + get_zone_size(zone->type))));
(Block *)((uint32_t)zone + get_zone_size(zone->type))));
// Newly created block metadata
new_block->size = old_block->size - size;
new_block->sub_size = new_block->size;
new_block->in_use = false;
new_block->ptr = (void *)((size_t)new_block + sizeof(Block));
new_block->ptr = (void *)((uint32_t)new_block + sizeof(Block));
new_block->zone = zone;
new_block->prev = old_block;
@ -114,7 +116,7 @@ static void save_block(Zone *head, Block *block, Zone *zone)
*
* ptr: returns the aligned pointer of the block (after the metadata)
*/
void *kmalloc(size_t size)
void *kmalloc(uint32_t size)
{
void *ptr = NULL;
@ -130,7 +132,7 @@ void *kmalloc(size_t size)
// Find an available block in a zone of type "type"
Block *available = find_block(head, size);
if (available == NULL) {
size_t full_size;
uint32_t full_size;
if (type == LARGE)
full_size = size + sizeof(Block) + sizeof(Zone);
else

View File

@ -1,9 +1,10 @@
#include "alloc.h"
#include "string.h"
#include <stdint.h>
// Prototype for kfree and kmalloc
void kfree(void *ptr);
void *kmalloc(size_t size);
void *kmalloc(uint32_t size);
/*
* ptr: block to resize (undefined behavior if invalid)
@ -17,12 +18,12 @@ void *kmalloc(size_t size);
*
* ptr: returns the aligned pointer of the kreallocated block
*/
void *krealloc(void *ptr, size_t size)
void *krealloc(void *ptr, uint32_t size)
{
void *new_ptr = NULL;
if (ptr == NULL)
return NULL;
Block *block = (Block *)((size_t)ptr - sizeof(Block));
Block *block = (Block *)((uint32_t)ptr - sizeof(Block));
if (block->size >= size) {
block->sub_size = size;
return (ptr);

View File

@ -1,8 +1,9 @@
#include "alloc.h"
#include <stdint.h>
size_t ksize(void *ptr)
uint32_t ksize(void *ptr)
{
Block *meta_data = (Block *)((size_t)ptr - sizeof(Block));
Block *meta_data = (Block *)((uint32_t)ptr - sizeof(Block));
return meta_data->sub_size;
}
}

View File

@ -1,4 +1,6 @@
#include "alloc.h"
#include "debug.h"
#include "kpanic.h"
#include "kprintf.h"
#include "memory.h"
@ -14,15 +16,15 @@ static void add_zone(Zone *zone, block_type_t type)
vzones[type] = zone;
}
static void new_block(Zone *zone, size_t zone_size)
static void new_block(Zone *zone, uint32_t zone_size)
{
Block *new_block = (Block *)align_mem((size_t)zone + sizeof(Zone));
Block *new_block = (Block *)align_mem((uint32_t)zone + sizeof(Zone));
// Metadata
new_block->in_use = false;
new_block->size = zone_size - sizeof(Zone) - sizeof(Block);
new_block->sub_size = new_block->size;
new_block->ptr = (Block *)((size_t)new_block + sizeof(Block));
new_block->ptr = (Block *)((uint32_t)new_block + sizeof(Block));
new_block->zone = zone;
// Init future linked lists
@ -39,16 +41,22 @@ static void new_block(Zone *zone, size_t zone_size)
new_block->next = zone->free;
new_block->next_free = zone->free;
}
kprintf("before zone: %p zone->free: %p new_block: %p\n", zone,
zone->free, new_block);
zone->free = new_block;
kprintf("after zone: %p zone->free: %p new_block: %p\n", zone,
zone->free, new_block);
assert(zone->free == new_block);
}
int new_vzone(block_type_t type, size_t size)
int new_vzone(block_type_t type, uint32_t size)
{
void *heap = alloc_pages(size);
if (heap == NULL) {
kprintf(KERN_ERR "error: alloc_pages failed\n");
return (-1);
}
PRINT_PTR(heap);
Zone *zone = (Zone *)heap;
zone->type = type;

View File

@ -1,5 +1,6 @@
#include "alloc.h"
#include "kprintf.h"
#include <stdint.h>
// FULL_INFO is to display (or not) both used and unused blocks
#define FULL_INFO 1
@ -7,7 +8,7 @@
void show_valloc_mem(void)
{
char *const vzones_name[3] = {"TINY", "SMALL", "LARGE"};
size_t total_size = 0;
uint32_t total_size = 0;
for (block_type_t type = 0; type < 3; ++type) {
int count = 0;
@ -18,10 +19,11 @@ void show_valloc_mem(void)
kprintf("---------- AVAILABLE %s [n°%d - %p] "
"----------\n",
vzones_name[type], count, zone_it);
int i = 0;
for (Block *block_it = zone_it->free; block_it != NULL;
block_it = block_it->next_free) {
kprintf("%p - %p : %u bytes\n", block_it->ptr,
(size_t)block_it->ptr +
(uint32_t)block_it->ptr +
block_it->sub_size + sizeof(Block),
block_it->sub_size);
}
@ -34,8 +36,10 @@ void show_valloc_mem(void)
vzones_name[type], count, zone_it);
for (Block *block_it = zone_it->used; block_it != NULL;
block_it = block_it->next_used) {
/* i++; */
/* if (i < 10) */
kprintf("%p - %p : %u bytes\n", block_it->ptr,
(size_t)block_it->ptr +
(uint32_t)block_it->ptr +
block_it->sub_size + sizeof(Block),
block_it->sub_size);
total_size += block_it->sub_size;

View File

@ -1,6 +1,7 @@
#include "alloc.h"
#include "kprintf.h"
#include "memory.h"
#include <stdint.h>
static void remove_used(Block *to_free)
{
@ -97,7 +98,7 @@ void vfree(void *ptr)
{
if (ptr == NULL)
return;
Block *to_free = (Block *)((size_t)ptr - sizeof(Block));
Block *to_free = (Block *)((uint32_t)ptr - sizeof(Block));
Block *to_merge = NULL;
to_free->in_use = false;
remove_used(to_free);

View File

@ -1,17 +1,21 @@
#include "alloc.h"
#include "debug.h"
#include "kprintf.h"
#include <stdint.h>
int new_zone(block_type_t type, size_t size);
int new_zone(block_type_t type, uint32_t size);
/*
* Find first available (not in_use) block
* in a zone matching the size we need
*/
static Block *find_block(Zone *head, size_t size)
static Block *find_block(Zone *head, uint32_t size)
{
for (Zone *zone_it = head; zone_it != NULL; zone_it = zone_it->next) {
assert(zone_it->free);
for (Block *block_it = zone_it->free; block_it != NULL;
block_it = block_it->next_free) {
/* PRINT_PTR(block_it); */
assert(!block_it->in_use);
if (size <= block_it->size) {
assert(block_it->zone == zone_it);
@ -44,17 +48,17 @@ static Block *find_block(Zone *head, size_t size)
* We can see that it now has its own metadata and available
* data and it points towards [6]
*/
static void frag_block(Zone *zone, Block *old_block, size_t size)
static void frag_block(Zone *zone, Block *old_block, uint32_t size)
{
Block *new_block = (Block *)align_mem((size_t)old_block + size);
Block *new_block = (Block *)align_mem((uint32_t)old_block + size);
assert(!(new_block >=
(Block *)((size_t)zone + get_zone_size(zone->type))));
(Block *)((uint32_t)zone + get_zone_size(zone->type))));
// Newly created block metadata
new_block->size = old_block->size - size;
new_block->sub_size = new_block->size;
new_block->in_use = false;
new_block->ptr = (void *)((size_t)new_block + sizeof(Block));
new_block->ptr = (void *)((uint32_t)new_block + sizeof(Block));
new_block->zone = zone;
new_block->prev = old_block;
@ -116,7 +120,7 @@ static void save_block(Zone *head, Block *block, Zone *zone)
*
* ptr: returns the aligned pointer of the block (after the metadata)
*/
void *vmalloc(size_t size)
void *vmalloc(uint32_t size)
{
void *ptr = NULL;
@ -132,7 +136,7 @@ void *vmalloc(size_t size)
// Find an available block in a zone of type "type"
Block *available = find_block(head, size);
if (available == NULL) {
size_t full_size;
uint32_t full_size;
if (type == LARGE)
full_size = size + sizeof(Block) + sizeof(Zone);
else

View File

@ -1,9 +1,10 @@
#include "alloc.h"
#include "string.h"
#include <stdint.h>
// Prototype for kfree and vmalloc
void kfree(void *ptr);
void *vmalloc(size_t size);
void *vmalloc(uint32_t size);
/*
* ptr: block to resize (undefined behavior if invalid)
@ -17,12 +18,12 @@ void *vmalloc(size_t size);
*
* ptr: returns the aligned pointer of the vreallocated block
*/
void *vrealloc(void *ptr, size_t size)
void *vrealloc(void *ptr, uint32_t size)
{
void *new_ptr = NULL;
if (ptr == NULL)
return NULL;
Block *block = (Block *)((size_t)ptr - sizeof(Block));
Block *block = (Block *)((uint32_t)ptr - sizeof(Block));
if (block->size >= size) {
block->sub_size = size;
return (ptr);

View File

@ -1,8 +1,9 @@
#include "alloc.h"
#include <stdint.h>
size_t vsize(void *ptr)
uint32_t vsize(void *ptr)
{
Block *meta_data = (Block *)((size_t)ptr - sizeof(Block));
Block *meta_data = (Block *)((uint32_t)ptr - sizeof(Block));
return meta_data->sub_size;
}
}