aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/memory/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/memory/mmap.c')
-rw-r--r--src/kernel/memory/mmap.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/kernel/memory/mmap.c b/src/kernel/memory/mmap.c
new file mode 100644
index 0000000..ab021b8
--- /dev/null
+++ b/src/kernel/memory/mmap.c
@@ -0,0 +1,106 @@
+#include <memory/mmap.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <system.h>
+
+#define FRAME_SIZE 0x1000
+#define FRAME_COUNT (total_memory / 4)
+#define FRAME_TABLE_SIZE (FRAME_COUNT / 32)
+
+#define FREE 0x0
+#define USED 0x1
+
+void *kmalloc(u32 size);
+
+extern u32 kernel_end;
+u32 kernel_end_address = (u32)&kernel_end;
+
+u32 total_memory;
+
+u32 *frame_table;
+
+void *kmalloc(u32 size)
+{
+ void *ret;
+
+ ret = (void *)kernel_end_address;
+ kernel_end_address += size;
+
+ return ret;
+}
+
+// TODO: Efficiency
+void *kmalloc_frames(u32 num)
+{
+ u8 found;
+
+ for (u32 i = 0; i < FRAME_COUNT; i++) {
+ found = 1;
+ for (u32 j = 0; j < num; j++) {
+ if (mmap_index_check(i + j) == USED) {
+ found = 0;
+ break;
+ }
+ }
+ if (found) {
+ for (u32 j = 0; j < num; j++) {
+ mmap_index_set_used(i + j);
+ }
+ return (void *)(i * FRAME_SIZE);
+ }
+ }
+
+ warn("Not enough frames");
+ return NULL;
+}
+
+void kfree_frames(void *ptr, u32 num)
+{
+ u32 address = (u32)ptr;
+ u32 i = address;
+
+ while (i < address + (num * FRAME_SIZE)) {
+ mmap_address_set_free(address);
+ i += FRAME_SIZE;
+ }
+}
+
+u8 mmap_index_check(u32 n)
+{
+ return (frame_table[n / 32] >> (n % 32)) & 0x1;
+}
+
+void mmap_init(u32 size)
+{
+ total_memory = size;
+ frame_table = kmalloc(FRAME_TABLE_SIZE);
+}
+
+void mmap_init_finalize()
+{
+ // TODO: Efficiency
+ //memset(frame_table, 0xFF, (&kernel_end / FRAME_SIZE) / 8);
+ for (u32 i = 0; i < kernel_end_address; i += FRAME_SIZE) {
+ mmap_address_set_used(i);
+ }
+}
+
+void mmap_address_set_free(u32 address)
+{
+ frame_table[(address / FRAME_SIZE) / 32] &= ~(1 << ((address / FRAME_SIZE) % 32));
+}
+
+void mmap_address_set_used(u32 address)
+{
+ frame_table[(address / FRAME_SIZE) / 32] |= (1 << ((address / FRAME_SIZE) % 32));
+}
+
+void mmap_index_set_free(u32 n)
+{
+ frame_table[n / 32] &= ~(1 << (n % 32));
+}
+
+void mmap_index_set_used(u32 n)
+{
+ frame_table[n / 32] |= 1 << (n % 32);
+} \ No newline at end of file