summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-02 10:10:24 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-02 10:13:32 -0500
commit1d794d87f4307f7b34f5b69d69213343aed9d137 (patch)
tree50d2508ddc4e6be814d31bfb37a37065e5e71525 /src
parentdebugger (diff)
downloadcorn-1d794d87f4307f7b34f5b69d69213343aed9d137.tar.gz
corn-1d794d87f4307f7b34f5b69d69213343aed9d137.tar.bz2
corn-1d794d87f4307f7b34f5b69d69213343aed9d137.zip
looping kalloc can allocate all of memory (sometimes) :3
Diffstat (limited to '')
-rw-r--r--src/arch/amd64/paging.c8
-rw-r--r--src/kmain.c4
-rw-r--r--src/lib.c1
-rw-r--r--src/memory/memory.c11
-rw-r--r--src/memory/physalloc.c40
-rw-r--r--src/memory/virtalloc.c106
6 files changed, 107 insertions, 63 deletions
diff --git a/src/arch/amd64/paging.c b/src/arch/amd64/paging.c
index 607267e..604e0a0 100644
--- a/src/arch/amd64/paging.c
+++ b/src/arch/amd64/paging.c
@@ -103,7 +103,7 @@ static void load_pd(void *phys) {
return;
pt->address = (uint64_t)phys >> 12;
pt->flags = F_PRESENT | F_WRITEABLE;
- invlpg(pdpt_mapped);
+ invlpg(pd_mapped);
}
static void load_pt(void *phys) {
@@ -456,10 +456,14 @@ static int map_pages(
page->address = (uint64_t)phys >> 12;
page->flags = F_PRESENT | flags;
- invlpg(virt);
+
+ if (flags & F_GLOBAL)
+ invlpg(virt);
}
+ __asm volatile("mov %cr3, %rax; mov %rax, %cr3;");
+
return 0;
failed:
diff --git a/src/kmain.c b/src/kmain.c
index 07244bf..7501669 100644
--- a/src/kmain.c
+++ b/src/kmain.c
@@ -8,8 +8,8 @@
void kmain(struct boot_info *info) {
memory_init(&info->map);
- //acpi_init(info->acpi_table);
//fb_init(1024, 768);
+ //acpi_init(info->acpi_table);
kprintf("enterd kmain\n");
@@ -17,7 +17,7 @@ void kmain(struct boot_info *info) {
*(char *)(0xB8000 + 0x146) = 'i';
while (1) {
- //kprintf("ret: 0x%p\n", kalloc(1024));
+ __asm__("hlt;");
// loop so we dont halt
// this allows interrupts to fire
}
diff --git a/src/lib.c b/src/lib.c
index ee4afcb..d2708c8 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -31,7 +31,6 @@ void *memmove(void *dest, const void *src, unsigned long n) {
}
void *memset(void *restrict dest, int c, unsigned long n) {
-
unsigned char *d = dest;
for (; n; n--) *d++ = c;
return dest;
diff --git a/src/memory/memory.c b/src/memory/memory.c
index ae26bfe..d1a163f 100644
--- a/src/memory/memory.c
+++ b/src/memory/memory.c
@@ -1,4 +1,3 @@
-#include "serial.h"
#include <memory.h>
#include <stdint.h>
#include <lib.h>
@@ -52,6 +51,7 @@ void *kalloc_new(size_t size) {
node = 0;
}
+ memset(addr, 0, pages * PAGE_SIZE);
struct page_header *header = addr;
header->magic = 0xBEEFCAFE;
header->used = size;
@@ -66,6 +66,8 @@ void *kalloc_new(size_t size) {
if (end_header != NULL) {
end_header->next = header;
+ } else {
+ end_header = header;
}
return mem;
@@ -146,7 +148,12 @@ void *krealloc(void *src, size_t dst_len) {
return NULL; // allocation failed
}
+ if (dst_len < src_len)
+ src_len = dst_len;
+
memcpy(dst, src, src_len);
+ kfree(src);
+
return dst;
}
@@ -159,7 +166,7 @@ void kfree(void *ptr) {
header = get_header(ptr);
- if (header == NULL || header->used == 0) {
+ if (header == NULL) {
panic("attempted to kfree invalid pointer");
}
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;
diff --git a/src/memory/virtalloc.c b/src/memory/virtalloc.c
index baa7892..bfeb670 100644
--- a/src/memory/virtalloc.c
+++ b/src/memory/virtalloc.c
@@ -35,6 +35,32 @@ static struct addr_node *get_node_idx(int idx) {
}
}
+static void update_node_ptrs(
+ struct addr_node *old,
+ struct addr_node *new,
+ int old_len,
+ int new_len
+) {
+ if (old == NULL)
+ return;
+ int idx = 0;
+ for (int i = 0; i < old_len; i++) {
+ struct addr_node *o = &old[i];
+ if (o && !o->is_used)
+ continue;
+ struct addr_node *n = &new[idx++];
+ *n = *o;
+ if (n->prev != NULL)
+ n->prev->next = n;
+ if (n->next != NULL)
+ n->next->prev = n;
+ }
+ for (int i = idx; i < new_len; i++) {
+ struct addr_node *n = &new[idx++];
+ n->is_used = false;
+ }
+}
+
static struct addr_node *get_node(void) {
size_t count = BSS_NODES + alloc_node_count;
@@ -43,10 +69,13 @@ static struct addr_node *get_node(void) {
int new_alloc = alloc_node_count * 2;
if (new_alloc < 8)
new_alloc = 8;
- int allocated = new_alloc - alloc_node_count;
- int old = new_alloc - allocated;
- alloc_nodes = krealloc(alloc_nodes, sizeof(struct addr_node) * new_alloc);
- memset(alloc_nodes + old, 0, sizeof(struct addr_node) + allocated);;
+ struct addr_node *new_nodes;
+ new_nodes = kalloc(sizeof(struct addr_node) * new_alloc);
+ if (new_nodes == NULL)
+ panic("virt addr alloc nodes is null");
+ update_node_ptrs(alloc_nodes, new_nodes, alloc_node_count, new_alloc);
+ kfree(alloc_nodes);
+ alloc_nodes = new_nodes;
alloc_node_count = new_alloc;
is_allocating = false;
count = BSS_NODES + alloc_node_count;
@@ -83,26 +112,60 @@ void virtaddr_init(void) {
start_node = &bootstrap_nodes[0];
}
-void *virtaddr_alloc(int n_pages) {
+static void merge_back(struct addr_node *node) {
+ while(node->prev) {
+ if (node->is_alloc != node->prev->is_alloc)
+ break;
+ struct addr_node *temp = node->prev;
+ node->start = temp->start;
+ node->prev = temp->prev;
+ if (temp->prev)
+ temp->prev->next = node;
+ free_node(temp);
+ }
+ if (node->prev == NULL) {
+ start_node = node;
+ }
+}
+
+static void merge_forward(struct addr_node *node) {
+<<<<<<< HEAD
+ while (node->next && !node->is_alloc) {
+=======
+ while(node->next) {
+ if (node->is_alloc != node->next->is_alloc)
+ break;
+>>>>>>> ea2de5a (looping kalloc can allocate all of memory (sometimes) :3)
+ struct addr_node *temp = node->next;
+ node->end = temp->end;
+ node->next = temp->next;
+ if (temp->next)
+ temp->next->prev = node;
+ free_node(temp);
+ }
+}
+
+void *virtaddr_alloc(int n_pages) {
if (n_pages < 1)
return NULL;
-
long n_length = n_pages * PAGE_SIZE;
struct addr_node *node = start_node;
for (; node != NULL ; node = node->next) {
-
+ long length = node->end - node->start;
if (node->is_alloc)
continue;
- long length = node->end - node->start;
if (length >= n_length) {
struct addr_node *new = get_node();
if (node->prev != NULL) {
node->prev->next = new;
+ } else {
+ start_node = new;
}
new->next = node;
+ new->prev = node->prev;
node->prev = new;
new->start = node->start;
new->end = new->start + n_length;
@@ -110,34 +173,17 @@ void *virtaddr_alloc(int n_pages) {
new->is_alloc = true;
new->is_used = true;
new->next = node;
- return (void *) new->start;
+ return (void*)new->start;
+ //void *mem = (void *) new->start;
+ //merge_back(new);
+ //merge_forward(new);
+ //return mem;
}
}
return NULL;
}
-static void merge_back(struct addr_node *node) {
- while (node->prev && !node->is_alloc) {
- struct addr_node *temp = node->prev;
- node->start = node->prev->start;
- node->prev = node->prev->prev;
- free_node(temp);
- }
- if (node->prev == NULL) {
- start_node = node;
- }
-}
-
-static void merge_forward(struct addr_node *node) {
- while (node->next && !node->is_alloc) {
- struct addr_node *temp = node->next;
- node->end = node->next->end;
- node->next = node->next->next;
- free_node(temp);
- }
-}
-
long virtaddr_free(void *virtaddr) {
uintptr_t virt = (uintptr_t) virtaddr;