diff options
-rw-r--r-- | kernel/arch/i386/mmu.c | 41 | ||||
-rw-r--r-- | kernel/includes/mmu.h | 4 | ||||
-rw-r--r-- | kernel/kmalloc.c | 24 | ||||
-rw-r--r-- | kernel/kmalloc.h | 4 | ||||
-rw-r--r-- | kernel/sched/scheduler.c | 6 | ||||
-rw-r--r-- | userland/libc/malloc/malloc.c | 2 |
6 files changed, 68 insertions, 13 deletions
diff --git a/kernel/arch/i386/mmu.c b/kernel/arch/i386/mmu.c index 53b2156..2c05fb6 100644 --- a/kernel/arch/i386/mmu.c +++ b/kernel/arch/i386/mmu.c @@ -9,9 +9,6 @@ #define INDEX_FROM_BIT(a) (a / (32)) #define OFFSET_FROM_BIT(a) (a % (32)) -#define PAGE_ALLOCATE 1 -#define PAGE_NO_ALLOCATE 0 - PageDirectory *kernel_directory; PageDirectory real_kernel_directory; PageDirectory *active_directory = 0; @@ -92,7 +89,7 @@ Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, u32 physical; directory->tables[table_index] = - (PageTable *)ksbrk_physical(sizeof(PageTable), (void **)&physical); + (PageTable *)kmalloc_align(sizeof(PageTable), (void **)&physical); memset(directory->tables[table_index], 0, sizeof(PageTable)); directory->physical_tables[table_index] = (u32)physical | ((set_user) ? 0x7 : 0x3); @@ -157,7 +154,7 @@ PageDirectory *get_active_pagedirectory(void) { PageTable *clone_table(u32 src_index, PageDirectory *src_directory, u32 *physical_address) { PageTable *new_table = - ksbrk_physical(sizeof(PageTable), (void **)physical_address); + kmalloc_align(sizeof(PageTable), (void **)physical_address); PageTable *src = src_directory->tables[src_index]; // Copy all the pages @@ -214,7 +211,7 @@ PageTable *clone_table(u32 src_index, PageDirectory *src_directory, PageTable *copy_table(PageTable *src, u32 *physical_address) { PageTable *new_table = - ksbrk_physical(sizeof(PageTable), (void **)physical_address); + kmalloc_align(sizeof(PageTable), (void **)physical_address); // copy all the pages for (u16 i = 0; i < 1024; i++) { @@ -239,7 +236,7 @@ PageDirectory *clone_directory(PageDirectory *original) { u32 physical_address; PageDirectory *new_directory = - ksbrk_physical(sizeof(PageDirectory), (void **)&physical_address); + kmalloc_align(sizeof(PageDirectory), (void **)&physical_address); u32 offset = (u32)new_directory->physical_tables - (u32)new_directory; new_directory->physical_address = physical_address + offset; @@ -388,6 +385,34 @@ void *allocate_frame(Page *page, int rw, int is_kernel) { return (void *)(frame_address * 0x1000); } +void mmu_free_pagedirectory(PageDirectory *pd) { + for (int i = 0; i < 1024; i++) { + if (!pd->tables[i]) { + continue; + } + if (pd->tables[i] == kernel_directory->tables[i]) { + continue; + } + + for (int j = 0; j < 1024; j++) { + Page *page = &(pd->tables[i]->pages[j]); + if (!page) { + continue; + } + if (!page->present) { + continue; + } + if (!page->frame) { + continue; + } + write_to_frame(((u32)page->frame) * 0x1000, 0); + } + kmalloc_align_free(pd->tables[i], sizeof(PageTable)); + pd->tables[i] = NULL; + } + kmalloc_align_free(pd, sizeof(PageDirectory)); +} + void mmu_free_address_range(void *ptr, size_t length, PageDirectory *pd) { size_t num_pages = (size_t)align_page((void *)length) / PAGE_SIZE; for (size_t i = 0; i < num_pages; i++, ptr += PAGE_SIZE) { @@ -581,7 +606,7 @@ void create_table(int table_index) { u32 physical; kernel_directory->tables[table_index] = (PageTable *)0xDEADBEEF; kernel_directory->tables[table_index] = - (PageTable *)ksbrk_physical(sizeof(PageTable), (void **)&physical); + (PageTable *)kmalloc_align(sizeof(PageTable), (void **)&physical); memset(kernel_directory->tables[table_index], 0, sizeof(PageTable)); kernel_directory->physical_tables[table_index] = (u32)physical | 0x3; } diff --git a/kernel/includes/mmu.h b/kernel/includes/mmu.h index 43814d5..211a950 100644 --- a/kernel/includes/mmu.h +++ b/kernel/includes/mmu.h @@ -9,6 +9,9 @@ typedef u8 mmu_flags; #define MMU_FLAG_RW (1 << 0) #define MMU_FLAG_KERNEL (1 << 1) +#define PAGE_ALLOCATE 1 +#define PAGE_NO_ALLOCATE 0 + #define PAGE_SIZE ((uintptr_t)0x1000) #define next_page(_ptr) \ ((_ptr) + (PAGE_SIZE - (((uintptr_t)_ptr) & (PAGE_SIZE - 1)))) @@ -37,6 +40,7 @@ typedef struct PageDirectory { int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags, PageDirectory *pd); +void mmu_free_pagedirectory(PageDirectory *pd); void mmu_allocate_shared_kernel_region(void *rc, size_t n); void *mmu_find_unallocated_virtual_range(void *addr, size_t length); void mmu_remove_virtual_physical_address_mapping(void *ptr, size_t length); diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c index 7138d61..59cc93d 100644 --- a/kernel/kmalloc.c +++ b/kernel/kmalloc.c @@ -2,12 +2,36 @@ #include <kmalloc.h> #include <ksbrk.h> #include <math.h> +#include <mmu.h> #include <random.h> #define NEW_ALLOC_SIZE 0x5000 #define IS_FREE (1 << 0) #define IS_FINAL (1 << 1) +void *kmalloc_align(size_t s, void **physical) { + // TODO: It should reuse virtual regions so that it does not run out + // of address space. + return ksbrk_physical(s, physical); +} + +void kmalloc_align_free(void *p, size_t s) { + for (int i = 0; i < s; i += 0x1000) { + Page *page = get_page((char *)p + i, NULL, PAGE_NO_ALLOCATE, 0); + if (!page) { + continue; + } + if (!page->present) { + continue; + } + if (!page->frame) { + continue; + } + write_to_frame(((u32)page->frame) * 0x1000, 0); + page->present = 0; + } +} + typedef struct MallocHeader { u64 magic; u32 size; diff --git a/kernel/kmalloc.h b/kernel/kmalloc.h index 8c55cb4..8b9d59d 100644 --- a/kernel/kmalloc.h +++ b/kernel/kmalloc.h @@ -4,10 +4,12 @@ #include <string.h> #include <typedefs.h> +void *kmalloc_align(size_t s, void **physical); +void kmalloc_align_free(void *p, size_t s); + void kmalloc_allocate_heap(void); void *kmalloc(size_t s); -void *kmalloc_align(size_t s); void *krealloc(void *ptr, size_t size); void *kreallocarray(void *ptr, size_t nmemb, size_t size); void *kallocarray(size_t nmemb, size_t size); diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c index 52e4848..45969b0 100644 --- a/kernel/sched/scheduler.c +++ b/kernel/sched/scheduler.c @@ -191,9 +191,6 @@ void free_process(process_t *p) { mmu_remove_virtual_physical_address_mapping(m->u_address, m->length); } - // NOTE: Kernel stuff begins at 0x90000000 - mmu_free_address_range((void *)0x1000, 0x90000000, p->cr3); - list_free(&p->read_list); list_free(&p->write_list); list_free(&p->disconnect_list); @@ -202,9 +199,12 @@ void free_process(process_t *p) { list_free(&p->event_queue); list_free(&p->file_descriptors); kfree(p->tcb); + + mmu_free_pagedirectory(p->cr3); } void exit_process(process_t *p, int status) { + disable_interrupts(); assert(p->pid != 1); if (p->parent) { p->parent->halts[WAIT_CHILD_HALT] = 0; diff --git a/userland/libc/malloc/malloc.c b/userland/libc/malloc/malloc.c index 1c992ef..bd880b8 100644 --- a/userland/libc/malloc/malloc.c +++ b/userland/libc/malloc/malloc.c @@ -4,7 +4,7 @@ #include <stddef.h> #include <stdlib.h> #include <typedefs.h> -#define NEW_ALLOC_SIZE 0x20000 +#define NEW_ALLOC_SIZE 0x5000 #define IS_FREE (1 << 0) #define IS_FINAL (1 << 1) |