aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/memory
diff options
context:
space:
mode:
authorMarvin Borner2020-06-17 18:31:46 +0200
committerMarvin Borner2020-06-17 18:31:46 +0200
commiteed77bd2970a00d1394ed027ceca5b646e4671ce (patch)
treec44643d98aed2b6818f2b33417c0dea9c5853094 /src/kernel/memory
parent49dfa1f4021026bf7c4d77817959c8aa24067016 (diff)
Started rewrite
Diffstat (limited to 'src/kernel/memory')
-rw-r--r--src/kernel/memory/alloc.c492
-rw-r--r--src/kernel/memory/alloc.h12
-rw-r--r--src/kernel/memory/mmap.c107
-rw-r--r--src/kernel/memory/mmap.h18
-rw-r--r--src/kernel/memory/paging.c117
-rw-r--r--src/kernel/memory/paging.h60
6 files changed, 0 insertions, 806 deletions
diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c
deleted file mode 100644
index 4f76080..0000000
--- a/src/kernel/memory/alloc.c
+++ /dev/null
@@ -1,492 +0,0 @@
-#include <io/io.h>
-#include <lib/lib.h>
-#include <memory/alloc.h>
-#include <memory/mmap.h>
-#include <memory/paging.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <system.h>
-
-static int locked = 0;
-
-int liballoc_lock()
-{
- spinlock(&locked);
- return 0;
-}
-
-int liballoc_unlock()
-{
- locked = 0;
- return 0;
-}
-
-void *liballoc_alloc(u32 p)
-{
- u32 ptr = kmalloc_frames((u32)p);
- return (void *)ptr;
-}
-
-int liballoc_free(void *ptr, u32 p)
-{
- kfree_frames((u32)ptr, (u32)p);
- return 0;
-}
-
-#define ALIGNMENT 16ul
-#define ALIGN_TYPE char
-#define ALIGN_INFO sizeof(ALIGN_TYPE) * 16
-#define USE_CASE1
-#define USE_CASE2
-#define USE_CASE3
-#define USE_CASE4
-#define USE_CASE5
-
-#define ALIGN(ptr) \
- if (ALIGNMENT > 1) { \
- u32 diff; \
- ptr = (void *)((u32)ptr + ALIGN_INFO); \
- diff = (u32)ptr & (ALIGNMENT - 1); \
- if (diff != 0) { \
- diff = ALIGNMENT - diff; \
- ptr = (void *)((u32)ptr + diff); \
- } \
- *((ALIGN_TYPE *)((u32)ptr - ALIGN_INFO)) = diff + ALIGN_INFO; \
- }
-
-#define UNALIGN(ptr) \
- if (ALIGNMENT > 1) { \
- u32 diff = *((ALIGN_TYPE *)((u32)ptr - ALIGN_INFO)); \
- if (diff < (ALIGNMENT + ALIGN_INFO)) { \
- ptr = (void *)((u32)ptr - diff); \
- } \
- }
-
-#define LIBALLOC_MAGIC 0x900df00d
-#define LIBALLOC_DEAD 0xbaadf00d
-
-struct liballoc_major {
- struct liballoc_major *prev;
- struct liballoc_major *next;
- u32 pages;
- u32 size;
- u32 usage;
- struct liballoc_minor *first;
-};
-
-struct liballoc_minor {
- struct liballoc_minor *prev;
- struct liballoc_minor *next;
- struct liballoc_major *block;
- u32 magic;
- u32 size;
- u32 req_size;
-};
-
-static struct liballoc_major *l_mem_root = NULL;
-static struct liballoc_major *l_best_bet = NULL;
-
-static u32 l_page_size = 4096;
-static u32 l_page_count = 16;
-static u64 l_allocated = 0;
-static u64 l_inuse = 0;
-
-static long long l_warning_count = 0;
-static long long l_error_count = 0;
-static long long l_possible_overruns = 0;
-
-static void *liballoc_memset(void *s, int c, u32 n)
-{
- for (u32 i = 0; i < n; i++)
- ((char *)s)[i] = c;
-
- return s;
-}
-
-static void *liballoc_memcpy(void *s1, const void *s2, u32 n)
-{
- char *cdest;
- char *csrc;
- u32 *ldest = (u32 *)s1;
- u32 *lsrc = (u32 *)s2;
-
- while (n >= sizeof(u32)) {
- *ldest++ = *lsrc++;
- n -= sizeof(u32);
- }
-
- cdest = (char *)ldest;
- csrc = (char *)lsrc;
-
- while (n > 0) {
- *cdest++ = *csrc++;
- n -= 1;
- }
- return s1;
-}
-
-static struct liballoc_major *allocate_new_page(u32 size)
-{
- u32 st;
- struct liballoc_major *maj;
-
- st = size + sizeof(struct liballoc_major);
- st += sizeof(struct liballoc_minor);
-
- if ((st % l_page_size) == 0)
- st = st / (l_page_size);
- else
- st = st / (l_page_size) + 1;
-
- if (st < l_page_count)
- st = l_page_count;
-
- maj = (struct liballoc_major *)liballoc_alloc(st);
-
- if (maj == NULL) {
- l_warning_count += 1;
- return NULL;
- }
-
- maj->prev = NULL;
- maj->next = NULL;
- maj->pages = st;
- maj->size = st * l_page_size;
- maj->usage = sizeof(struct liballoc_major);
- maj->first = NULL;
-
- l_allocated += maj->size;
-
- return maj;
-}
-
-void *malloc(u32 req_size)
-{
- assert(paging_enabled);
-
- int started_bet = 0;
- u64 best_size = 0;
- void *p = NULL;
- u32 diff;
- struct liballoc_major *maj;
- struct liballoc_minor *min;
- struct liballoc_minor *new_min;
- u32 size = req_size;
-
- if (ALIGNMENT > 1) {
- size += ALIGNMENT + ALIGN_INFO;
- }
-
- liballoc_lock();
-
- if (size == 0) {
- l_warning_count += 1;
- liballoc_unlock();
- return malloc(1);
- }
-
- if (l_mem_root == NULL) {
- l_mem_root = allocate_new_page(size);
- if (l_mem_root == NULL) {
- liballoc_unlock();
- return NULL;
- }
- }
-
- maj = l_mem_root;
- started_bet = 0;
-
- if (l_best_bet != NULL) {
- best_size = l_best_bet->size - l_best_bet->usage;
-
- if (best_size > (size + sizeof(struct liballoc_minor))) {
- maj = l_best_bet;
- started_bet = 1;
- }
- }
-
- while (maj != NULL) {
- diff = maj->size - maj->usage;
- if (best_size < diff) {
- l_best_bet = maj;
- best_size = diff;
- }
-
-#ifdef USE_CASE1
- if (diff < (size + sizeof(struct liballoc_minor))) {
- if (maj->next != NULL) {
- maj = maj->next;
- continue;
- }
-
- if (started_bet == 1) {
- maj = l_mem_root;
- started_bet = 0;
- continue;
- }
-
- maj->next = allocate_new_page(size);
- if (maj->next == NULL)
- break;
- maj->next->prev = maj;
- maj = maj->next;
- }
-#endif
-
-#ifdef USE_CASE2
- if (maj->first == NULL) {
- maj->first =
- (struct liballoc_minor *)((u32)maj + sizeof(struct liballoc_major));
-
- maj->first->magic = LIBALLOC_MAGIC;
- maj->first->prev = NULL;
- maj->first->next = NULL;
- maj->first->block = maj;
- maj->first->size = size;
- maj->first->req_size = req_size;
- maj->usage += size + sizeof(struct liballoc_minor);
- l_inuse += size;
- p = (void *)((u32)(maj->first) + sizeof(struct liballoc_minor));
- ALIGN(p);
- liballoc_unlock();
- return p;
- }
-#endif
-
-#ifdef USE_CASE3
- diff = (u32)(maj->first);
- diff -= (u32)maj;
- diff -= sizeof(struct liballoc_major);
-
- if (diff >= (size + sizeof(struct liballoc_minor))) {
- maj->first->prev =
- (struct liballoc_minor *)((u32)maj + sizeof(struct liballoc_major));
- maj->first->prev->next = maj->first;
- maj->first = maj->first->prev;
- maj->first->magic = LIBALLOC_MAGIC;
- maj->first->prev = NULL;
- maj->first->block = maj;
- maj->first->size = size;
- maj->first->req_size = req_size;
- maj->usage += size + sizeof(struct liballoc_minor);
- l_inuse += size;
- p = (void *)((u32)(maj->first) + sizeof(struct liballoc_minor));
- ALIGN(p);
- liballoc_unlock();
- return p;
- }
-#endif
-
-#ifdef USE_CASE4
- min = maj->first;
-
- while (min != NULL) {
- if (min->next == NULL) {
- diff = (u32)(maj) + maj->size;
- diff -= (u32)min;
- diff -= sizeof(struct liballoc_minor);
- diff -= min->size;
- if (diff >= (size + sizeof(struct liballoc_minor))) {
- min->next = (struct liballoc_minor
- *)((u32)min +
- sizeof(struct liballoc_minor) +
- min->size);
- min->next->prev = min;
- min = min->next;
- min->next = NULL;
- min->magic = LIBALLOC_MAGIC;
- min->block = maj;
- min->size = size;
- min->req_size = req_size;
- maj->usage += size + sizeof(struct liballoc_minor);
- l_inuse += size;
- p = (void *)((u32)min + sizeof(struct liballoc_minor));
- ALIGN(p);
- liballoc_unlock();
- return p;
- }
- }
-
- if (min->next != NULL) {
- diff = (u32)(min->next);
- diff -= (u32)min;
- diff -= sizeof(struct liballoc_minor);
- diff -= min->size;
-
- if (diff >= (size + sizeof(struct liballoc_minor))) {
- new_min = (struct liballoc_minor
- *)((u32)min +
- sizeof(struct liballoc_minor) +
- min->size);
- new_min->magic = LIBALLOC_MAGIC;
- new_min->next = min->next;
- new_min->prev = min;
- new_min->size = size;
- new_min->req_size = req_size;
- new_min->block = maj;
- min->next->prev = new_min;
- min->next = new_min;
- maj->usage += size + sizeof(struct liballoc_minor);
- l_inuse += size;
- p = (void *)((u32)new_min + sizeof(struct liballoc_minor));
- ALIGN(p);
- liballoc_unlock();
- return p;
- }
- }
-
- min = min->next;
- }
-#endif
-
-#ifdef USE_CASE5
- if (maj->next == NULL) {
- if (started_bet == 1) {
- maj = l_mem_root;
- started_bet = 0;
- continue;
- }
- maj->next = allocate_new_page(size);
- if (maj->next == NULL)
- break;
- maj->next->prev = maj;
- }
-#endif
- maj = maj->next;
- }
-
- liballoc_unlock();
-
- return NULL;
-}
-
-// Definitely improveable
-void *valloc(u32 req_size)
-{
- u32 mask = l_page_size - 1;
- u32 mem = malloc(req_size + l_page_size);
- return (void *)((mem + mask) & ~mask);
-}
-
-void free(void *ptr)
-{
- struct liballoc_minor *min;
- struct liballoc_major *maj;
-
- if (ptr == NULL) {
- l_warning_count += 1;
- return;
- }
-
- UNALIGN(ptr);
- liballoc_lock();
-
- min = (struct liballoc_minor *)((u32)ptr - sizeof(struct liballoc_minor));
-
- if (min->magic != LIBALLOC_MAGIC) {
- l_error_count += 1;
-
- if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
- ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
- ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) {
- l_possible_overruns += 1;
- }
-
- liballoc_unlock();
- return;
- }
-
- maj = min->block;
- l_inuse -= min->size;
- maj->usage -= (min->size + sizeof(struct liballoc_minor));
- min->magic = LIBALLOC_DEAD;
-
- if (min->next != NULL)
- min->next->prev = min->prev;
- if (min->prev != NULL)
- min->prev->next = min->next;
- if (min->prev == NULL)
- maj->first = min->next;
- if (maj->first == NULL) {
- if (l_mem_root == maj)
- l_mem_root = maj->next;
- if (l_best_bet == maj)
- l_best_bet = NULL;
- if (maj->prev != NULL)
- maj->prev->next = maj->next;
- if (maj->next != NULL)
- maj->next->prev = maj->prev;
- l_allocated -= maj->size;
- liballoc_free(maj, maj->pages);
- } else {
- if (l_best_bet != NULL) {
- int best_size = l_best_bet->size - l_best_bet->usage;
- int maj_size = maj->size - maj->usage;
- if (maj_size > best_size)
- l_best_bet = maj;
- }
- }
- liballoc_unlock();
-}
-
-void *calloc(u32 nobj, u32 size)
-{
- int real_size;
- void *p;
-
- real_size = nobj * size;
-
- p = malloc(real_size);
-
- liballoc_memset(p, 0, real_size);
-
- return p;
-}
-
-void *realloc(void *p, u32 size)
-{
- void *ptr;
- struct liballoc_minor *min;
- u32 real_size;
-
- if (size == 0) {
- free(p);
- return NULL;
- }
-
- if (p == NULL)
- return malloc(size);
-
- ptr = p;
- UNALIGN(ptr);
- liballoc_lock();
- min = (struct liballoc_minor *)((u32)ptr - sizeof(struct liballoc_minor));
-
- if (min->magic != LIBALLOC_MAGIC) {
- l_error_count += 1;
- if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
- ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
- ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) {
- l_possible_overruns += 1;
- }
-
- liballoc_unlock();
- return NULL;
- }
-
- real_size = min->req_size;
-
- if (real_size >= size) {
- min->req_size = size;
- liballoc_unlock();
- return p;
- }
-
- liballoc_unlock();
-
- ptr = malloc(size);
- liballoc_memcpy(ptr, p, real_size);
- free(p);
-
- return ptr;
-} \ No newline at end of file
diff --git a/src/kernel/memory/alloc.h b/src/kernel/memory/alloc.h
deleted file mode 100644
index bb3f452..0000000
--- a/src/kernel/memory/alloc.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef MELVIX_ALLOC_H
-#define MELVIX_ALLOC_H
-
-#include <stdint.h>
-
-void *malloc(u32);
-void *valloc(u32);
-void *realloc(void *, u32);
-void *calloc(u32, u32);
-void free(void *);
-
-#endif \ No newline at end of file
diff --git a/src/kernel/memory/mmap.c b/src/kernel/memory/mmap.c
deleted file mode 100644
index 2e4821d..0000000
--- a/src/kernel/memory/mmap.c
+++ /dev/null
@@ -1,107 +0,0 @@
-#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;
-
-// Not to be used externally!
-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
diff --git a/src/kernel/memory/mmap.h b/src/kernel/memory/mmap.h
deleted file mode 100644
index 1de801f..0000000
--- a/src/kernel/memory/mmap.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef MELVIX_MMAP
-#define MELVIX_MMAP
-
-#include <stdint.h>
-
-void *kmalloc_frames(u32 num);
-void kfree_frames(void *ptr, u32 num);
-
-u8 mmap_check(u32 n);
-void mmap_init(u32 size);
-void mmap_init_finalize();
-void mmap_address_set_free(u32 address);
-void mmap_address_set_used(u32 address);
-u8 mmap_index_check(u32 n);
-void mmap_index_set_free(u32 n);
-void mmap_index_set_used(u32 n);
-
-#endif \ No newline at end of file
diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c
deleted file mode 100644
index e2c48b8..0000000
--- a/src/kernel/memory/paging.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <io/io.h>
-#include <lib/lib.h>
-#include <memory/alloc.h>
-#include <memory/mmap.h>
-#include <memory/paging.h>
-#include <stdint.h>
-#include <system.h>
-
-struct page_dir *kernel_page_directory;
-
-void paging_install()
-{
- memory_init();
-
- struct page_table *page_table;
-
- page_table = kmalloc_frames(1);
- memset(page_table, 0, sizeof(struct page_table));
- for (u32 i = 0; i < PAGE_COUNT; i++) {
- page_table->entries[i].present = 1;
- page_table->entries[i].writable = 1;
- page_table->entries[i].address = SHIFT(i * PAGE_SIZE);
- }
-
- kernel_page_directory = kmalloc_frames(1);
- memset(kernel_page_directory, 0, sizeof(struct page_dir));
- kernel_page_directory->entries[0].present = 1;
- kernel_page_directory->entries[0].writable = 1;
- kernel_page_directory->entries[0].address = SHIFT((u32)page_table);
-
- paging_switch_dir((u32)kernel_page_directory);
- paging_enable();
- info("Installed paging");
-
- // Test mallocing
- u32 *c = malloc(2048);
- c[42] = 0x4242;
- assert(c[42] == 0x4242);
- free(c);
- info("Malloc test succeeded!");
-}
-
-void paging_disable()
-{
- u32 cr0 = cr0_get();
- cr0 &= 0x7fffffff;
- cr0_set(cr0);
- paging_enabled = 0;
-}
-
-void paging_enable()
-{
- u32 cr0 = cr0_get();
- cr0 |= 0x80000000;
- cr0_set(cr0);
- paging_enabled = 1;
-}
-
-void paging_switch_dir(u32 dir)
-{
- cr3_set(dir);
-}
-
-struct page_table_entry *paging_get_page(u32 address, struct page_dir *page_dir)
-{
- struct page_table *page_table;
-
- address /= PAGE_SIZE;
- u32 n = address / PAGE_COUNT;
-
- if (page_dir->entries[n].present == 0) {
- page_table = kmalloc_frames(1);
- memset(page_table, 0, sizeof(struct page_table));
-
- page_dir->entries[n].address = SHIFT((u32)page_table);
- page_dir->entries[n].present = 1;
- page_dir->entries[n].writable = 1;
- page_dir->entries[n].user = 1;
- } else {
- page_table = (void *)UNSHIFT(page_dir->entries[n].address);
- }
-
- return &page_table->entries[address % PAGE_COUNT];
-}
-
-void paging_frame_alloc(struct page_table_entry *page)
-{
- void *ptr = kmalloc_frames(1);
-
- if (page->address != 0) {
- warn("Page is already allocated");
- return;
- }
- page->address = SHIFT((u32)ptr);
- page->present = 1;
- page->user = 1;
-}
-
-void paging_frame_free(struct page_table_entry *page)
-{
- kfree_frames((void *)UNSHIFT(page->address), 1);
- memset((void *)page, 0, sizeof(struct page_table_entry));
-}
-
-struct page_dir *paging_make_dir()
-{
- struct page_dir *ret = kmalloc_frames(1);
-
- memcpy(ret, kernel_page_directory, sizeof(struct page_dir));
-
- return ret;
-}
-
-void paging_free_dir(struct page_dir *page_dir)
-{
- kfree_frames(page_dir, 1);
-} \ No newline at end of file
diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h
deleted file mode 100644
index af7d4a2..0000000
--- a/src/kernel/memory/paging.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef MELVIX_PAGING_H
-#define MELVIX_PAGING_H
-
-#include <stdint.h>
-
-#define PAGE_SIZE 0x1000
-#define PAGE_COUNT 1024
-#define SHIFT(address) ((address) >> 12)
-#define UNSHIFT(address) ((address) << 12)
-
-int paging_enabled;
-
-struct page_table_entry {
- u32 present : 1;
- u32 writable : 1;
- u32 user : 1;
- u32 write_through : 1;
- u32 cache_disable : 1;
- u32 accessed : 1;
- u32 dirty : 1;
- u32 attribute : 1;
- u32 global : 1;
- u32 available : 3;
- u32 address : 20;
-} __attribute__((packed));
-
-struct page_table {
- struct page_table_entry entries[PAGE_COUNT];
-};
-
-struct page_dir_entry {
- u32 present : 1;
- u32 writable : 1;
- u32 user : 1;
- u32 write_through : 1;
- u32 cache_disable : 1;
- u32 accessed : 1;
- u32 reserved : 1;
- u32 page_size : 1;
- u32 global : 1;
- u32 available : 3;
- u32 address : 20;
-} __attribute__((packed));
-
-struct page_dir {
- struct page_dir_entry entries[PAGE_COUNT];
-};
-
-void paging_install();
-void paging_enable();
-void paging_disable();
-void paging_switch_dir(u32 dir);
-
-struct page_table_entry *paging_get_page(u32 address, struct page_dir *page_dir);
-void paging_frame_alloc(struct page_table_entry *page);
-void paging_frame_free(struct page_table_entry *page);
-struct page_dir *paging_make_dir();
-void paging_free_dir();
-
-#endif \ No newline at end of file