diff --git a/kernel/kernel.c b/kernel/kernel.c index 174e098..29bd618 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -62,6 +62,6 @@ void kernel_main(uint32_t magic, uint32_t addr) { void* test = kmalloc(0x1001); void* test2 = kmalloc(1); kfree(test); - void* test3 = kmalloc(1); + void* test3 = kmalloc(0x1001); printf("%p | %p | %p\n", test, test2, test3); } diff --git a/memory/pmm/pmm.h b/memory/pmm/pmm.h index cc5db47..5df6f70 100644 --- a/memory/pmm/pmm.h +++ b/memory/pmm/pmm.h @@ -3,6 +3,7 @@ #include "../../lib/stdlib/stdlib.h" #include "../../lib/string/string.h" +#include "../../lib/stdio/stdio.h" #include #include diff --git a/memory/vmm/kmalloc.c b/memory/vmm/kmalloc.c index 42c21ee..50b635c 100644 --- a/memory/vmm/kmalloc.c +++ b/memory/vmm/kmalloc.c @@ -1,12 +1,53 @@ #include "vmm.h" -void* kmalloc(size_t size) { - void* block_virt_addr = vmm_alloc_blocks(size); +#define MAX_ALLOC_SAME_TIME 0x1000 + +typedef struct { + uint32_t virt_addr; + uint32_t nb_blocks : 31; + uint16_t free : 1; +} __attribute__((__packed__)) freemap_t; +static freemap_t memory_map[MAX_ALLOC_SAME_TIME] = {0}; + +void* kmalloc(size_t size) { + uint32_t total_pages_needed = size / PAGE_SIZE + (size % PAGE_SIZE ? 1 : 0); + size_t i; + size_t j; + for (j = 0, i = 0; i < MAX_ALLOC_SAME_TIME; i++) { + if (!memory_map[i].free) { + j++; + if (!memory_map[i].nb_blocks && !memory_map[i].virt_addr) break; + } + if (memory_map[i].free && memory_map[i].nb_blocks == total_pages_needed) { + memory_map[i].free = 1; + return (void*)memory_map[i].virt_addr; + } + } + if (i == MAX_ALLOC_SAME_TIME && j == MAX_ALLOC_SAME_TIME) return NULL; + void* block_virt_addr = vmm_alloc_blocks(total_pages_needed); + if (i == MAX_ALLOC_SAME_TIME) { + for (i = 0; i < MAX_ALLOC_SAME_TIME; i++) { + if (memory_map[i].free) { + vmm_free_blocks(memory_map[i].virt_addr, memory_map[i].nb_blocks); + break; + } + } + } + memory_map[i].virt_addr = (uint32_t)block_virt_addr; + memory_map[i].nb_blocks = total_pages_needed; + memory_map[i].free = 0; return block_virt_addr; } -void kfree(uint32_t virt_addr) { - vmm_free_block(virt_addr); +void kfree(void* virt_addr) { + for (size_t i = 0; i < DTABLE_ADDR_SPACE_SIZE / 2; i++) { + if (!memory_map[i].free && !memory_map[i].nb_blocks && !memory_map[i].virt_addr) break; + if (memory_map[i].virt_addr == (uint32_t)virt_addr) { + memory_map[i].free = 1; + return; + } + } + printf("ERROR: Invalid free\n"); } diff --git a/memory/vmm/vmm.c b/memory/vmm/vmm.c index fb35b31..58cbf80 100644 --- a/memory/vmm/vmm.c +++ b/memory/vmm/vmm.c @@ -61,11 +61,11 @@ uint32_t build_virt_addr(uint32_t pd_index, uint32_t pt_index) { return (pd_index << 22) | (pt_index << 12); } -uint32_t* vmm_find_next_free() { - for (size_t i = 0; i < 1024; i++) { +uint32_t vmm_find_next_free() { + for (size_t i = 0; i < PAGES_PER_DIR; i++) { if (pd_entry_is_present(_current_dir->m_entries[i])) { pt_entry* entry = (pt_entry*)pd_entry_pfn(_current_dir->m_entries[i]); - for (size_t j = 0; j < 1024; j++) { + for (size_t j = 0; j < PAGES_PER_TABLE; j++) { if (!pt_entry_is_present(entry[j])) { return build_virt_addr(i, j); } @@ -74,7 +74,7 @@ uint32_t* vmm_find_next_free() { p_table* new_table = (p_table*)pmm_alloc_block(); if (new_table == 0) return NULL; memset(new_table, 0, sizeof(p_table)); - for (size_t i = 0; i < 1024; i++) { + for (size_t i = 0; i < PAGES_PER_TABLE; i++) { pt_entry new_page = 0; pt_entry* new_page_p = &new_page; if (!vmm_alloc_page(new_page_p)) continue; @@ -90,14 +90,14 @@ uint32_t* vmm_find_next_free() { return NULL; } -uint32_t* vmm_find_next_free_s(size_t nb_blocks) { +uint32_t vmm_find_next_free_s(size_t nb_blocks) { if (nb_blocks == 1) return vmm_find_next_free(); - for (size_t i = 0; i < 1024; i++) { + for (size_t i = 0; i < PAGES_PER_DIR; i++) { if (pd_entry_is_present(_current_dir->m_entries[i])) { pt_entry* entry = (pt_entry*)pd_entry_pfn(_current_dir->m_entries[i]); - for (size_t j = 0; j < 1024; j++) { + for (size_t j = 0; j < PAGES_PER_TABLE; j++) { if (!pt_entry_is_present(entry[j])) { - for (size_t k = 1; k < 1024 - j; k++) { + for (size_t k = 1; k < PAGES_PER_TABLE - j; k++) { if (!pt_entry_is_present(entry[j + k]) && k + 1 >= nb_blocks) return build_virt_addr(i, j); else if (pt_entry_is_present(entry[j + k])) { @@ -110,7 +110,7 @@ uint32_t* vmm_find_next_free_s(size_t nb_blocks) { p_table* new_table = (p_table*)pmm_alloc_block(); if (new_table == 0) return NULL; memset(new_table, 0, sizeof(p_table)); - for (size_t i = 0; i < 1024; i++) { + for (size_t i = 0; i < PAGES_PER_TABLE; i++) { pt_entry new_page = 0; pt_entry* new_page_p = &new_page; if (!vmm_alloc_page(new_page_p)) continue; @@ -126,24 +126,25 @@ uint32_t* vmm_find_next_free_s(size_t nb_blocks) { return NULL; } -void* vmm_alloc_blocks(size_t size) { - uint32_t total_pages_needed = size / PAGE_SIZE + (size % PAGE_SIZE ? 1 : 0); - uint32_t virtual_addr = vmm_find_next_free_s(total_pages_needed); +void* vmm_alloc_blocks(size_t nb_blocks) { + uint32_t virtual_addr = (uint32_t)vmm_find_next_free_s(nb_blocks); if (virtual_addr == NULL) return NULL; uint32_t pd_index = PAGE_DIR_INDEX(virtual_addr); uint32_t pt_index = PAGE_TAB_INDEX(virtual_addr); - pt_entry* page_table = pd_entry_pfn(_current_dir->m_entries[pd_index]); - for (size_t i = 0; i/PAGE_SIZE < total_pages_needed; i+=PAGE_SIZE) { + pt_entry* page_table = (pt_entry*)pd_entry_pfn(_current_dir->m_entries[pd_index]); + for (size_t i = 0; i/PAGE_SIZE < nb_blocks; i+=PAGE_SIZE) { pt_entry_add_attrib(page_table + i + pt_index, I86_PTE_PRESENT | I86_PTE_WRITABLE); } return (void*)virtual_addr; } -void vmm_free_block(uint32_t virtual_addr) { +void vmm_free_blocks(uint32_t virtual_addr, uint32_t nb_blocks) { uint32_t pd_index = PAGE_DIR_INDEX(virtual_addr); uint32_t pt_index = PAGE_TAB_INDEX(virtual_addr); - pt_entry* page_table = pd_entry_pfn(_current_dir->m_entries[pd_index]); - vmm_free_page(page_table + pt_index * PAGE_SIZE); + pt_entry* page_table = (pt_entry*)pd_entry_pfn(_current_dir->m_entries[pd_index]); + for (size_t i = 0; i/PAGE_SIZE < nb_blocks; i+=PAGE_SIZE) { + pt_entry_del_attrib(page_table + i + pt_index, I86_PTE_PRESENT | I86_PTE_WRITABLE); + } } extern uint32_t start_kernel_virt; diff --git a/memory/vmm/vmm.h b/memory/vmm/vmm.h index 7c2a845..67b01ee 100644 --- a/memory/vmm/vmm.h +++ b/memory/vmm/vmm.h @@ -25,9 +25,9 @@ typedef struct { } p_dir; void vmm_init(); -void* vmm_alloc_blocks(size_t size); // Size en bytes -void vmm_free_block(uint32_t virtual_addr); +void* vmm_alloc_blocks(size_t size); +void vmm_free_blocks(uint32_t virtual_addr, uint32_t nb_blocks); void* kmalloc(size_t size); -void kfree(uint32_t virt_addr); +void kfree(void* virt_addr); #endif