diff --git a/headers/alloc.h b/headers/alloc.h index fac395a..8a65e67 100644 --- a/headers/alloc.h +++ b/headers/alloc.h @@ -8,12 +8,10 @@ // Remove this and replace it with header // for debugging purposes -/* #include */ -#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); \ No newline at end of file +size_t ksize(void *virt_addr); +size_t vsize(void *virt_addr); diff --git a/headers/debug.h b/headers/debug.h index 6b23d44..e9aad60 100644 --- a/headers/debug.h +++ b/headers/debug.h @@ -1,9 +1,18 @@ #pragma once +#include "kpanic.h" #include "kprintf.h" #include -#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; diff --git a/headers/kpanic.h b/headers/kpanic.h index 3318caf..8fbca94 100644 --- a/headers/kpanic.h +++ b/headers/kpanic.h @@ -1,3 +1,3 @@ #pragma once -void kpanic(const char *format, ...); \ No newline at end of file +void kpanic(const char *format, ...); diff --git a/headers/memory.h b/headers/memory.h index 30294c7..2d105a9 100644 --- a/headers/memory.h +++ b/headers/memory.h @@ -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); diff --git a/src/kernel.c b/src/kernel.c index fc1a7ab..f0ace45 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -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(); } diff --git a/src/kpanic.c b/src/kpanic.c index 6bf7d58..a75e0eb 100644 --- a/src/kpanic.c +++ b/src/kpanic.c @@ -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"); */ diff --git a/src/memory/frame.c b/src/memory/frame.c index 2277254..1c0b4bf 100644 --- a/src/memory/frame.c +++ b/src/memory/frame.c @@ -2,11 +2,12 @@ #include #include +#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"); diff --git a/src/memory/memory.c b/src/memory/memory.c index 0f4f0d4..9a4fe0f 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -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; } diff --git a/src/memory/page.c b/src/memory/page.c index 5f63d7b..5a9427c 100644 --- a/src/memory/page.c +++ b/src/memory/page.c @@ -2,6 +2,7 @@ #include #include +#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; } diff --git a/src/memory/phys/allocator.c b/src/memory/phys/allocator.c index 60b609f..b03dd0b 100644 --- a/src/memory/phys/allocator.c +++ b/src/memory/phys/allocator.c @@ -1,6 +1,7 @@ #include "alloc.h" #include "kprintf.h" #include "memory.h" +#include 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) { diff --git a/src/memory/phys/info.c b/src/memory/phys/info.c index 68ba687..ab817c3 100644 --- a/src/memory/phys/info.c +++ b/src/memory/phys/info.c @@ -1,5 +1,6 @@ #include "alloc.h" #include "kprintf.h" +#include // 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; diff --git a/src/memory/phys/kfree.c b/src/memory/phys/kfree.c index 1e6ecfd..9645baf 100644 --- a/src/memory/phys/kfree.c +++ b/src/memory/phys/kfree.c @@ -1,6 +1,7 @@ #include "alloc.h" #include "kprintf.h" #include "memory.h" +#include 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); diff --git a/src/memory/phys/kmalloc.c b/src/memory/phys/kmalloc.c index b8b921d..f933807 100644 --- a/src/memory/phys/kmalloc.c +++ b/src/memory/phys/kmalloc.c @@ -1,11 +1,13 @@ #include "alloc.h" +#include "debug.h" #include "kprintf.h" +#include /* * 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 diff --git a/src/memory/phys/krealloc.c b/src/memory/phys/krealloc.c index 3594f4a..647de68 100644 --- a/src/memory/phys/krealloc.c +++ b/src/memory/phys/krealloc.c @@ -1,9 +1,10 @@ #include "alloc.h" #include "string.h" +#include // 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); diff --git a/src/memory/phys/ksize.c b/src/memory/phys/ksize.c index 200ab61..952d993 100644 --- a/src/memory/phys/ksize.c +++ b/src/memory/phys/ksize.c @@ -1,8 +1,9 @@ #include "alloc.h" +#include -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; -} \ No newline at end of file +} diff --git a/src/memory/virt/allocator.c b/src/memory/virt/allocator.c index 6c83b78..10592c8 100644 --- a/src/memory/virt/allocator.c +++ b/src/memory/virt/allocator.c @@ -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; diff --git a/src/memory/virt/info.c b/src/memory/virt/info.c index d2811dc..34c496d 100644 --- a/src/memory/virt/info.c +++ b/src/memory/virt/info.c @@ -1,5 +1,6 @@ #include "alloc.h" #include "kprintf.h" +#include // 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; diff --git a/src/memory/virt/vfree.c b/src/memory/virt/vfree.c index 695d119..b712202 100644 --- a/src/memory/virt/vfree.c +++ b/src/memory/virt/vfree.c @@ -1,6 +1,7 @@ #include "alloc.h" #include "kprintf.h" #include "memory.h" +#include 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); diff --git a/src/memory/virt/vmalloc.c b/src/memory/virt/vmalloc.c index 2eba13b..2dadecc 100644 --- a/src/memory/virt/vmalloc.c +++ b/src/memory/virt/vmalloc.c @@ -1,17 +1,21 @@ #include "alloc.h" +#include "debug.h" #include "kprintf.h" +#include -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 diff --git a/src/memory/virt/vrealloc.c b/src/memory/virt/vrealloc.c index bf3d379..61247fd 100644 --- a/src/memory/virt/vrealloc.c +++ b/src/memory/virt/vrealloc.c @@ -1,9 +1,10 @@ #include "alloc.h" #include "string.h" +#include // 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); diff --git a/src/memory/virt/vsize.c b/src/memory/virt/vsize.c index d2bfb13..5a5d3ba 100644 --- a/src/memory/virt/vsize.c +++ b/src/memory/virt/vsize.c @@ -1,8 +1,9 @@ #include "alloc.h" +#include -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; -} \ No newline at end of file +}