Skip to content

Commit

Permalink
+ | Kmalloc on point
Browse files Browse the repository at this point in the history
  • Loading branch information
BolvicBolvicovic committed Sep 11, 2024
1 parent c684644 commit bb3e4a9
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 25 deletions.
2 changes: 1 addition & 1 deletion kernel/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions memory/pmm/pmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "../../lib/stdlib/stdlib.h"
#include "../../lib/string/string.h"
#include "../../lib/stdio/stdio.h"
#include <stdint.h>
#include <stddef.h>

Expand Down
49 changes: 45 additions & 4 deletions memory/vmm/kmalloc.c
Original file line number Diff line number Diff line change
@@ -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");
}
35 changes: 18 additions & 17 deletions memory/vmm/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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;
Expand All @@ -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])) {
Expand All @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions memory/vmm/vmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit bb3e4a9

Please sign in to comment.