summaryrefslogtreecommitdiff
path: root/src/mem.zig
diff options
context:
space:
mode:
authorGravatar Matthew Wozniak <me@woz.blue> 2026-05-29 21:59:53 -0400
committerGravatar Matthew Wozniak <me@woz.blue> 2026-05-29 22:04:38 -0400
commitfe456c2014c8d1d88b7fd5b24ebda7f7b4c53460 (patch)
treea1ae3682aede1ea7550f4be76a79118bd6502902 /src/mem.zig
downloadquail-fe456c2014c8d1d88b7fd5b24ebda7f7b4c53460.tar.gz
quail-fe456c2014c8d1d88b7fd5b24ebda7f7b4c53460.zip
basic physical memory page allocator
Signed-off-by: Matthew Wozniak <me@woz.blue>
Diffstat (limited to 'src/mem.zig')
-rw-r--r--src/mem.zig41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/mem.zig b/src/mem.zig
new file mode 100644
index 0000000..b361b88
--- /dev/null
+++ b/src/mem.zig
@@ -0,0 +1,41 @@
+const std = @import("std");
+
+const Page = extern struct {
+ next: *Page,
+};
+
+var head = @extern(*align(4096) Page, .{ .name = "_heap_start" });
+
+pub fn init() void {
+ // how many pages do we have?
+ const page_count = @intFromPtr(@extern(
+ *const anyopaque,
+ .{ .name = "_heap_size" },
+ )) / 4096;
+
+ // go through every page and make it point it to the next one
+ const pages: []Page = @as([*]Page, @ptrCast(head))[0..page_count];
+ for (0..page_count - 1) |i| {
+ pages[i].next = &pages[i + 1];
+ }
+
+ std.log.scoped(.mem).info(
+ "{} physical pages of 4096 B = {} B free",
+ .{ page_count, page_count * 4096 },
+ );
+}
+
+// allocates 1 page by taking it off the front of the linked list
+pub fn alloc() []align(4096) u8 {
+ const page = @as([*]align(4096) u8, @ptrCast(head))[0..4096];
+ head = head.next;
+ return page;
+}
+
+// free the page by putting it back on the front of the linked list
+pub fn free(mem: []align(4096) u8) void {
+ std.debug.assert(mem.len == 4096);
+ const page: *Page = @ptrCast(mem.ptr);
+ page.next = head;
+ head = page;
+}