summaryrefslogtreecommitdiff
path: root/kernel/memory/virtalloc.c
diff options
context:
space:
mode:
authorIan McFarlane <i.mcfarlane2002@gmail.com>2025-05-06 15:14:11 -0400
committerIan McFarlane <i.mcfarlane2002@gmail.com>2025-05-06 15:14:11 -0400
commitda396afa8b612b8f8ff07d71c57761a627b158eb (patch)
treeb4935b29aca686c6ee17a583cffe149d7bb3c819 /kernel/memory/virtalloc.c
parentupdate forkman with spinlock (diff)
parentstart docs (diff)
downloadcomus-da396afa8b612b8f8ff07d71c57761a627b158eb.tar.gz
comus-da396afa8b612b8f8ff07d71c57761a627b158eb.tar.bz2
comus-da396afa8b612b8f8ff07d71c57761a627b158eb.zip
merge main into forkmanforkman
Diffstat (limited to 'kernel/memory/virtalloc.c')
-rw-r--r--kernel/memory/virtalloc.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c
index 0cbba33..3d60a9f 100644
--- a/kernel/memory/virtalloc.c
+++ b/kernel/memory/virtalloc.c
@@ -1,10 +1,12 @@
-#include "lib/kio.h"
#include <lib.h>
#include <comus/memory.h>
#include <stdint.h>
#include "virtalloc.h"
+extern char kernel_start[];
+extern char kernel_end[];
+
static struct virt_addr_node *get_node_idx(struct virt_ctx *ctx, int idx)
{
if (idx < BOOTSTRAP_VIRT_ALLOC_NODES) {
@@ -64,6 +66,7 @@ static struct virt_addr_node *get_node(struct virt_ctx *ctx)
for (; idx < count; idx++) {
struct virt_addr_node *node = get_node_idx(ctx, idx);
if (!node->is_used) {
+ node->is_used = true;
ctx->used_node_count++;
return node;
}
@@ -81,7 +84,7 @@ static void free_node(struct virt_ctx *ctx, struct virt_addr_node *node)
void virtaddr_init(struct virt_ctx *ctx)
{
struct virt_addr_node init = {
- .start = 0x50000000,
+ .start = 0x0,
.end = 0x1000000000000, // 48bit memory address max
.next = NULL,
.prev = NULL,
@@ -96,6 +99,10 @@ void virtaddr_init(struct virt_ctx *ctx)
ctx->alloc_node_count = 0;
ctx->used_node_count = 0;
ctx->is_allocating = false;
+
+ virtaddr_take(ctx, (void *)0,
+ ((uint64_t)kernel_end + PAGE_SIZE - 1) / PAGE_SIZE *
+ PAGE_SIZE);
}
int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new)
@@ -138,32 +145,31 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new)
static void merge_back(struct virt_ctx *ctx, struct virt_addr_node *node)
{
- while (node->prev) {
- if (node->is_alloc != node->prev->is_alloc)
+ struct virt_addr_node *prev;
+ for (prev = node->prev; prev != NULL; prev = prev->prev) {
+ if (prev->is_alloc)
break;
- struct virt_addr_node *temp = node->prev;
- node->start = temp->start;
- node->prev = temp->prev;
- if (temp->prev)
- temp->prev->next = node;
- free_node(ctx, temp);
+ node->start = prev->start;
+ node->prev = prev->prev;
+ if (node->prev)
+ node->prev->next = node;
+ free_node(ctx, prev);
}
- if (node->prev == NULL) {
+ if (node->prev == NULL)
ctx->start_node = node;
- }
}
static void merge_forward(struct virt_ctx *ctx, struct virt_addr_node *node)
{
- while (node->next) {
- if (node->is_alloc != node->next->is_alloc)
+ struct virt_addr_node *next;
+ for (next = node->next; next != NULL; next = next->next) {
+ if (next->is_alloc)
break;
- struct virt_addr_node *temp = node->next;
- node->end = temp->end;
- node->next = temp->next;
- if (temp->next)
- temp->next->prev = node;
- free_node(ctx, temp);
+ node->end = next->end;
+ node->next = next->next;
+ if (node->next)
+ node->next->prev = node;
+ free_node(ctx, next);
}
}
@@ -211,9 +217,9 @@ int virtaddr_take(struct virt_ctx *ctx, const void *virt, int n_pages)
left->prev = node->prev;
left->start = node->start;
left->end = (uintptr_t)virt;
- left->is_used = true;
left->is_alloc = false;
- node->prev->next = left;
+ if (node->prev)
+ node->prev->next = left;
node->prev = left;
}
@@ -224,16 +230,15 @@ int virtaddr_take(struct virt_ctx *ctx, const void *virt, int n_pages)
right->next = node->next;
right->start = (uintptr_t)virt + n_length;
right->end = node->end;
- right->is_used = true;
right->is_alloc = false;
- node->next->prev = right;
+ if (node->next)
+ node->next->prev = right;
node->next = right;
}
node->start = (uintptr_t)virt;
node->end = node->start + n_length;
node->is_alloc = true;
- node->is_used = true;
return 0;
}
@@ -257,6 +262,7 @@ long virtaddr_free(struct virt_ctx *ctx, const void *virtaddr)
if (node->start == virt) {
int length = node->end - node->start;
int pages = length / PAGE_SIZE;
+ node->is_alloc = false;
merge_back(ctx, node);
merge_forward(ctx, node);
return pages;