diff options
-rw-r--r-- | src/kernel/fs/ata.c | 2 | ||||
-rw-r--r-- | src/kernel/fs/elf.c | 10 | ||||
-rw-r--r-- | src/kernel/graphics/vesa.c | 12 | ||||
-rw-r--r-- | src/kernel/kernel.c | 3 | ||||
-rw-r--r-- | src/kernel/lib/memory.c | 10 | ||||
-rw-r--r-- | src/kernel/lib/stdlib/itoa.c | 5 | ||||
-rw-r--r-- | src/kernel/memory/alloc.c | 552 | ||||
-rw-r--r-- | src/kernel/memory/alloc.h | 61 | ||||
-rw-r--r-- | src/kernel/memory/paging.c | 225 | ||||
-rw-r--r-- | src/kernel/memory/paging.h | 75 | ||||
-rw-r--r-- | src/kernel/system.c | 6 |
11 files changed, 310 insertions, 651 deletions
diff --git a/src/kernel/fs/ata.c b/src/kernel/fs/ata.c index d5c758c..2a1ab6f 100644 --- a/src/kernel/fs/ata.c +++ b/src/kernel/fs/ata.c @@ -117,4 +117,4 @@ void read_abs_sectors(uint32_t lba, uint8_t sector_count, uint16_t buf[]) asm("rep insw" ::"c"(SECTOR_SIZE / 2), "d"(sel_base_port + DATA), "D"(buf + i)); i += SECTOR_SIZE / 2; } -}
\ No newline at end of file +} diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index b9ea22a..fe024e3 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -43,9 +43,9 @@ void elf_load(char *path) seg_begin = program_header->vaddr; seg_end = seg_begin + program_header->memsz; - for (uint32_t z = 0; z < seg_end - seg_begin; z += 4096) - paging_map((uint32_t)seg_begin + z, (uint32_t)seg_begin + z, - PT_PRESENT | PT_RW | PT_USED | PT_ALL_PRIV); + /* for (uint32_t z = 0; z < seg_end - seg_begin; z += 4096) */ + /* paging_map((uint32_t)seg_begin + z, (uint32_t)seg_begin + z, */ + /* PT_PRESENT | PT_RW | PT_USED | PT_ALL_PRIV); */ memcpy((void *)seg_begin, file + program_header->offset, program_header->filesz); @@ -68,8 +68,8 @@ void elf_load(char *path) set_kernel_stack(sp); // paging_switch_directory(1); - uint32_t esp = paging_alloc_pages(0x1000); - asm("mov %0, %%esp" ::"r"(esp + 0x1000)); + /* uint32_t esp = paging_alloc_pages(0x1000); */ + /* asm("mov %0, %%esp" ::"r"(esp + 0x1000)); */ log("Jumping to usermode!"); asm volatile("\ diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index e8ef0e0..f116146 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -184,11 +184,11 @@ void set_optimal_resolution() uint32_t fb_size = vbe_width * vbe_height * vbe_bpl; cursor_buffer = kmalloc(fb_size); - for (uint32_t z = 0; z < fb_size; z += 4096) { - paging_map((uint32_t)fb + z, (uint32_t)fb + z, PT_PRESENT | PT_RW | PT_USED); - paging_map((uint32_t)cursor_buffer + z, (uint32_t)cursor_buffer + z, - PT_PRESENT | PT_RW | PT_USED); - } + /* for (uint32_t z = 0; z < fb_size; z += 4096) { */ + /* paging_map((uint32_t)fb + z, (uint32_t)fb + z, PT_PRESENT | PT_RW | PT_USED); */ + /* paging_map((uint32_t)cursor_buffer + z, (uint32_t)cursor_buffer + z, */ + /* PT_PRESENT | PT_RW | PT_USED); */ + /* } */ if (vbe_height > 1440) vesa_set_font(32); @@ -368,4 +368,4 @@ void vesa_set_color(uint32_t color) { vesa_convert_color(terminal_color, color); vesa_convert_color(terminal_background, default_background_color); -}
\ No newline at end of file +} diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index da3a8ef..756721f 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -39,8 +39,9 @@ void kernel_main(uint32_t magic, uint32_t multiboot_address) idt_install(); isrs_install(); irq_install(); - paging_install(multiboot_address); + memory_init(multiboot_address); + paging_install(); multiboot_parse(multiboot_address); // Install drivers diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c index c244052..5347add 100644 --- a/src/kernel/lib/memory.c +++ b/src/kernel/lib/memory.c @@ -52,7 +52,7 @@ uint32_t memory_get_all() uint32_t memory_get_free() { - return memory_get_all() - paging_get_used_pages() * 4; + return memory_get_all() /*- paging_get_used_pages() * 4*/; } void memory_print() @@ -81,12 +81,12 @@ void memory_mmap_init(struct multiboot_tag_mmap *tag) ((struct multiboot_tag_mmap *)tag)->entry_size)) { if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) { debug("Found free memory"); - paging_set_present(mmap->addr, mmap->len >> 12); + /* paging_set_present(mmap->addr, mmap->len >> 12); */ sum += mmap->len; } else if (mmap->type == MULTIBOOT_MEMORY_RESERVED) { debug("Found reserved memory"); - paging_set_present(mmap->addr, mmap->len >> 12); - paging_set_used(mmap->addr, mmap->len >> 12); + /* paging_set_present(mmap->addr, mmap->len >> 12); */ + /* paging_set_used(mmap->addr, mmap->len >> 12); */ } else if (mmap->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE) { debug("Found ACPI reclaimable memory"); } else if (mmap->type == MULTIBOOT_MEMORY_NVS) { @@ -116,4 +116,4 @@ int memory_init(uint32_t multiboot_address) } } return ret; -}
\ No newline at end of file +} diff --git a/src/kernel/lib/stdlib/itoa.c b/src/kernel/lib/stdlib/itoa.c index 94c3351..e6300d9 100644 --- a/src/kernel/lib/stdlib/itoa.c +++ b/src/kernel/lib/stdlib/itoa.c @@ -8,9 +8,6 @@ static const char ITOA_TABLE[] = "0123456789"; char *itoa(int n) { - if (paging_enabled == 0) - return "0"; // kmalloc isn't available - if (!n) { char *ret = (char *)kmalloc(2); ret[0] = '0'; @@ -44,4 +41,4 @@ char *itoa(int n) strinv(ret); return ret; -}
\ No newline at end of file +} diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 174f298..fbf97d8 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -2,478 +2,188 @@ #include <stdint.h> #include <kernel/memory/paging.h> #include <kernel/memory/alloc.h> +#include <kernel/system.h> +#include <kernel/lib/lib.h> -int liballoc_lock() -{ - // cli(); - return 0; -} +uint32_t placement_address; -int liballoc_unlock() -{ - // sti(); - return 0; -} - -void *liballoc_alloc(size_t p) -{ - uint32_t ptr = paging_alloc_pages((uint32_t)p); - return (void *)ptr; -} +struct heap_header *kheap = NULL; +struct heap_header *uheap = NULL; -int liballoc_free(void *ptr, size_t p) +void kheap_init() { - paging_set_free((uint32_t)ptr, (uint32_t)p); - return 0; + placement_address = &ASM_KERNEL_END; + kheap = (struct heap_header *)fmalloc(KHEAP_SIZE); + init_heap(kheap, KHEAP_SIZE); + + // Make user heap + uheap = (struct heap_header *)kmalloc_a(UHEAP_SIZE); + init_heap(uheap, UHEAP_SIZE); + paging_map_user(paging_root_directory, (uint32_t)&uheap, (uint32_t)&uheap); } -#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) { \ - uintptr_t diff; \ - ptr = (void *)((uintptr_t)ptr + ALIGN_INFO); \ - diff = (uintptr_t)ptr & (ALIGNMENT - 1); \ - if (diff != 0) { \ - diff = ALIGNMENT - diff; \ - ptr = (void *)((uintptr_t)ptr + diff); \ - } \ - *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)) = diff + ALIGN_INFO; \ - } - -#define UNALIGN(ptr) \ - if (ALIGNMENT > 1) { \ - uintptr_t diff = *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)); \ - if (diff < (ALIGNMENT + ALIGN_INFO)) { \ - ptr = (void *)((uintptr_t)ptr - diff); \ - } \ - } - -#define LIBALLOC_MAGIC 0x900df00d -#define LIBALLOC_DEAD 0xbaadf00d - -struct liballoc_major { - struct liballoc_major *prev; - struct liballoc_major *next; - unsigned int pages; - unsigned int size; - unsigned int usage; - struct liballoc_minor *first; -}; - -struct liballoc_minor { - struct liballoc_minor *prev; - struct liballoc_minor *next; - struct liballoc_major *block; - unsigned int magic; - unsigned int size; - unsigned int req_size; -}; - -static struct liballoc_major *l_memRoot = NULL; -static struct liballoc_major *l_bestBet = NULL; - -static unsigned int l_pageSize = 4096; -static unsigned int l_pageCount = 16; -static unsigned long long l_allocated = 0; -static unsigned long long l_inuse = 0; - -static long long l_warningCount = 0; -static long long l_errorCount = 0; -static long long l_possibleOverruns = 0; - -static void *liballoc_memset(void *s, int c, size_t n) +void *fmalloc(uint32_t size) { - unsigned int i; - for (i = 0; i < n; i++) - ((char *)s)[i] = c; - - return s; + //assert(placement_address + size < MEM_END); + uint32_t hold = placement_address; + memset((void *)hold, 0, size); + placement_address += size; + return (void *)hold; } -static void *liballoc_memcpy(void *s1, const void *s2, size_t n) +void *kmalloc_a(uint32_t size) { - char *cdest; - char *csrc; - unsigned int *ldest = (unsigned int *)s1; - unsigned int *lsrc = (unsigned int *)s2; - - while (n >= sizeof(unsigned int)) { - *ldest++ = *lsrc++; - n -= sizeof(unsigned int); - } + //assert(((placement_address & 0xFFFFF000) + 0x1000) + size < MEM_END); + placement_address &= 0xFFFFF000; + placement_address += 0x1000; - cdest = (char *)ldest; - csrc = (char *)lsrc; + uint32_t hold = placement_address; + placement_address += size; - while (n > 0) { - *cdest++ = *csrc++; - n -= 1; - } - return s1; + return (void *)hold; } -static struct liballoc_major *allocate_new_page(unsigned int size) +struct heap_header *find_sized_heap(struct heap_header *heap, size_t size) { - unsigned int st; - struct liballoc_major *maj; + while ((heap->size < HEAP_FIND_SIZE + size) || (heap->free != true)) { + assert(heap->magic == KHEAP_MAGIC); + assert(heap->magic2 == KHEAP_MAGIC2); + struct heap_footer *foot = + (struct heap_footer *)((uint32_t)heap + HEAP_S + heap->size); + assert(foot->magic == KHEAP_MAGIC); + assert(foot->magic2 == KHEAP_MAGIC2); - st = size + sizeof(struct liballoc_major); - st += sizeof(struct liballoc_minor); + if (foot->size == KHEAP_END) + panic("Out of heap space"); - if ((st % l_pageSize) == 0) - st = st / (l_pageSize); - else - st = st / (l_pageSize) + 1; + if (foot->size != heap->size) + panic("Heap footer/header mismatch"); - if (st < l_pageCount) - st = l_pageCount; - - maj = (struct liballoc_major *)liballoc_alloc(st); - - if (maj == NULL) { - l_warningCount += 1; - return NULL; + heap = (struct heap_header *)((uint32_t)foot + sizeof(struct heap_footer)); } - maj->prev = NULL; - maj->next = NULL; - maj->pages = st; - maj->size = st * l_pageSize; - maj->usage = sizeof(struct liballoc_major); - maj->first = NULL; - - l_allocated += maj->size; - - return maj; + return heap; } -void *PREFIX(malloc)(size_t req_size) +void split_heap(struct heap_header *heap, size_t size) { - int startedBet = 0; - unsigned long long bestSize = 0; - void *p = NULL; - uintptr_t diff; - struct liballoc_major *maj; - struct liballoc_minor *min; - struct liballoc_minor *new_min; - unsigned long size = req_size; - - if (ALIGNMENT > 1) { - size += ALIGNMENT + ALIGN_INFO; - } - - liballoc_lock(); - - if (size == 0) { - l_warningCount += 1; - liballoc_unlock(); - return PREFIX(malloc)(1); - } - - if (l_memRoot == NULL) { - l_memRoot = allocate_new_page(size); - if (l_memRoot == NULL) { - liballoc_unlock(); - return NULL; - } - } + struct heap_footer *foot = (struct heap_footer *)((uint32_t)heap + HEAP_S + size); + foot->magic = KHEAP_MAGIC; + foot->magic2 = KHEAP_MAGIC2; + foot->size = size; - maj = l_memRoot; - startedBet = 0; + size_t new_size = heap->size - HEAP_TOTAL - size; + heap->size = size; - if (l_bestBet != NULL) { - bestSize = l_bestBet->size - l_bestBet->usage; + heap = (struct heap_header *)((uint32_t)foot + sizeof(struct heap_footer)); + heap->size = new_size; + heap->free = true; + heap->magic = KHEAP_MAGIC; + heap->magic2 = KHEAP_MAGIC2; - if (bestSize > (size + sizeof(struct liballoc_minor))) { - maj = l_bestBet; - startedBet = 1; - } + foot = (struct heap_footer *)((uint32_t)heap + HEAP_S + heap->size); + if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { + warn("Invalid footer in split"); } - while (maj != NULL) { - diff = maj->size - maj->usage; - if (bestSize < diff) { - l_bestBet = maj; - bestSize = diff; - } - -#ifdef USE_CASE1 - if (diff < (size + sizeof(struct liballoc_minor))) { - if (maj->next != NULL) { - maj = maj->next; - continue; - } - - if (startedBet == 1) { - maj = l_memRoot; - startedBet = 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 *)((uintptr_t)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 *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - ALIGN(p); - liballoc_unlock(); - return p; - } -#endif - -#ifdef USE_CASE3 - diff = (uintptr_t)(maj->first); - diff -= (uintptr_t)maj; - diff -= sizeof(struct liballoc_major); - - if (diff >= (size + sizeof(struct liballoc_minor))) { - maj->first->prev = (struct liballoc_minor *)((uintptr_t)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 *)((uintptr_t)(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 = (uintptr_t)(maj) + maj->size; - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - if (diff >= (size + sizeof(struct liballoc_minor))) { - min->next = (struct liballoc_minor - *)((uintptr_t)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 *)((uintptr_t)min + - sizeof(struct liballoc_minor)); - ALIGN(p); - liballoc_unlock(); - return p; - } - } - - if (min->next != NULL) { - diff = (uintptr_t)(min->next); - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - - if (diff >= (size + sizeof(struct liballoc_minor))) { - new_min = (struct liballoc_minor - *)((uintptr_t)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 *)((uintptr_t)new_min + - sizeof(struct liballoc_minor)); - ALIGN(p); - liballoc_unlock(); - return p; - } - } - - min = min->next; - } -#endif - -#ifdef USE_CASE5 - if (maj->next == NULL) { - if (startedBet == 1) { - maj = l_memRoot; - startedBet = 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; + if (foot->size != KHEAP_END) + foot->size = new_size; } -void PREFIX(free)(void *ptr) +void free_internal(struct heap_header *heap, void *address) { - struct liballoc_minor *min; - struct liballoc_major *maj; - - if (ptr == NULL) { - l_warningCount += 1; + struct heap_header *head = (struct heap_header *)((uint32_t)address - HEAP_S); + if (head == heap) { + warn("Can't collapse top of heap"); + head->free = true; return; } - UNALIGN(ptr); - liballoc_lock(); + if ((head->magic != KHEAP_MAGIC) || (head->magic2 != KHEAP_MAGIC2)) { + //warn("Invalid header in heap"); + return; + } - min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); + struct heap_footer *foot = (struct heap_footer *)((uint32_t)head + HEAP_S + head->size); + if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) + panic("Bad heap call"); - if (min->magic != LIBALLOC_MAGIC) { - l_errorCount += 1; + foot = (struct heap_footer *)((uint32_t)head - sizeof(struct heap_footer)); + if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { + //warn("Invalid footer in heap"); + return; + } - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || - ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { - l_possibleOverruns += 1; - } + if (foot->size == KHEAP_END) + panic("Impossible condition for heap"); - liballoc_unlock(); + heap = (struct heap_header *)((uint32_t)foot - foot->size - HEAP_S); + if ((heap->magic != KHEAP_MAGIC) || (heap->magic2 != KHEAP_MAGIC2)) { + warn("Invalid parent in heap"); 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_memRoot == maj) - l_memRoot = maj->next; - if (l_bestBet == maj) - l_bestBet = 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_bestBet != NULL) { - int bestSize = l_bestBet->size - l_bestBet->usage; - int majSize = maj->size - maj->usage; - if (majSize > bestSize) - l_bestBet = maj; - } + foot = (struct heap_footer *)((uint32_t)heap + (heap->size + head->size + HEAP_TOTAL) + + HEAP_S); + if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { + /*vga_puts("Footer with size of "); + vga_puts_hex(foot->size); + vga_puts(" / head size of "); + vga_puts_hex(heap->size); + vga_puts("\n"); + dump_struct(foot, sizeof(struct heap_footer)); + warn("fatal arithmetic error in free() call"); + */ + return; } - liballoc_unlock(); + + heap->size += head->size + HEAP_TOTAL; + foot->size = heap->size; } -void *PREFIX(calloc)(size_t nobj, size_t size) +void *malloc_internal(struct heap_header *heap, size_t size) { - int real_size; - void *p; - - real_size = nobj * size; - - p = PREFIX(malloc)(real_size); - - liballoc_memset(p, 0, real_size); - - return p; + heap = find_sized_heap(heap, size + 8); + heap->free = false; + split_heap(heap, size); + return (void *)((uint32_t)heap + HEAP_S); } -void *PREFIX(realloc)(void *p, size_t size) +void init_heap(struct heap_header *heap, size_t size) { - void *ptr; - struct liballoc_minor *min; - unsigned int real_size; - - if (size == 0) { - PREFIX(free)(p); - return NULL; - } - - if (p == NULL) - return PREFIX(malloc)(size); - - ptr = p; - UNALIGN(ptr); - liballoc_lock(); - min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - if (min->magic != LIBALLOC_MAGIC) { - l_errorCount += 1; - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || - ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { - l_possibleOverruns += 1; - } + heap->magic = KHEAP_MAGIC; + heap->magic2 = KHEAP_MAGIC2; + heap->free = true; + heap->size = size - HEAP_TOTAL; + + struct heap_footer *foot = (struct heap_footer *)((uint32_t)heap + HEAP_S + heap->size); + foot->magic = KHEAP_MAGIC; + foot->magic2 = KHEAP_MAGIC2; + foot->size = KHEAP_END; +} - liballoc_unlock(); - return NULL; - } +void *kmalloc(uint32_t size) +{ + if (kheap == NULL) + return fmalloc(size); - real_size = min->req_size; + return malloc_internal(kheap, size); +} - if (real_size >= size) { - min->req_size = size; - liballoc_unlock(); - return p; - } +void kfree(void *address) +{ + if (kheap == NULL) + return; - liballoc_unlock(); + free_internal(kheap, address); +} - ptr = PREFIX(malloc)(size); - liballoc_memcpy(ptr, p, real_size); - PREFIX(free)(p); +void *umalloc(size_t size) +{ + return malloc_internal(uheap, size); +} - return ptr; -}
\ No newline at end of file +void ufree(void *address) +{ + free_internal(uheap, address); +} diff --git a/src/kernel/memory/alloc.h b/src/kernel/memory/alloc.h index 3ddc8d8..16d61f5 100644 --- a/src/kernel/memory/alloc.h +++ b/src/kernel/memory/alloc.h @@ -2,23 +2,44 @@ #define MELVIX_ALLOC_H #include <stddef.h> - -#define PREFIX(func) k##func - -int liballoc_lock(); - -int liballoc_unlock(); - -void *liballoc_alloc(size_t); - -int liballoc_free(void *, size_t); - -void *PREFIX(malloc)(size_t); - -void *PREFIX(realloc)(void *, size_t); - -void *PREFIX(calloc)(size_t, size_t); - -void PREFIX(free)(void *); - -#endif
\ No newline at end of file +#include <stdint.h> +#include <stdbool.h> + +#define KHEAP_MAGIC 0x04206969 +#define KHEAP_MAGIC2 0xDEADBEEF +#define KHEAP_END 0xFFFFDEAD +#define MEM_END 0x8000000 + +struct heap_header { + uint32_t magic; + bool free; + uint32_t size; + uint32_t magic2; +}; + +struct heap_footer { + uint32_t magic; + uint32_t size; + uint32_t magic2; +}; + +void kheap_init(); + +void *fmalloc(uint32_t size); +void *kmalloc(uint32_t size); +void *kmalloc_a(uint32_t size); +void kfree(void *ptr); + +void *umalloc(size_t size); +void ufree(void *address); + +void init_heap(struct heap_header *heap, size_t size); + +#define KHEAP_SIZE 0xFFFFF +#define UHEAP_SIZE 0xFFFFF +#define HEAP_S (sizeof(struct heap_header)) +#define HEAP_TOTAL (sizeof(struct heap_footer) + HEAP_S) +#define HEAP_MINIMUM 1 +#define HEAP_FIND_SIZE (HEAP_TOTAL + HEAP_MINIMUM) + +#endif diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index e237a90..910b569 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -1,198 +1,143 @@ #include <stdint.h> #include <kernel/memory/paging.h> +#include <kernel/memory/alloc.h> #include <kernel/system.h> #include <kernel/lib/lib.h> #include <kernel/io/io.h> #include <kernel/acpi/acpi.h> -int paging_enabled = 0; +struct page_directory *paging_current_directory = NULL; +struct page_directory *paging_root_directory = NULL; -uint32_t *current_page_directory; -uint32_t (*current_page_tables)[1024]; -uint32_t kernel_page_directory[1024] __attribute__((aligned(4096))); -uint32_t kernel_page_tables[1024][1024] __attribute__((aligned(4096))); -uint32_t user_page_directory[1024] __attribute__((aligned(4096))); -uint32_t user_page_tables[1024][1024] __attribute__((aligned(4096))); +/* void paging_install(uint32_t multiboot_address) */ +/* { */ +/* if (!memory_init(multiboot_address)) */ +/* paging_set_present(0, memory_get_all() >> 3); // /4 */ +/* paging_set_used(0, ((uint32_t)ASM_KERNEL_END >> 12) + 1); // /4096 */ +/* } */ -void paging_init() +struct page_table *get_cr3() { - for (uint32_t i = 0; i < 1024; i++) { - for (uint32_t j = 0; j < 1024; j++) { - current_page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW; - } - } - - for (uint32_t i = 0; i < 1024; i++) { - current_page_directory[i] = ((uint32_t)current_page_tables[i]) | PD_RW | PD_PRESENT; - } -} - -void paging_install(uint32_t multiboot_address) -{ - // User paging - paging_switch_directory(1); - paging_init(); - paging_set_user(0, memory_get_all() >> 3); - - // Kernel paging - paging_switch_directory(0); - paging_init(); - - // if mmap approach didn't work - if (!memory_init(multiboot_address)) - paging_set_present(0, memory_get_all() >> 3); // /4 - paging_set_used(0, ((uint32_t)ASM_KERNEL_END >> 12) + 1); // /4096 - // paging_set_user(0, memory_get_all() >> 3); // HMM - - paging_enable(); - log("Installed paging"); + uint32_t cr3; + asm volatile("movl %%cr3, %%eax" : "=a"(cr3)); + return (struct page_table *)cr3; } -void paging_disable() +uint32_t get_cr0() { uint32_t cr0; - asm("mov %%cr0, %0" : "=r"(cr0)); - cr0 &= 0x7fffffff; - asm("mov %0, %%cr0" ::"r"(cr0)); - paging_enabled = 0; + asm volatile("movl %%cr0, %%eax" : "=a"(cr0)); + return cr0; } -void paging_enable() +void set_cr3(struct page_directory *dir) { - asm("mov %0, %%cr3" ::"r"(current_page_directory)); - uint32_t cr0; - asm("mov %%cr0, %0" : "=r"(cr0)); - cr0 |= 0x80000000; - asm("mov %0, %%cr0" ::"r"(cr0)); - paging_enabled = 1; + uint32_t addr = (uint32_t)&dir->tables[0]; + asm volatile("movl %%eax, %%cr3" ::"a"(addr)); } -void paging_switch_directory(int user) +void set_cr0(uint32_t cr0) { - if (user == 1) { - current_page_tables = user_page_tables; - current_page_directory = user_page_directory; - } else { - current_page_tables = kernel_page_tables; - current_page_directory = kernel_page_directory; - } - asm("mov %0, %%cr3" ::"r"(current_page_directory)); + asm volatile("movl %%eax, %%cr0" ::"a"(cr0)); } -void invlpg(uint32_t addr) +void paging_switch_directory(struct page_directory *dir) { - asm("invlpg (%0)" ::"r"(addr) : "memory"); + set_cr3(dir); + set_cr0(get_cr0() | 0x80000000); } -void paging_map(uint32_t phy, uint32_t virt, uint16_t flags) +struct page_directory *paging_make_directory() { - uint32_t pdi = virt >> 22; - uint32_t pti = virt >> 12 & 0x03FF; - current_page_tables[pdi][pti] = phy | flags; - invlpg(virt); -} + struct page_directory *dir = + (struct page_directory *)kmalloc_a(sizeof(struct page_directory)); -uint32_t paging_get_phys(uint32_t virt) -{ - uint32_t pdi = virt >> 22; - uint32_t pti = (virt >> 12) & 0x03FF; - return current_page_tables[pdi][pti] & 0xFFFFF000; -} + for (int i = 0; i < 1024; i++) + dir->tables[i] = EMPTY_TAB; -uint16_t paging_get_flags(uint32_t virt) -{ - uint32_t pdi = virt >> 22; - uint32_t pti = (virt >> 12) & 0x03FF; - return current_page_tables[pdi][pti] & 0xFFF; + return dir; } -void paging_set_flag_up(uint32_t virt, uint32_t count, uint32_t flag) +struct page_table *paging_make_table() { - uint32_t page_n = virt / 0x1000; - for (uint32_t i = page_n; i < page_n + count; i++) { - current_page_tables[i / 1024][i % 1024] |= flag; - invlpg(i * 0x1000); + struct page_table *tab = (struct page_table *)kmalloc_a(sizeof(struct page_table)); + + for (int i = 0; i < 1024; i++) { + tab->pages[i].present = 0; + tab->pages[i].rw = 1; } + + return tab; } -void paging_set_flag_down(uint32_t virt, uint32_t count, uint32_t flag) +void paging_map(struct page_directory *dir, uint32_t phys, uint32_t virt) { - uint32_t page_n = virt / 0x1000; - for (uint32_t i = page_n; i < page_n + count; i++) { - current_page_tables[i / 1024][i % 1024] &= ~flag; - invlpg(i * 0x1000); + short id = virt >> 22; + struct page_table *tab = paging_make_table(); + + dir->tables[id] = ((struct page_table *)((uint32_t)tab | 3)); // RW + + for (int i = 0; i < 1024; i++) { + tab->pages[i].frame = phys >> 12; + tab->pages[i].present = 1; + phys += 4096; } } -void paging_set_present(uint32_t virt, uint32_t count) +void paging_map_user(struct page_directory *dir, uint32_t phys, uint32_t virt) { - paging_set_flag_up(virt, count, PT_PRESENT); -} + short id = virt >> 22; + struct page_table *tab = paging_make_table(); -void paging_set_absent(uint32_t virt, uint32_t count) -{ - paging_set_flag_down(virt, count, PT_PRESENT); -} + dir->tables[id] = ((struct page_table *)((uint32_t)tab | 3 | 4)); // RW + usermode -void paging_set_used(uint32_t virt, uint32_t count) -{ - paging_set_flag_up(virt, count, PT_USED); + int i; + for (i = 0; i < 1024; i++) { + tab->pages[i].frame = phys >> 12; + tab->pages[i].present = 1; + tab->pages[i].user = 1; + phys += 4096; + } } -void paging_set_free(uint32_t virt, uint32_t count) +void paging_install() { - paging_set_flag_down(virt, count, PT_USED); -} + kheap_init(); -void paging_set_user(uint32_t virt, uint32_t count) -{ - uint32_t page_n = virt / 0x1000; - for (uint32_t i = page_n; i < page_n + count; i += 1024) { - current_page_directory[i / 1024] |= PD_ALL_PRIV; - } - paging_set_flag_up(virt, count, PT_ALL_PRIV); + paging_current_directory = paging_make_directory(); + paging_root_directory = paging_current_directory; + + for (uint32_t i = 0; i < 0xF0000000; i += PAGE_S) + paging_map(paging_root_directory, i, i); } -uint32_t paging_find_pages(uint32_t count) +void paging_convert_page(struct page_directory *kdir) { - uint32_t continuous = 0; - uint32_t startDir = 0; - uint32_t startPage = 0; - for (uint32_t i = 0; i < 1024; i++) { - for (uint32_t j = 0; j < 1024; j++) { - if (!(current_page_tables[i][j] & PT_PRESENT) || - (current_page_tables[i][j] & PT_USED)) { - continuous = 0; - startDir = i; - startPage = j + 1; - } else { - if (++continuous == count) - return (startDir * 0x400000) + (startPage * 0x1000); - } + for (int i = 0; i < 1024; i++) { + kdir->tables[i] = (struct page_table *)((uint32_t)kdir->tables[i] | 4); // Usermode + + if (((uint32_t)kdir->tables[i]) & 1) { // Is present + for (int j = 0; j < 1024; j++) + kdir->tables[i]->pages[j].user = 1; // Usermode } } - - panic("Out of memory!"); - return 0; } -uint32_t paging_alloc_pages(uint32_t count) +struct page_directory *paging_copy_user_directory(struct page_directory *dir) { - uint32_t ptr = paging_find_pages(count); - paging_set_used(ptr, count); - paging_set_user(ptr, count); - return ptr; -} + struct page_directory *copy = paging_make_directory(); + memcpy(copy, paging_root_directory, sizeof(struct page_directory)); -uint32_t paging_get_used_pages() -{ - uint32_t n = 0; for (uint32_t i = 0; i < 1024; i++) { - for (uint32_t j = 0; j < 1024; j++) { - uint8_t flags = current_page_tables[i][j] & PT_USED; - if (flags == 1) - n++; + if (((uint32_t)dir->tables[i]) & 4) { + struct page_table *tab = + (struct page_table *)((uint32_t)dir->tables[i] & 0xFFFFF000); + + void *buffer = kmalloc_a(PAGE_S); + memcpy(buffer, (void *)(tab->pages[0].frame << 12), PAGE_S); + paging_map_user(copy, (uint32_t)buffer, (uint32_t)i << 22); } } - return n; + + return copy; } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 1578e2a..c02cd3a 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -3,62 +3,47 @@ #include <stdint.h> -#define PD_PRESENT 1 << 0 -#define PD_RW 1 << 1 -#define PD_ALL_PRIV 1 << 2 -#define PD_WRITETHR 1 << 3 -#define PD_CACHE_D 1 << 4 -#define PD_ACCESSED 1 << 5 -#define PD_4M_PAGE 1 << 7 +struct page { + uint32_t present : 1; + uint32_t rw : 1; + uint32_t user : 1; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t unused : 7; + uint32_t frame : 20; +}; -#define PT_PRESENT 1 << 0 -#define PT_RW 1 << 1 -#define PT_ALL_PRIV 1 << 2 -#define PT_WRITETHR 1 << 3 -#define PT_CACHE_D 1 << 4 -#define PT_ACCESSED 1 << 5 -#define PT_DIRTY 1 << 6 -#define PT_GLOBAL 1 << 8 -#define PT_USED 1 << 9 +struct page_table { + struct page pages[1024]; +}; -int paging_enabled; +struct page_directory { + struct page_table *tables[1024]; +}; -uint32_t *current_page_directory; +struct page_directory *paging_root_directory; -void paging_install(uint32_t multiboot_address); +struct page_table *get_cr3(); +uint32_t get_cr0(); -void paging_enable(); +void set_cr3(struct page_directory *dir); +void set_cr0(uint32_t new_cr0); -void paging_disable(); +void paging_switch_directory(struct page_directory *dir); -void paging_switch_directory(int user); +struct page_directory *paging_make_directory(); +struct page_table *paging_make_table(); -void paging_map(uint32_t phy, uint32_t virt, uint16_t flags); +void paging_install(); -uint32_t paging_get_phys(uint32_t virt); +void paging_map(struct page_directory *cr3, uint32_t virt, uint32_t phys); +void paging_map_user(struct page_directory *cr3, uint32_t virt, uint32_t phys); -uint16_t paging_get_flags(uint32_t virt); +void paging_convert_page(struct page_directory *kdir); -void paging_set_flags(uint32_t virt, uint32_t count, uint16_t flags); +struct page_directory *paging_copy_user_directory(struct page_directory *dir); -void paging_set_flag_up(uint32_t virt, uint32_t count, uint32_t flag); - -void paging_set_flag_down(uint32_t virt, uint32_t count, uint32_t flag); - -void paging_set_present(uint32_t virt, uint32_t count); - -void paging_set_absent(uint32_t virt, uint32_t count); - -void paging_set_used(uint32_t virt, uint32_t count); - -void paging_set_free(uint32_t virt, uint32_t count); - -void paging_set_user(uint32_t virt, uint32_t count); - -uint32_t paging_find_pages(uint32_t count); - -uint32_t paging_alloc_pages(uint32_t count); - -uint32_t paging_get_used_pages(); +#define EMPTY_TAB ((struct page_table *)0x00000002) +#define PAGE_S 0x400000 #endif diff --git a/src/kernel/system.c b/src/kernel/system.c index f2e3d55..18fbaf4 100644 --- a/src/kernel/system.c +++ b/src/kernel/system.c @@ -121,7 +121,7 @@ loop: void v86(uint8_t code, regs16_t *regs) { - paging_disable(); + /* paging_disable(); */ int32(code, regs); - paging_enable(); -}
\ No newline at end of file + /* paging_enable(); */ +} |