summaryrefslogtreecommitdiff
path: root/src/memory/physalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory/physalloc.c')
-rw-r--r--src/memory/physalloc.c40
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;