aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/mm
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/mm')
-rw-r--r--kernel/mm/pmm.cpp114
-rw-r--r--kernel/mm/vmm.cpp2
2 files changed, 93 insertions, 23 deletions
diff --git a/kernel/mm/pmm.cpp b/kernel/mm/pmm.cpp
index 1234d8a..fb92767 100644
--- a/kernel/mm/pmm.cpp
+++ b/kernel/mm/pmm.cpp
@@ -2,43 +2,111 @@
#include <kernel.h>
#include <stdio.h>
-// Finds biggest memory chunk to place the bitmap
-static int find_biggest_chunk(limine_memmap_response* memmap) {
- int biggestmem = 0;
- int biggestindex = 0;
- for (size_t i = 0; i < memmap->entry_count; i++) {
- if (memmap->entries[i]->length > biggestmem) {
- biggestmem = memmap->entries[i]->length;
- biggestindex = i;
- }
- }
+#define BIT_WIDTH 64
- return biggestindex;
-}
+Bitmap* head;
-static MemRegion** setup_meminfo(limine_memmap_response* memmap, int chunk) {
- const uint64_t* basemem = (uint64_t*)memmap->entries[chunk]->base;
- int use_count = 1; // for placing structures in the right location
+void pmm_init(limine_memmap_response* memmap) {
+ Bitmap* current = nullptr;
+ Bitmap* tail = nullptr;
+ bool first = true;
for (size_t i = 0; i < memmap->entry_count; i++) {
if (memmap->entries[i]->type == LIMINE_MEMMAP_USABLE) {
-
+ // sets bitmap struct pointer address
+ current = (Bitmap*)(memmap->entries[i]->base + _hhdm_offset);
+
+ // sets up bitmap
+ current->address = (uint64_t*)(memmap->entries[i]->base + sizeof(Bitmap) + _hhdm_offset);
+
+ current->limit = memmap->entries[i]->length;
+
+ // almost always will be less pages than the full space
+ // since it doesn't account for remainders (yet)
+ // length / page size / bit width
+ current->length = memmap->entries[i]->length / 0x1000uL / BIT_WIDTH;
+ if (current->length < 1) {
+ continue;
+ }
+ // printf("len %lx\n", current->length);
+
+ // allocate memory for the bitmaps themselves
+ // printf("test %lx\n", current->limit / 0x40000uL / BIT_WIDTH);
+ for (size_t i = 0; i < (current->limit / 0x1000uL / BIT_WIDTH / BIT_WIDTH) + 1; i++) {
+ for (size_t j = 0; j < BIT_WIDTH; j++) {
+ // shifts bits off the right and masks the rest out to check for a 0
+ if (!((current->address[i] >> j) & 0x1uL)) {
+ current->address[i] |= 0x1uL << j;
+ // printf("init alloc: %lx\n", ((i * BIT_WIDTH) + j) * 0x1000uL + (uint64_t)current - _hhdm_offset);
+ break;
+ }
+ }
+ }
+
+ if (first) {
+ current->next = nullptr;
+ tail = current;
+ head = current;
+ first = false;
+ }
+ else {
+ tail->next = current;
+ tail = current;
+ }
}
}
-}
-void pmm_init(limine_memmap_response* memmap) {
- int chunk = find_biggest_chunk(memmap);
-
- setup_meminfo(memmap, chunk);
+ tail->next = nullptr;
printf("Initialized PMM\n");
}
-void* palloc() {
+uint64_t palloc() {
+ Bitmap* current = head;
+ while (true) {
+ for (size_t i = 0; i < current->length; i++) {
+ //if ((current->address[i] & UINT64_MAX) != UINT64_MAX) {
+ for (size_t j = 0; j < BIT_WIDTH; j++) {
+ // shifts bits off the right and masks the rest out to check for a 0
+ if (!((current->address[i] >> j) & 0x1uL)) {
+ current->address[i] |= 0x1uL << j;
+ // printf("addr: %lx\n", current + j);
+ return ((i * BIT_WIDTH) + j) * 0x1000uL + (uint64_t)current - _hhdm_offset;
+ }
+ }
+ //}
+ }
+
+ if (current->next == nullptr) {
+ return NULL;
+ }
+ current = current->next;
+ }
}
-void pfree(void* page) {
+void pfree(uint64_t page) {
+ Bitmap* current = head;
+ int offset;
+
+ while (true) {
+ if (page + _hhdm_offset >= (uint64_t)current) {
+ if (page + _hhdm_offset <= current->limit + (uint64_t)current) {
+ break;
+ }
+ }
+ current = current->next;
+ }
+ // Gets the starting number of the mem region page to get the correct bit number
+ // start 4D000, freeing 4E000, offset D - E = 1 = bit in bitmap
+ offset = ((uint64_t)current / 0x1000uL) & 0xFuL;
+ // divided by the amount of address space each index can hold
+ // should probably put that in its own variable/define later
+ uint64_t index = (page - ((uint64_t)current - _hhdm_offset)) / 0x40000uL;
+ int bit = page / 0x1000uL % BIT_WIDTH - offset;
+
+ // printf("before: %lx, ", current->address[index]);
+ current->address[index] &= ~(0x1uL << bit);
+ // printf("after: %lx\n", current->address[index]);
} \ No newline at end of file
diff --git a/kernel/mm/vmm.cpp b/kernel/mm/vmm.cpp
new file mode 100644
index 0000000..d5228ef
--- /dev/null
+++ b/kernel/mm/vmm.cpp
@@ -0,0 +1,2 @@
+#include <mm/vmm.h>
+