BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 4f822f67ee63ef4245ad6bfcd0e3fe04ff6f34a0

// Related

Nucleus

Barry Stack-based page frame allocator 4f822f6 (3 years, 3 months ago)
diff --git a/kernel/main.c b/kernel/main.c
index c2eb55d..5a10a59 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -7,6 +7,7 @@
 #include <stdint.h>
 #include <string.h>
 #include "multiboot.h"
+#include "../memory/memory.h"
 
 extern char _bss[], _end[];
 
@@ -17,5 +18,8 @@ kmain(uint32_t esp, struct MultibootInfo *mbinfo)
 	void *ebda = (void *) (*((uint16_t *) 0x040E) << 4);
 	memset(_bss, 0, _end - _bss);
 
+	/* Setup frame allocator */
+	init_frames(mbinfo->mmapLen, (void *) mbinfo->mmapAddr);
+
 	while (1);
 }
diff --git a/memory/frame.c b/memory/frame.c
new file mode 100644
index 0000000..35b2fed
--- /dev/null
+++ b/memory/frame.c
@@ -0,0 +1,70 @@
+/*
+ * This file controls the page frame allocator.  It is the core of the physical
+ * memory manager.  The kernel heap and paging systems both sit on top of this.
+ * It keeps track of which frames of physical memory a free and hands them out
+ * as needed.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include "memory.h"
+
+/* Types of an E820 Memory Map Entry */
+enum E820Type {
+	E820_NONE,
+	E820_USABLE,
+	E820_RESERVED,
+	E820_RECLAIMABLE,
+	E820_NVS,
+	E820_BAD,
+};
+
+/* Structure of an E820 Memory Map Entry */
+struct E820Entry {
+	uint32_t size;
+	uint32_t base, baseHigh;
+	uint32_t length, lengthHigh;
+	uint32_t type;
+} __attribute__((packed));
+
+static uintptr_t nextFrame;
+
+/* Allocate a page frame */
+uintptr_t
+alloc_frame(void)
+{
+	uintptr_t frame = nextFrame;
+	nextFrame = *((uintptr_t *) frame);
+	*((uintptr_t *) frame) = 0;
+	return frame;
+}
+
+/* Free a page frame */
+void
+free_frame(uintptr_t frame)
+{
+	*((uintptr_t *) frame) = nextFrame;
+	nextFrame = frame;
+}
+
+/* Setup the page frame allocator */
+void
+init_frames(uint32_t size, void *addr)
+{
+	/*
+	 * When the kernel starts, the bootloader passes the kernel a map of
+	 * memory.  This map must be read so the memory manager can avoid bad
+	 * areas of memory and areas that are mapped to hardware, ACPI, etc.
+	 */
+	size_t i, j;
+	struct E820Entry *memMap = addr;
+	for (i = 0; i < size / sizeof(struct E820Entry); i++) {
+		if (memMap[i].baseHigh > 0
+		 || memMap[i].base > 0xFFFFFFFF
+		 || memMap[i].type != E820_USABLE)
+			continue;
+
+		for (j = 0; j < memMap[i].length; j += PAGE_SIZE)
+			free_frame(memMap[i].baseHigh + memMap[i].base + j);
+	}
+}
diff --git a/memory/memory.h b/memory/memory.h
new file mode 100644
index 0000000..a4abeb0
--- /dev/null
+++ b/memory/memory.h
@@ -0,0 +1,13 @@
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define PAGE_SIZE 0x1000
+
+uintptr_t alloc_frame(void);
+void free_frame(uintptr_t frame);
+void init_frames(size_t memMapSize, void *memMap);
+
+#endif