diff options
author | Marvin Borner | 2020-06-17 18:31:46 +0200 |
---|---|---|
committer | Marvin Borner | 2020-06-17 18:31:46 +0200 |
commit | eed77bd2970a00d1394ed027ceca5b646e4671ce (patch) | |
tree | c44643d98aed2b6818f2b33417c0dea9c5853094 /src/kernel/memory | |
parent | 49dfa1f4021026bf7c4d77817959c8aa24067016 (diff) |
Started rewrite
Diffstat (limited to 'src/kernel/memory')
-rw-r--r-- | src/kernel/memory/alloc.c | 492 | ||||
-rw-r--r-- | src/kernel/memory/alloc.h | 12 | ||||
-rw-r--r-- | src/kernel/memory/mmap.c | 107 | ||||
-rw-r--r-- | src/kernel/memory/mmap.h | 18 | ||||
-rw-r--r-- | src/kernel/memory/paging.c | 117 | ||||
-rw-r--r-- | src/kernel/memory/paging.h | 60 |
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 |