diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | kernel/arch/x86_64/limine.cpp | 9 | ||||
| -rw-r--r-- | kernel/include/mm/pmm.h | 16 | ||||
| -rw-r--r-- | kernel/include/mm/vmm.h | 8 | ||||
| -rw-r--r-- | kernel/makefile | 2 | ||||
| -rw-r--r-- | kernel/mm/pmm.cpp | 114 | ||||
| -rw-r--r-- | kernel/mm/vmm.cpp | 2 |
7 files changed, 110 insertions, 42 deletions
@@ -20,5 +20,6 @@ misc/ # not important
make.png
.clangd
+.gdbinit
.vscode/
diff --git a/kernel/arch/x86_64/limine.cpp b/kernel/arch/x86_64/limine.cpp index 5e9905f..2fd518b 100644 --- a/kernel/arch/x86_64/limine.cpp +++ b/kernel/arch/x86_64/limine.cpp @@ -135,14 +135,9 @@ extern "C" void _start() { }
printf("hhdm offset: %lx\n", _hhdm_offset);
- // pmm_init(memmap_request.response);
+ pmm_init(memmap_request.response);
+
- // asm("xchgw %bx, %bx");
- // uint64_t pmm_test[5];
- // for (size_t i = 0; i < 5; i++) {
- // pmm_test[i] = (uint64_t)palloc();
- // printf("Alloc %d: %lx\n", i, pmm_test[i]);
- // }
kernel_main();
diff --git a/kernel/include/mm/pmm.h b/kernel/include/mm/pmm.h index 36c5f83..772bc44 100644 --- a/kernel/include/mm/pmm.h +++ b/kernel/include/mm/pmm.h @@ -5,21 +5,15 @@ #include <stddef.h> #include <limine.h> -struct MemRegion { - uint64_t base; +struct Bitmap { + Bitmap* next; uint64_t length; - uint64_t bitmap_pos; // where the region starts on the bitmap index -}; - -struct BitmapInfo { + uint64_t limit; uint64_t* address; - uint64_t ind_length; - int region_count; - MemRegion* regions[]; }; void pmm_init(limine_memmap_response* memmap); -void* palloc(); -void pfree(void* page); +uint64_t palloc(); +void pfree(uint64_t page); #endif
\ No newline at end of file diff --git a/kernel/include/mm/vmm.h b/kernel/include/mm/vmm.h new file mode 100644 index 0000000..2cf06d7 --- /dev/null +++ b/kernel/include/mm/vmm.h @@ -0,0 +1,8 @@ +#ifndef VMM_H +#define VMM_H + +#include <stdint.h> + + + +#endif
\ No newline at end of file diff --git a/kernel/makefile b/kernel/makefile index 99b2dd8..a855808 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,6 +1,6 @@ # Kernel makefile
-CFLAGS := -ffreestanding -Wall -Wextra -g -std=gnu99 -O2 -Iinclude --sysroot=$(SYSROOT) \
+CFLAGS := -ffreestanding -Wall -Wextra -g -std=gnu11 -O2 -Iinclude --sysroot=$(SYSROOT) \
-isystem $(SYSROOT)/usr/include
CXXFLAGS := -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -g -O2 -Iinclude --sysroot=$(SYSROOT) \
-isystem $(SYSROOT)/usr/include -std=gnu++20
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> + |
