diff options
Diffstat (limited to 'src/memory/physalloc.c')
-rw-r--r-- | src/memory/physalloc.c | 40 |
1 files changed, 14 insertions, 26 deletions
diff --git a/src/memory/physalloc.c b/src/memory/physalloc.c index 67c99c7..b0dbdcd 100644 --- a/src/memory/physalloc.c +++ b/src/memory/physalloc.c @@ -1,4 +1,3 @@ -#include "serial.h" #include <memory.h> #include <stdint.h> #include <lib.h> @@ -15,8 +14,6 @@ extern char kernel_end; // between memory_start and kernel_start will be the bitmap static uintptr_t memory_start = 0; -typedef unsigned char page[4096]; - struct memory_area { uint64_t len; uintptr_t addr; @@ -26,9 +23,8 @@ static uint64_t *bitmap; static uint64_t total_memory; static uint64_t free_memory; static uint64_t page_count; -static uint64_t page_free_start; static uint64_t segment_count; -static struct memory_area *page_start; +struct memory_area *page_start; static int n_pages(const struct memory_area *m) { return m->len / PAGE_SIZE; @@ -37,7 +33,7 @@ static int n_pages(const struct memory_area *m) { static void *page_at(int i) { int cur_page = 0; for (uint64_t idx = 0; idx < segment_count; idx++) { - struct memory_area *m = &page_start[idx]; + const struct memory_area *m = page_start; int pages = n_pages(m); if (i - cur_page < pages) { return (void *) (m->addr + (PAGE_SIZE * (i - cur_page))); @@ -47,10 +43,11 @@ static void *page_at(int i) { return NULL; } -static long page_idx(page p) { - uintptr_t addr = (uintptr_t) p; +static long page_idx(void *page) { + uintptr_t addr = (uintptr_t) page; int cur_page = 0; - for (struct memory_area *m = page_start; m != NULL; m++) { + for (uint64_t idx = 0; idx < segment_count; idx++) { + const struct memory_area *m = page_start; if ((uintptr_t) m + m->len > addr) { return cur_page + ((addr - m->addr) / PAGE_SIZE); } @@ -82,15 +79,9 @@ void *alloc_phys_pages(int pages) { int n_contiguous = 0; int free_region_start = 0; - bool first = true; - for (uint64_t i = page_free_start; i < page_count; i++) { + for (uint64_t i = 0; i < page_count; i++) { bool free = !bitmap_get(i); - if (first) { - first = false; - page_free_start = i; - } - if (free) { if (n_contiguous == 0) free_region_start = i; n_contiguous++; @@ -113,8 +104,6 @@ void free_phys_pages(void *ptr, int pages) { long idx = page_idx(ptr); if (idx == -1) return; - if ((unsigned) idx < page_free_start) page_free_start = idx; - for (int i = 0; i < pages; i++) bitmap_set(idx + pages, false); } @@ -165,7 +154,6 @@ void memory_init(struct memory_map *map) { total_memory = 0; free_memory = 0; page_count = 0; - page_free_start = 0; page_start = NULL; segment_count = 0; @@ -181,21 +169,21 @@ void memory_init(struct memory_map *map) { segment_count++; } - long bitmap_pages = page_count / 64 / PAGE_SIZE + 1; - free_memory = page_count * PAGE_SIZE; - - //HACK: terrible hack bad bad bad bad + long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1; long bitmap_size = bitmap_pages * PAGE_SIZE; bitmap = (uint64_t *) page_align(kaddr(kernel_end)); long page_area_size = segment_count * sizeof(struct memory_area); char *page_area_addr = (char *)bitmap + bitmap_size; - bitmap = mmap(bitmap, bitmap_size); - memset(bitmap, 0, bitmap_size); + page_area_addr = (char *) page_align((uintptr_t) page_area_addr); - memory_start = page_align(kaddr(kernel_end) + bitmap_size + page_area_size); + memory_start = page_align((uintptr_t)page_area_addr + page_area_size); + bitmap = mmap(bitmap, bitmap_size); + memset(bitmap, 0, bitmap_size); page_area_addr = mmap(page_area_addr, page_area_size); + memset(page_area_addr, 0, page_area_size); + page_start = (struct memory_area *) page_area_addr; struct memory_area *area = page_start; |