diff options
author | Marvin Borner | 2020-05-13 21:28:56 +0200 |
---|---|---|
committer | Marvin Borner | 2020-05-13 22:12:41 +0200 |
commit | a9c7529dcca845d98192ece62be70f752972216b (patch) | |
tree | 666d49ceb411a669abe6191151b2238fd7156c30 | |
parent | e1a6ed079303dc7d218f1d5326a13b6755781271 (diff) |
Replaced alloc.h with liballoc
And many more adaptions to the lib
31 files changed, 842 insertions, 565 deletions
diff --git a/src/kernel/acpi/acpi.c b/src/kernel/acpi/acpi.c index 9feed08..6e1811c 100644 --- a/src/kernel/acpi/acpi.c +++ b/src/kernel/acpi/acpi.c @@ -32,11 +32,11 @@ void acpi_init(struct rsdp *rsdp) // TODO: Fix ACPI table discovering (HPET & MADT missing) // TODO: Fix ACPI breaking VESA (why?!) - struct sdt_header *header = (struct sdt_header *)kmalloc(sizeof(struct sdt_header)); - rsdt = (struct rsdt *)kmalloc(sizeof(struct rsdt)); - fadt = (struct fadt *)kmalloc(sizeof(struct fadt)); - hpet = (struct hpet *)kmalloc(sizeof(struct hpet)); - madt = (struct madt *)kmalloc(sizeof(struct madt)); + struct sdt_header *header = (struct sdt_header *)malloc(sizeof(struct sdt_header)); + rsdt = (struct rsdt *)malloc(sizeof(struct rsdt)); + fadt = (struct fadt *)malloc(sizeof(struct fadt)); + hpet = (struct hpet *)malloc(sizeof(struct hpet)); + madt = (struct madt *)malloc(sizeof(struct madt)); if (strncmp(rsdp->signature, "RSD PTR ", 8) == 0) { memcpy(rsdt, rsdp->rsdt_address, sizeof(struct rsdt) + 32); @@ -72,7 +72,7 @@ void acpi_init(struct rsdp *rsdp) } else { warn("Wrong RSD signature!"); } - kfree(header); + free(header); } void acpi_old_init(struct multiboot_tag_old_acpi *tag) diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index c89fd2e..a67ab6a 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -46,23 +46,23 @@ struct process *elf_load(char *path) proc->registers.eip = header->entry; paging_switch_directory(proc->cr3); - u32 stk = (u32)kmalloc_a(PAGE_S); - proc->registers.useresp = 0x40000000 - (PAGE_S / 2); + u32 stk = (u32)malloc(PAGE_SIZE); + proc->registers.useresp = 0x40000000 - (PAGE_SIZE / 2); proc->registers.ebp = proc->registers.useresp; proc->registers.esp = proc->registers.useresp; - paging_map_user(proc->cr3, stk, 0x40000000 - PAGE_S); + paging_map(stk, 0x40000000 - PAGE_SIZE, PT_USER); for (int i = 0; i < header->phnum; i++, program_header++) { switch (program_header->type) { case 0: break; case 1: { - u32 loc = (u32)kmalloc_a(PAGE_S); - paging_map_user(proc->cr3, loc, program_header->vaddr); + u32 loc = (u32)malloc(PAGE_SIZE); + paging_map(loc, program_header->vaddr, PT_USER); memcpy((void *)program_header->vaddr, ((void *)((u32)file) + program_header->offset), program_header->filesz); - if (program_header->filesz > PAGE_S) + if (program_header->filesz > PAGE_SIZE) panic("ELF binary section too large"); break; } @@ -71,6 +71,6 @@ struct process *elf_load(char *path) } } - paging_switch_directory(paging_root_directory); + paging_switch_directory(paging_kernel_directory); return proc; }
\ No newline at end of file diff --git a/src/kernel/fs/ext2.c b/src/kernel/fs/ext2.c index 3193f87..70c72aa 100644 --- a/src/kernel/fs/ext2.c +++ b/src/kernel/fs/ext2.c @@ -78,7 +78,7 @@ static void load_bgdt() read_abs_sectors(bgdt_lba, bgdt_sectors, buf); u32 bgdt_size = sizeof(struct bgd) * num_groups; - bgdt = kmalloc(bgdt_size); + bgdt = malloc(bgdt_size); memcpy(bgdt, buf, bgdt_size); } @@ -106,7 +106,7 @@ void ext2_open_inode(u32 inode_num, struct ext2_file *file) read_inode(&file->inode, inode_num); file->pos = 0; file->block_index = 0; - file->buf = kmalloc(block_size); + file->buf = malloc(block_size); file->curr_block_pos = 0; read_block(file->inode.dbp[0], file->buf); @@ -136,7 +136,7 @@ u32 ext2_read(struct ext2_file *file, u8 *buf, u32 count) file->block_index++; if (file->block_index >= 12) { // TODO: Add triple block pointer support - u32 *tmp = kmalloc(block_size); + u32 *tmp = malloc(block_size); read_block(file->inode.ibp, tmp); read_block(tmp[file->block_index - 12], file->buf); } else { @@ -159,7 +159,7 @@ bool ext2_next_dirent(struct ext2_file *file, struct ext2_dirent *dir) memcpy(dir, buf, READ_SIZE); u32 size = dir->name_len + 1; - u8 *name = kmalloc(size); + u8 *name = malloc(size); if (ext2_read(file, name, size - 1) != size - 1) return false; @@ -192,7 +192,7 @@ u32 ext2_find_in_dir(u32 dir_inode, const char *name) inode = 0; cleanup: - kfree(dir.buf); + free(dir.buf); return inode; } diff --git a/src/kernel/fs/fs.c b/src/kernel/fs/fs.c index a23b943..b9bada7 100644 --- a/src/kernel/fs/fs.c +++ b/src/kernel/fs/fs.c @@ -25,7 +25,7 @@ u32 read(char *path, u32 offset, u32 count, u8 *buf) if (inode != 0) { debug("Reading %s: %dKiB", path, count >> 10); ext2_read(&file, buf, count); - kfree(file.buf); + free(file.buf); buf[count - 1] = '\0'; return buf; } else { @@ -49,9 +49,9 @@ u8 *read_file(char *path) if (inode != 0) { u32 size = file.inode.size; debug("Reading %s: %dKiB", path, size >> 10); - u8 *buf = kmalloc(size); + u8 *buf = malloc(size); ext2_read(&file, buf, size); - kfree(file.buf); + free(file.buf); buf[size - 1] = '\0'; return buf; } else { diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index 6c80597..7fa4e15 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -49,7 +49,7 @@ u16 *vbe_get_modes() for (u16 *p = mode_ptr; *p != 0xFFFF; p++) number_modes++; - u16 *ret = (u16 *)kmalloc(sizeof(u16) * number_modes); + u16 *ret = (u16 *)malloc(sizeof(u16) * number_modes); for (u32 i = 0; i < number_modes; i++) ret[i] = ((u16 *)info->video_modes)[i]; @@ -69,7 +69,7 @@ struct vbe_mode_info *vbe_get_mode_info(u16 mode) struct vbe_mode_info_all *mode_info = (struct vbe_mode_info_all *)0x7E00; - struct vbe_mode_info *ret = (struct vbe_mode_info *)kmalloc(sizeof(struct vbe_mode_info)); + struct vbe_mode_info *ret = (struct vbe_mode_info *)malloc(sizeof(struct vbe_mode_info)); ret->attributes = mode_info->attributes; ret->pitch = mode_info->pitch; ret->width = mode_info->width; @@ -94,7 +94,7 @@ void set_optimal_resolution() if (mode_info == 0 || (mode_info->attributes & 0x90) != 0x90 || (mode_info->memory_model != 4 && mode_info->memory_model != 6)) { - kfree(mode_info); + free(mode_info); continue; } @@ -111,10 +111,10 @@ void set_optimal_resolution() vbe_bpl = mode_info->bpp >> 3; fb = (u8 *)mode_info->framebuffer; } - kfree(mode_info); + free(mode_info); } - kfree(video_modes); + free(video_modes); if (highest == 0) { log("Mode detection failed!"); @@ -139,7 +139,7 @@ void set_optimal_resolution() mode_info = vbe_get_mode_info((u16)modes[i]); if (mode_info == 0 || (mode_info->attributes & 0x90) != 0x90 || (mode_info->memory_model != 4 && mode_info->memory_model != 6)) { - kfree(mode_info); + free(mode_info); continue; } @@ -152,7 +152,7 @@ void set_optimal_resolution() vbe_bpl = mode_info->bpp >> 3; fb = (u8 *)mode_info->framebuffer; } - kfree(mode_info); + free(mode_info); } // Everything else failed :( @@ -165,13 +165,13 @@ void set_optimal_resolution() vbe_set_mode(highest); /* u32 fb_size = vbe_width * vbe_height * vbe_bpl; */ - /* cursor_buffer = kmalloc(fb_size); */ + /* cursor_buffer = malloc(fb_size); */ /* for (u32 z = 0; z < fb_size; z += PAGE_S) { */ - /* paging_map_user(paging_root_directory, (u32)fb + z, (u32)fb + z); */ + /* paging_map_user(paging_kernel_directory, (u32)fb + z, (u32)fb + z); */ /* } */ /* dev_make("fb", NULL, (write)fb_write); */ - /* struct fs_node *node = (struct fs_node *)kmalloc(sizeof(struct fs_node)); */ + /* struct fs_node *node = (struct fs_node *)malloc(sizeof(struct fs_node)); */ /* strcpy(node->name, "/dev/fb"); */ /* fs_open(node); */ /* node->write = (write)fb_write; */ diff --git a/src/kernel/input/ps2/keyboard.c b/src/kernel/input/ps2/keyboard.c index 2ed825a..60ec3df 100644 --- a/src/kernel/input/ps2/keyboard.c +++ b/src/kernel/input/ps2/keyboard.c @@ -12,7 +12,7 @@ u8 scancode; void keyboard_handler(struct regs *r) { scancode = inb(0x60); - struct keyboard_event *event = umalloc(sizeof(struct keyboard_event)); + struct keyboard_event *event = malloc(sizeof(struct keyboard_event)); event->scancode = scancode; event_trigger(MAP_KEYBOARD, (u8 *)event); } diff --git a/src/kernel/input/ps2/mouse.c b/src/kernel/input/ps2/mouse.c index f0b98df..b86ca99 100644 --- a/src/kernel/input/ps2/mouse.c +++ b/src/kernel/input/ps2/mouse.c @@ -90,7 +90,7 @@ char mouse_read() void mouse_install() { - event = umalloc(sizeof(struct mouse_event)); + event = malloc(sizeof(struct mouse_event)); u8 status; // Enable auxiliary mouse device diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index f0b19c0..82937f2 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -45,8 +45,8 @@ void kernel_main(u32 magic, u32 multiboot_address, u32 esp) isrs_install(); irq_install(); + paging_install(multiboot_address); multiboot_parse(multiboot_address); - paging_install(); // Install drivers timer_install(); diff --git a/src/kernel/lib/data/list.c b/src/kernel/lib/data/list.c index 7ecc950..31e6631 100644 --- a/src/kernel/lib/data/list.c +++ b/src/kernel/lib/data/list.c @@ -7,7 +7,7 @@ struct list *list_create() { - struct list *list = kcalloc(sizeof(struct list), 1); + struct list *list = calloc(sizeof(struct list), 1); return list; } @@ -29,13 +29,13 @@ void *list_remove_node(struct list *list, struct list_node *node) node->next->prev = node->prev; node->prev->next = node->next; list->size--; - kfree(node); + free(node); } return val; } struct list_node *list_insert_front(struct list *list, void *val) { - struct list_node *t = kcalloc(sizeof(struct list_node), 1); + struct list_node *t = calloc(sizeof(struct list_node), 1); list->head->prev = t; t->next = list->head; t->val = val; @@ -50,7 +50,7 @@ struct list_node *list_insert_front(struct list *list, void *val) void list_insert_back(struct list *list, void *val) { - struct list_node *t = kcalloc(sizeof(struct list_node), 1); + struct list_node *t = calloc(sizeof(struct list_node), 1); t->prev = list->tail; if (list->tail) list->tail->next = t; @@ -72,7 +72,7 @@ void *list_remove_front(struct list *list) list->head = t->next; if (list->head) list->head->prev = NULL; - kfree(t); + free(t); list->size--; return val; } @@ -86,7 +86,7 @@ void *list_remove_back(struct list *list) list->tail = t->prev; if (list->tail) list->tail->next = NULL; - kfree(t); + free(t); list->size--; return val; } @@ -170,14 +170,14 @@ void list_destroy(struct list *list) while (node != NULL) { struct list_node *save = node; node = node->next; - kfree(save); + free(save); } - kfree(list); + free(list); } void listnode_destroy(struct list_node *node) { - kfree(node); + free(node); } // Conversion @@ -199,13 +199,13 @@ struct list *str_split(const char *str, const char *delim, u32 *numtokens) if (numtokens) (*numtokens)++; } - kfree(s); + free(s); return ret_list; } char *list_to_str(struct list *list, const char *delim) { - char *ret = kmalloc(256); + char *ret = malloc(256); memset(ret, 0, 256); int len = 0, ret_len = 256; while (list_size(list) > 0) { @@ -213,8 +213,7 @@ char *list_to_str(struct list *list, const char *delim) int len_temp = strlen(temp); if (len + len_temp + 1 + 1 > ret_len) { ret_len = ret_len * 2; - /* ret = krealloc(ret, ret_len); */ - ret = kmalloc(ret_len); + ret = realloc(ret, ret_len); len = len + len_temp + 1; } strcat(ret, delim); diff --git a/src/kernel/lib/data/tree.c b/src/kernel/lib/data/tree.c index 65b8433..9758ec1 100644 --- a/src/kernel/lib/data/tree.c +++ b/src/kernel/lib/data/tree.c @@ -1,15 +1,16 @@ #include <lib/data.h> #include <memory/alloc.h> +#include <stddef.h> #include <stdint.h> struct tree *tree_create() { - return (struct tree *)kcalloc(sizeof(struct tree), 1); + return (struct tree *)calloc(sizeof(struct tree), 1); } struct tree_node *treenode_create(void *value) { - struct tree_node *n = kcalloc(sizeof(struct tree_node), 1); + struct tree_node *n = calloc(sizeof(struct tree_node), 1); n->value = value; n->children = list_create(); return n; @@ -17,7 +18,7 @@ struct tree_node *treenode_create(void *value) struct tree_node *tree_insert(struct tree *tree, struct tree_node *subroot, void *value) { - struct tree_node *treenode = kcalloc(sizeof(struct tree_node), 1); + struct tree_node *treenode = calloc(sizeof(struct tree_node), 1); treenode->children = list_create(); treenode->value = value; @@ -62,7 +63,7 @@ void tree_remove(struct tree *tree, struct tree_node *remove_node) struct tree_node *parent = tree_find_parent(tree, remove_node, &child_index); if (parent != NULL) { struct tree_node *freethis = list_remove_by_index(parent->children, child_index); - kfree(freethis); + free(freethis); } } diff --git a/src/kernel/lib/lib.h b/src/kernel/lib/lib.h index 921e575..6f2c04d 100644 --- a/src/kernel/lib/lib.h +++ b/src/kernel/lib/lib.h @@ -33,11 +33,10 @@ void *memset(void *dest, char val, u32 count); int memcmp(const void *a_ptr, const void *b_ptr, u32 size); void memory_info_init(struct multiboot_tag_basic_meminfo *tag); - void memory_mmap_init(struct multiboot_tag_mmap *tag); +int memory_init(u32 multiboot_address); void memory_print(); - u32 memory_get_all(); #endif
\ No newline at end of file diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c index 61b1414..0f3cb34 100644 --- a/src/kernel/lib/memory.c +++ b/src/kernel/lib/memory.c @@ -58,10 +58,10 @@ u32 memory_get_free() void memory_print() { // TODO: Fix multiboot mem lower/upper - /*if (meminfo != NULL) { + if (meminfo != NULL) { info("Mem lower: 0x%x", meminfo->mem_lower); info("Mem upper: 0x%x", meminfo->mem_upper); - }*/ + } info("Total memory found: %dMiB", (memory_get_all() >> 10) + 1); info("Total free memory: %dMiB", (memory_get_free() >> 10) + 1); } @@ -76,18 +76,17 @@ void memory_mmap_init(struct multiboot_tag_mmap *tag) u32 sum = 0; struct multiboot_mmap_entry *mmap; - for (mmap = ((struct multiboot_tag_mmap *)tag)->entries; - (multiboot_u8 *)mmap < (multiboot_u8 *)tag + tag->size; + for (mmap = ((struct multiboot_tag_mmap *)tag)->entries; (u8 *)mmap < (u8 *)tag + tag->size; mmap = (multiboot_memory_map_t *)((u32)mmap + ((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) { @@ -97,4 +96,24 @@ void memory_mmap_init(struct multiboot_tag_mmap *tag) } } total = sum >> 10; // I want kb +} + +int memory_init(u32 multiboot_address) +{ + int ret = 0; + struct multiboot_tag *tag; + + for (tag = (struct multiboot_tag *)(multiboot_address + 8); + tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (struct multiboot_tag *)((u8 *)tag + ((tag->size + 7) & ~7))) { + if (tag->type == MULTIBOOT_TAG_TYPE_BASIC_MEMINFO) { + info("Got memory info"); + memory_info_init((struct multiboot_tag_basic_meminfo *)tag); + } else if (tag->type == MULTIBOOT_TAG_TYPE_MMAP) { + info("Got memory map"); + memory_mmap_init((struct multiboot_tag_mmap *)tag); + ret = 1; + } + } + return ret; }
\ No newline at end of file diff --git a/src/kernel/lib/stdio/debug.c b/src/kernel/lib/stdio/debug.c index 74eb594..3acb987 100644 --- a/src/kernel/lib/stdio/debug.c +++ b/src/kernel/lib/stdio/debug.c @@ -33,12 +33,12 @@ void serial_vprintf(const char *fmt, va_list args) } else if (buff == 'x') { char *p = htoa((u32)va_arg(args, int)); serial_print(p); - kfree(p); + free(p); readyToFormat = 0; } else if (buff == 'd') { char *p = itoa(va_arg(args, int)); serial_print(p); - kfree(p); + free(p); readyToFormat = 0; } else if (buff == 'c') { serial_put((char)va_arg(args, int)); diff --git a/src/kernel/lib/stdio/vprintf.c b/src/kernel/lib/stdio/vprintf.c index 37723b2..4c0c432 100644 --- a/src/kernel/lib/stdio/vprintf.c +++ b/src/kernel/lib/stdio/vprintf.c @@ -33,12 +33,12 @@ void vprintf(const char *fmt, va_list args) } else if (buff == 'x') { char *p = htoa((u32)va_arg(args, int)); _puts(p); - kfree(p); + free(p); readyToFormat = 0; } else if (buff == 'd') { char *p = itoa(va_arg(args, int)); _puts(p); - kfree(p); + free(p); readyToFormat = 0; } else if (buff == 'c') { putch((char)va_arg(args, int)); diff --git a/src/kernel/lib/stdlib/htoa.c b/src/kernel/lib/stdlib/htoa.c index c4dbd5e..9cf57cc 100644 --- a/src/kernel/lib/stdlib/htoa.c +++ b/src/kernel/lib/stdlib/htoa.c @@ -6,7 +6,7 @@ static const char HTOA_TABLE[] = "0123456789ABCDEF"; char *htoa(u32 n) { - char *ret = (char *)kmalloc(10); + char *ret = (char *)malloc(10); int i = 0; while (n) { @@ -23,7 +23,7 @@ char *htoa(u32 n) ret[i] = 0; char *aux = strdup(ret); - kfree(ret); + free(ret); ret = aux; strinv(ret); diff --git a/src/kernel/lib/stdlib/itoa.c b/src/kernel/lib/stdlib/itoa.c index b4a9db1..2020ca6 100644 --- a/src/kernel/lib/stdlib/itoa.c +++ b/src/kernel/lib/stdlib/itoa.c @@ -9,7 +9,7 @@ static const char ITOA_TABLE[] = "0123456789"; char *itoa(int n) { if (!n) { - char *ret = (char *)kmalloc(2); + char *ret = (char *)malloc(2); ret[0] = '0'; ret[1] = 0; return ret; @@ -22,7 +22,7 @@ char *itoa(int n) for (sz = 0; n % pow(10, sz) != n; sz++) { } - char *ret = (char *)kmalloc((u32)(sz + 1)); + char *ret = (char *)malloc((u32)(sz + 1)); for (int i = 0; i < sz; i++) { int digit = (n % pow(10, i + 1)) / pow(10, i); @@ -31,11 +31,11 @@ char *itoa(int n) ret[sz] = 0; if (negative) { - char *aux = (char *)kmalloc((u32)(sz + 2)); + char *aux = (char *)malloc((u32)(sz + 2)); strcpy(aux, ret); aux[sz] = '-'; aux[sz + 1] = 0; - kfree(ret); + free(ret); ret = aux; } diff --git a/src/kernel/lib/string/strdup.c b/src/kernel/lib/string/strdup.c index 00bb863..3b138e8 100644 --- a/src/kernel/lib/string/strdup.c +++ b/src/kernel/lib/string/strdup.c @@ -4,7 +4,7 @@ char *strdup(const char *orig) { u32 s_orig = strlen(orig); - char *ret = (char *)kmalloc(s_orig + 1); + char *ret = (char *)malloc(s_orig + 1); strcpy(ret, orig); return ret; }
\ No newline at end of file diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index bd4ecb3..d94e482 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -1,3 +1,4 @@ +#include <io/io.h> #include <lib/lib.h> #include <memory/alloc.h> #include <memory/paging.h> @@ -5,192 +6,477 @@ #include <stdint.h> #include <system.h> -extern u32 end; -u32 placement_address; +static int locked = 0; -struct heap_header *kheap = NULL; -struct heap_header *uheap = NULL; +int liballoc_lock() +{ + spinlock(locked); + return 0; +} -void kheap_init() +int liballoc_unlock() { - end = &end; - placement_address = 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, (u32)&uheap, (u32)&uheap); + locked = 0; + return 0; } -void *fmalloc(u32 size) +void *liballoc_alloc(u32 p) { - assert(placement_address + size < MEM_END); - u32 hold = placement_address; - memset((void *)hold, 0, size); - placement_address += size; - return (void *)hold; + u32 ptr = paging_alloc_pages((u32)p); + return (void *)ptr; } -void *kmalloc_a(u32 size) +int liballoc_free(void *ptr, u32 p) { - assert(((placement_address & 0xFFFFF000) + 0x1000) + size < MEM_END); - placement_address &= 0xFFFFF000; - placement_address += 0x1000; + paging_set_free((u32)ptr, (u32)p); + return 0; +} - u32 hold = placement_address; - placement_address += size; +#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; \ + } - return (void *)hold; -} +#define UNALIGN(ptr) \ + if (ALIGNMENT > 1) { \ + u32 diff = *((ALIGN_TYPE *)((u32)ptr - ALIGN_INFO)); \ + if (diff < (ALIGNMENT + ALIGN_INFO)) { \ + ptr = (void *)((u32)ptr - diff); \ + } \ + } -struct heap_header *find_sized_heap(struct heap_header *heap, u32 size) +#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) { - 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 *)((u32)heap + HEAP_S + heap->size); - assert(foot->magic == KHEAP_MAGIC); - assert(foot->magic2 == KHEAP_MAGIC2); + u32 i; + for (i = 0; i < n; i++) + ((char *)s)[i] = c; - if (foot->size == KHEAP_END) - panic("Out of heap space"); - - if (foot->size != heap->size) - panic("Heap footer/header mismatch"); + return s; +} - heap = (struct heap_header *)((u32)foot + sizeof(struct heap_footer)); +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); } - return heap; + cdest = (char *)ldest; + csrc = (char *)lsrc; + + while (n > 0) { + *cdest++ = *csrc++; + n -= 1; + } + return s1; } -void split_heap(struct heap_header *heap, u32 size) +static struct liballoc_major *allocate_new_page(u32 size) { - struct heap_footer *foot = (struct heap_footer *)((u32)heap + HEAP_S + size); - foot->magic = KHEAP_MAGIC; - foot->magic2 = KHEAP_MAGIC2; - foot->size = size; + u32 st; + struct liballoc_major *maj; + + st = size + sizeof(struct liballoc_major); + st += sizeof(struct liballoc_minor); - u32 new_size = heap->size - HEAP_TOTAL - size; - heap->size = size; + if ((st % l_page_size) == 0) + st = st / (l_page_size); + else + st = st / (l_page_size) + 1; - heap = (struct heap_header *)((u32)foot + sizeof(struct heap_footer)); - heap->size = new_size; - heap->free = true; - heap->magic = KHEAP_MAGIC; - heap->magic2 = KHEAP_MAGIC2; + if (st < l_page_count) + st = l_page_count; - foot = (struct heap_footer *)((u32)heap + HEAP_S + heap->size); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { - warn("Invalid footer in split"); + maj = (struct liballoc_major *)liballoc_alloc(st); + + if (maj == NULL) { + l_warning_count += 1; + return NULL; } - if (foot->size != KHEAP_END) - foot->size = new_size; + 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 free_internal(struct heap_header *heap, void *address) +void *malloc(u32 req_size) { - struct heap_header *head = (struct heap_header *)((u32)address - HEAP_S); - if (head == heap) { - //warn("Can't collapse top of heap"); // TODO: Fix "can't collapse top of heap" at start - head->free = true; - return; + int startedBet = 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; } - if ((head->magic != KHEAP_MAGIC) || (head->magic2 != KHEAP_MAGIC2)) { - warn("Invalid header in heap"); - return; - } + liballoc_lock(); - struct heap_footer *foot = (struct heap_footer *)((u32)head + HEAP_S + head->size); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) - panic("Bad heap call"); + if (size == 0) { + l_warning_count += 1; + liballoc_unlock(); + return malloc(1); + } - foot = (struct heap_footer *)((u32)head - sizeof(struct heap_footer)); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { - warn("Invalid footer in heap"); - return; + if (l_mem_root == NULL) { + l_mem_root = allocate_new_page(size); + if (l_mem_root == NULL) { + liballoc_unlock(); + return NULL; + } } - if (foot->size == KHEAP_END) - panic("Impossible condition for heap"); + maj = l_mem_root; + startedBet = 0; - heap = (struct heap_header *)((u32)foot - foot->size - HEAP_S); - if ((heap->magic != KHEAP_MAGIC) || (heap->magic2 != KHEAP_MAGIC2)) { - warn("Invalid parent in heap"); - return; + 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; + startedBet = 1; + } } - foot = (struct heap_footer *)((u32)heap + (heap->size + head->size + HEAP_TOTAL) + HEAP_S); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { - panic("Fatal arithmetic error in free() call"); - return; + 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 (startedBet == 1) { + maj = l_mem_root; + 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 *)((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 (startedBet == 1) { + maj = l_mem_root; + startedBet = 0; + continue; + } + maj->next = allocate_new_page(size); + if (maj->next == NULL) + break; + maj->next->prev = maj; + } +#endif + maj = maj->next; } - heap->size += head->size + HEAP_TOTAL; - foot->size = heap->size; -} + liballoc_unlock(); -void *malloc_internal(struct heap_header *heap, u32 size) -{ - heap = find_sized_heap(heap, size + 8); - heap->free = false; - split_heap(heap, size); - return (void *)((u32)heap + HEAP_S); + return NULL; } -void init_heap(struct heap_header *heap, u32 size) +void free(void *ptr) { - heap->magic = KHEAP_MAGIC; - heap->magic2 = KHEAP_MAGIC2; - heap->free = true; - heap->size = size - HEAP_TOTAL; - - struct heap_footer *foot = (struct heap_footer *)((u32)heap + HEAP_S + heap->size); - foot->magic = KHEAP_MAGIC; - foot->magic2 = KHEAP_MAGIC2; - foot->size = KHEAP_END; -} + struct liballoc_minor *min; + struct liballoc_major *maj; -void *kmalloc(u32 size) -{ - if (kheap == NULL) - return fmalloc(size); + if (ptr == NULL) { + l_warning_count += 1; + return; + } - return malloc_internal(kheap, size); -} + UNALIGN(ptr); + liballoc_lock(); -void *kcalloc(u32 num, u32 size) -{ - void *ptr = kmalloc(num * size); - memset(ptr, 0, num * size); - return ptr; -} + min = (struct liballoc_minor *)((u32)ptr - sizeof(struct liballoc_minor)); -void kfree(void *address) -{ - if (kheap == NULL) + 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; + } - free_internal(kheap, address); + 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 *umalloc(u32 size) +void *calloc(u32 nobj, u32 size) { - return malloc_internal(uheap, size); -} + int real_size; + void *p; -void *ucalloc(u32 num, u32 size) -{ - void *ptr = umalloc(num * size); - memset(ptr, 0, num * size); - return ptr; + real_size = nobj * size; + + p = malloc(real_size); + + liballoc_memset(p, 0, real_size); + + return p; } -void ufree(void *address) +void *realloc(void *p, u32 size) { - free_internal(uheap, address); + 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 index a7b05bc..6c4290e 100644 --- a/src/kernel/memory/alloc.h +++ b/src/kernel/memory/alloc.h @@ -1,47 +1,11 @@ #ifndef MELVIX_ALLOC_H #define MELVIX_ALLOC_H -#include <stdbool.h> -#include <stddef.h> #include <stdint.h> -#define KHEAP_MAGIC 0xCAFEBABE -#define KHEAP_MAGIC2 0xDEADBEEF -#define KHEAP_END 0xFFFFDEAD -#define MEM_END 0x8000000 - -struct heap_header { - u32 magic; - bool free; - u32 size; - u32 magic2; -}; - -struct heap_footer { - u32 magic; - u32 size; - u32 magic2; -}; - -void kheap_init(); - -void *fmalloc(u32 size); -void *kcalloc(u32 num, u32 size); -void *kmalloc(u32 size); -void *kmalloc_a(u32 size); -void kfree(void *ptr); - -void *umalloc(u32 size); -void *ucalloc(u32 num, u32 size); -void ufree(void *address); - -void init_heap(struct heap_header *heap, u32 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) +void *malloc(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/paging.c b/src/kernel/memory/paging.c index d538fe9..e3c088a 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -1,174 +1,194 @@ -#include <acpi/acpi.h> -#include <interrupts/interrupts.h> -#include <io/io.h> #include <lib/lib.h> #include <memory/alloc.h> #include <memory/paging.h> #include <stdint.h> #include <system.h> -#include <tasks/process.h> -struct page_directory *paging_current_directory = NULL; -struct page_directory *paging_root_directory = NULL; +int paging_enabled = 0; -/* void paging_install(u32 multiboot_address) */ -/* { */ -/* if (!memory_init(multiboot_address)) */ -/* paging_set_present(0, memory_get_all() >> 3); // /4 */ -/* paging_set_used(0, ((u32)ASM_KERNEL_END >> 12) + 1); // /4096 */ -/* } */ +u32 root_dir[1024][1024] __attribute__((aligned(4096))); +struct page_directory *paging_directory; // Current +struct page_directory *paging_kernel_directory = (struct page_directory *)root_dir; -struct page_table *get_cr3() +void paging_init(struct page_directory *dir, int user) { - u32 cr3; - asm volatile("movl %%cr3, %%eax" : "=a"(cr3)); - return (struct page_table *)cr3; -} + for (u32 i = 0; i < 1024; i++) { + for (u32 j = 0; j < 1024; j++) { + paging_directory->tables[i]->pages[j] = + ((j * 0x1000) + (i * PAGE_SIZE)) | PT_RW | (user ? PT_USER : 0); + } + } -u32 get_cr0() -{ - u32 cr0; - asm volatile("movl %%cr0, %%eax" : "=a"(cr0)); - return cr0; + for (u32 i = 0; i < 1024; i++) { + paging_directory->tables[i] = ((u32)paging_directory->tables[i]) | PD_RW | + PD_PRESENT | (user ? PD_USER : 0); + } } -void set_cr3(struct page_directory *dir) +struct page_directory *paging_make_directory(int user) { - u32 addr = (u32)&dir->tables[0]; - asm volatile("movl %%eax, %%cr3" ::"a"(addr)); + struct page_directory *dir = (struct page_directory *)malloc(sizeof(struct page_directory)); + + paging_init(dir, user); + + return dir; } -void set_cr0(u32 cr0) +extern u32 end; +void paging_install(u32 multiboot_address) { - asm volatile("movl %%eax, %%cr0" ::"a"(cr0)); + // Kernel paging + paging_switch_directory(paging_directory); + paging_init(paging_directory, 0); + + if (!memory_init(multiboot_address)) + paging_set_present(0, memory_get_all() >> 3); // /4 + paging_set_used(0, ((u32)end >> 12) + 1); // /4096 + log("Enabling"); + + paging_enable(); + log("Installed paging"); } void paging_disable() { - set_cr0(get_cr0() | 0x7fffffff); + u32 cr0; + asm("mov %%cr0, %0" : "=r"(cr0)); + cr0 &= 0x7fffffff; + asm("mov %0, %%cr0" ::"r"(cr0)); + paging_enabled = 0; } void paging_enable() { - set_cr3(paging_current_directory); - set_cr0(get_cr0() | 0x80000000); + asm("mov %0, %%cr3" ::"r"(paging_directory)); + u32 cr0; + asm("mov %%cr0, %0" : "=r"(cr0)); + cr0 |= 0x80000000; + asm("mov %0, %%cr0" ::"r"(cr0)); + paging_enabled = 1; } void paging_switch_directory(struct page_directory *dir) { - set_cr3(dir); - set_cr0(get_cr0() | 0x80000000); + paging_directory = dir; + asm("mov %0, %%cr3" ::"r"(paging_directory)); } -struct page_directory *paging_make_directory() +void invlpg(u32 addr) { - struct page_directory *dir = - (struct page_directory *)kmalloc_a(sizeof(struct page_directory)); - - for (int i = 0; i < 1024; i++) - dir->tables[i] = EMPTY_TAB; - - return dir; + asm("invlpg (%0)" ::"r"(addr) : "memory"); } -struct page_table *paging_make_table() +void paging_map(u32 phy, u32 virt, u16 flags) { - 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; + u32 pdi = virt >> 22; + u32 pti = virt >> 12 & 0x03FF; + paging_directory->tables[pdi]->pages[pti] = phy | flags; + invlpg(virt); } -void paging_map(struct page_directory *dir, u32 phys, u32 virt) +u32 paging_get_phys(u32 virt) { - short id = virt >> 22; - struct page_table *tab = paging_make_table(); + u32 pdi = virt >> 22; + u32 pti = (virt >> 12) & 0x03FF; + return paging_directory->tables[pdi]->pages[pti] & 0xFFFFF000; +} - dir->tables[id] = ((struct page_table *)((u32)tab | 3)); // RW +u16 paging_get_flags(u32 virt) +{ + u32 pdi = virt >> 22; + u32 pti = (virt >> 12) & 0x03FF; + return paging_directory->tables[pdi]->pages[pti] & 0xFFF; +} - for (int i = 0; i < 1024; i++) { - tab->pages[i].frame = phys >> 12; - tab->pages[i].present = 1; - phys += 4096; +void paging_set_flag_up(u32 virt, u32 count, u32 flag) +{ + u32 page_n = virt / 0x1000; + for (u32 i = page_n; i < page_n + count; i++) { + paging_directory->tables[i / 1024]->pages[i % 1024] |= flag; + invlpg(i * 0x1000); } } -void paging_map_user(struct page_directory *dir, u32 phys, u32 virt) +void paging_set_flag_down(u32 virt, u32 count, u32 flag) { - short id = virt >> 22; - struct page_table *tab = paging_make_table(); - - dir->tables[id] = ((struct page_table *)((u32)tab | 3 | 4)); // RW + usermode - - for (int i = 0; i < 1024; i++) { - tab->pages[i].frame = phys >> 12; - tab->pages[i].present = 1; - tab->pages[i].user = 1; - phys += 4096; + u32 page_n = virt / 0x1000; + for (u32 i = page_n; i < page_n + count; i++) { + paging_directory->tables[i / 1024]->pages[i % 1024] &= ~flag; + invlpg(i * 0x1000); } } -// Hmm -u32 paging_get_phys(u32 virt) +void paging_set_present(u32 virt, u32 count) { - u32 pdi = virt >> 22; - u32 pti = (virt >> 12) & 0x03FF; - return (*(u32 *)&paging_current_directory->tables[pdi]->pages[pti]) & 0xFFFFF000; + paging_set_flag_up(virt, count, PT_PRESENT); } -void paging_install() +void paging_set_absent(u32 virt, u32 count) { - kheap_init(); - - paging_current_directory = paging_make_directory(); - paging_root_directory = paging_current_directory; + paging_set_flag_down(virt, count, PT_PRESENT); +} - for (u32 i = 0; i < 0xF0000000; i += PAGE_S) - paging_map(paging_root_directory, i, i); - paging_switch_directory(paging_root_directory); - info("Installed paging"); +void paging_set_used(u32 virt, u32 count) +{ + paging_set_flag_up(virt, count, PT_USED); +} - // Test mallocing - u32 a = (u32)kmalloc(4096); - u32 b = (u32)kmalloc(4096); - kfree((void *)b); - kfree((void *)a); - u32 c = (u32)kmalloc(2048); - assert(a == c); - info("kmalloc test succeeded!"); +void paging_set_free(u32 virt, u32 count) +{ + paging_set_flag_down(virt, count, PT_USED); } -void paging_convert_page(struct page_directory *kdir) +void paging_set_user(u32 virt, u32 count) { - for (int i = 0; i < 1024; i++) { - kdir->tables[i] = (struct page_table *)((u32)kdir->tables[i] | 4); // Usermode + u32 page_n = virt / 0x1000; + for (u32 i = page_n; i < page_n + count; i += 1024) { + paging_directory->tables[i] = ((u32)paging_directory->tables[i]) | PD_USER; + } + paging_set_flag_up(virt, count, PT_USER); +} - if (((u32)kdir->tables[i]) & 1) { // Is present - for (int j = 0; j < 1024; j++) - kdir->tables[i]->pages[j].user = 1; // Usermode +u32 paging_find_pages(u32 count) +{ + u32 continuous = 0; + u32 start_dir = 0; + u32 start_page = 0; + for (u32 i = 0; i < 1024; i++) { + for (u32 j = 0; j < 1024; j++) { + if (!(paging_directory->tables[i]->pages[j] & PT_PRESENT) || + (paging_directory->tables[i]->pages[j] & PT_USED)) { + continuous = 0; + start_dir = i; + start_page = j + 1; + } else { + if (++continuous == count) + return (start_dir * 0x400000) + (start_page * 0x1000); + } } } + + panic("Out of memory!"); + return 0; } -struct page_directory *paging_copy_user_directory(struct page_directory *dir) +u32 paging_alloc_pages(u32 count) { - struct page_directory *copy = paging_make_directory(); - memcpy(copy, paging_root_directory, sizeof(struct page_directory)); + u32 ptr = paging_find_pages(count); + paging_set_used(ptr, count); + paging_set_user(ptr, count); + return ptr; +} +u32 paging_get_used_pages() +{ + u32 n = 0; for (u32 i = 0; i < 1024; i++) { - if (((u32)dir->tables[i]) & 4) { - struct page_table *tab = - (struct page_table *)((u32)dir->tables[i] & 0xFFFFF000); - - void *buffer = kmalloc_a(PAGE_S); - memcpy(buffer, (void *)(tab->pages[0].frame << 12), PAGE_S); - paging_map_user(copy, (u32)buffer, (u32)i << 22); + for (u32 j = 0; j < 1024; j++) { + u8 flags = paging_directory->tables[i]->pages[j] & PT_USED; + if (flags == 1) + n++; } } - - return copy; + return n; }
\ No newline at end of file diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index a9aef92..f1fe064 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -3,50 +3,59 @@ #include <stdint.h> -struct page { - u32 present : 1; - u32 rw : 1; - u32 user : 1; - u32 accessed : 1; - u32 dirty : 1; - u32 unused : 7; - u32 frame : 20; -}; +#define PAGE_SIZE 0x400000 + +#define PD_PRESENT 1 << 0 +#define PD_RW 1 << 1 +#define PD_USER 1 << 2 +#define PD_WRITETHR 1 << 3 +#define PD_CACHE_D 1 << 4 +#define PD_ACCESSED 1 << 5 +#define PD_4M_PAGE 1 << 7 + +#define PT_PRESENT 1 << 0 +#define PT_RW 1 << 1 +#define PT_USER 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]; + u32 pages[1024]; }; struct page_directory { struct page_table *tables[1024]; }; -struct page_directory *paging_root_directory; - -struct page_table *get_cr3(); -u32 get_cr0(); - -void set_cr3(struct page_directory *dir); -void set_cr0(u32 new_cr0); +struct page_directory *paging_kernel_directory; +int paging_enabled; -void paging_disable(); +void paging_install(u32 multiboot_address); void paging_enable(); -void paging_switch_directory(struct page_directory *dir); +void paging_disable(); -struct page_directory *paging_make_directory(); -struct page_table *paging_make_table(); +struct page_directory *paging_make_directory(int user); +void paging_switch_directory(struct page_directory *dir); +void paging_map(u32 phy, u32 virt, u16 flags); u32 paging_get_phys(u32 virt); -void paging_install(); - -void paging_map(struct page_directory *cr3, u32 virt, u32 phys); -void paging_map_user(struct page_directory *cr3, u32 virt, u32 phys); - -void paging_convert_page(struct page_directory *kdir); - -struct page_directory *paging_copy_user_directory(struct page_directory *dir); - -#define EMPTY_TAB ((struct page_table *)0x00000002) -#define PAGE_S 0x400000 +u16 paging_get_flags(u32 virt); +u32 paging_get_used_pages(); + +void paging_set_flags(u32 virt, u32 count, u16 flags); +void paging_set_flag_up(u32 virt, u32 count, u32 flag); +void paging_set_flag_down(u32 virt, u32 count, u32 flag); +void paging_set_present(u32 virt, u32 count); +void paging_set_absent(u32 virt, u32 count); +void paging_set_used(u32 virt, u32 count); +void paging_set_free(u32 virt, u32 count); +void paging_set_user(u32 virt, u32 count); + +u32 paging_find_pages(u32 count); +u32 paging_alloc_pages(u32 count); #endif
\ No newline at end of file diff --git a/src/kernel/multiboot.c b/src/kernel/multiboot.c index af1a88b..f7ac876 100644 --- a/src/kernel/multiboot.c +++ b/src/kernel/multiboot.c @@ -13,7 +13,7 @@ void multiboot_parse(u32 multiboot_address) for (tag = (struct multiboot_tag *)(multiboot_address + 8); tag->type != MULTIBOOT_TAG_TYPE_END; - tag = (struct multiboot_tag *)((multiboot_u8 *)tag + ((tag->size + 7) & ~7))) { + tag = (struct multiboot_tag *)((u8 *)tag + ((tag->size + 7) & ~7))) { switch (tag->type) { case MULTIBOOT_TAG_TYPE_CMDLINE: // TODO: Add cmdline config support @@ -28,14 +28,14 @@ void multiboot_parse(u32 multiboot_address) break; case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: debug("Got memory info"); - memory_info_init((struct multiboot_tag_basic_meminfo *)tag); + /* memory_info_init((struct multiboot_tag_basic_meminfo *)tag); */ break; case MULTIBOOT_TAG_TYPE_BOOTDEV: debug("Got boot device"); break; case MULTIBOOT_TAG_TYPE_MMAP: debug("Got memory map"); - memory_mmap_init((struct multiboot_tag_mmap *)tag); + /* memory_mmap_init((struct multiboot_tag_mmap *)tag); */ break; case MULTIBOOT_TAG_TYPE_VBE: debug("Got VBE"); diff --git a/src/kernel/multiboot.h b/src/kernel/multiboot.h index 8570e69..3eb9b93 100644 --- a/src/kernel/multiboot.h +++ b/src/kernel/multiboot.h @@ -90,183 +90,178 @@ #ifndef ASM_FILE -typedef u8 multiboot_u8; -typedef u16 multiboot_u16; -typedef u32 multiboot_u32; -typedef unsigned long long multiboot_u64; - struct multiboot_header { /* Must be MULTIBOOT_MAGIC - see above. */ - multiboot_u32 magic; + u32 magic; /* ISA */ - multiboot_u32 architecture; + u32 architecture; /* Total header length. */ - multiboot_u32 header_length; + u32 header_length; /* The above fields plus this one must equal 0 mod 2^32. */ - multiboot_u32 checksum; + u32 checksum; }; struct multiboot_header_tag { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; + u16 type; + u16 flags; + u32 size; }; struct multiboot_header_tag_information_request { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; - multiboot_u32 requests[0]; + u16 type; + u16 flags; + u32 size; + u32 requests[0]; }; struct multiboot_header_tag_address { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; - multiboot_u32 header_addr; - multiboot_u32 load_addr; - multiboot_u32 load_end_addr; - multiboot_u32 bss_end_addr; + u16 type; + u16 flags; + u32 size; + u32 header_addr; + u32 load_addr; + u32 load_end_addr; + u32 bss_end_addr; }; struct multiboot_header_tag_entry_address { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; - multiboot_u32 entry_addr; + u16 type; + u16 flags; + u32 size; + u32 entry_addr; }; struct multiboot_header_tag_console_flags { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; - multiboot_u32 console_flags; + u16 type; + u16 flags; + u32 size; + u32 console_flags; }; struct multiboot_header_tag_framebuffer { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; - multiboot_u32 width; - multiboot_u32 height; - multiboot_u32 depth; + u16 type; + u16 flags; + u32 size; + u32 width; + u32 height; + u32 depth; }; struct multiboot_header_tag_module_align { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; + u16 type; + u16 flags; + u32 size; }; struct multiboot_header_tag_relocatable { - multiboot_u16 type; - multiboot_u16 flags; - multiboot_u32 size; - multiboot_u32 min_addr; - multiboot_u32 max_addr; - multiboot_u32 align; - multiboot_u32 preference; + u16 type; + u16 flags; + u32 size; + u32 min_addr; + u32 max_addr; + u32 align; + u32 preference; }; struct multiboot_color { - multiboot_u8 red; - multiboot_u8 green; - multiboot_u8 blue; + u8 red; + u8 green; + u8 blue; }; struct multiboot_mmap_entry { - multiboot_u64 addr; - multiboot_u64 len; + u64 addr; + u64 len; #define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_RESERVED 2 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_NVS 4 #define MULTIBOOT_MEMORY_BADRAM 5 - multiboot_u32 type; - multiboot_u32 zero; + u32 type; + u32 zero; }; typedef struct multiboot_mmap_entry multiboot_memory_map_t; struct multiboot_tag { - multiboot_u32 type; - multiboot_u32 size; + u32 type; + u32 size; }; struct multiboot_tag_string { - multiboot_u32 type; - multiboot_u32 size; + u32 type; + u32 size; char string[0]; }; struct multiboot_tag_module { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 mod_start; - multiboot_u32 mod_end; + u32 type; + u32 size; + u32 mod_start; + u32 mod_end; char cmdline[0]; }; struct multiboot_tag_basic_meminfo { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 mem_lower; - multiboot_u32 mem_upper; + u32 type; + u32 size; + u32 mem_lower; + u32 mem_upper; }; struct multiboot_tag_bootdev { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 biosdev; - multiboot_u32 slice; - multiboot_u32 part; + u32 type; + u32 size; + u32 biosdev; + u32 slice; + u32 part; }; struct multiboot_tag_mmap { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 entry_size; - multiboot_u32 entry_version; + u32 type; + u32 size; + u32 entry_size; + u32 entry_version; struct multiboot_mmap_entry entries[0]; }; struct multiboot_vbe_info_block { - multiboot_u8 external_specification[512]; + u8 external_specification[512]; }; struct multiboot_vbe_mode_info_block { - multiboot_u8 external_specification[256]; + u8 external_specification[256]; }; struct multiboot_tag_vbe { - multiboot_u32 type; - multiboot_u32 size; + u32 type; + u32 size; - multiboot_u16 vbe_mode; - multiboot_u16 vbe_interface_seg; - multiboot_u16 vbe_interface_off; - multiboot_u16 vbe_interface_len; + u16 vbe_mode; + u16 vbe_interface_seg; + u16 vbe_interface_off; + u16 vbe_interface_len; struct multiboot_vbe_info_block vbe_control_info; struct multiboot_vbe_mode_info_block vbe_mode_info; }; struct multiboot_tag_framebuffer_common { - multiboot_u32 type; - multiboot_u32 size; - - multiboot_u64 framebuffer_addr; - multiboot_u32 framebuffer_pitch; - multiboot_u32 framebuffer_width; - multiboot_u32 framebuffer_height; - multiboot_u8 framebuffer_bpp; + u32 type; + u32 size; + + u64 framebuffer_addr; + u32 framebuffer_pitch; + u32 framebuffer_width; + u32 framebuffer_height; + u8 framebuffer_bpp; #define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 #define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 #define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - multiboot_u8 framebuffer_type; - multiboot_u16 reserved; + u8 framebuffer_type; + u16 reserved; }; struct multiboot_tag_framebuffer { @@ -274,106 +269,106 @@ struct multiboot_tag_framebuffer { union { struct { - multiboot_u16 framebuffer_palette_num_colors; + u16 framebuffer_palette_num_colors; struct multiboot_color framebuffer_palette[0]; }; struct { - multiboot_u8 framebuffer_red_field_position; - multiboot_u8 framebuffer_red_mask_size; - multiboot_u8 framebuffer_green_field_position; - multiboot_u8 framebuffer_green_mask_size; - multiboot_u8 framebuffer_blue_field_position; - multiboot_u8 framebuffer_blue_mask_size; + u8 framebuffer_red_field_position; + u8 framebuffer_red_mask_size; + u8 framebuffer_green_field_position; + u8 framebuffer_green_mask_size; + u8 framebuffer_blue_field_position; + u8 framebuffer_blue_mask_size; }; }; }; struct multiboot_tag_elf_sections { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 num; - multiboot_u32 entsize; - multiboot_u32 shndx; + u32 type; + u32 size; + u32 num; + u32 entsize; + u32 shndx; char sections[0]; }; struct multiboot_tag_apm { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u16 version; - multiboot_u16 cseg; - multiboot_u32 offset; - multiboot_u16 cseg_16; - multiboot_u16 dseg; - multiboot_u16 flags; - multiboot_u16 cseg_len; - multiboot_u16 cseg_16_len; - multiboot_u16 dseg_len; + u32 type; + u32 size; + u16 version; + u16 cseg; + u32 offset; + u16 cseg_16; + u16 dseg; + u16 flags; + u16 cseg_len; + u16 cseg_16_len; + u16 dseg_len; }; struct multiboot_tag_efs32 { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 pointer; + u32 type; + u32 size; + u32 pointer; }; struct multiboot_tag_efi64 { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u64 pointer; + u32 type; + u32 size; + u64 pointer; }; struct multiboot_tag_smbios { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u8 major; - multiboot_u8 minor; - multiboot_u8 reserved[6]; - multiboot_u8 tables[0]; + u32 type; + u32 size; + u8 major; + u8 minor; + u8 reserved[6]; + u8 tables[0]; }; struct multiboot_tag_old_acpi { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u8 rsdp[0]; + u32 type; + u32 size; + u8 rsdp[0]; }; struct multiboot_tag_new_acpi { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u8 rsdp[0]; + u32 type; + u32 size; + u8 rsdp[0]; }; struct multiboot_tag_network { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u8 dhcpack[0]; + u32 type; + u32 size; + u8 dhcpack[0]; }; struct multiboot_tag_efi_mmap { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 descr_size; - multiboot_u32 descr_vers; - multiboot_u8 efi_mmap[0]; + u32 type; + u32 size; + u32 descr_size; + u32 descr_vers; + u8 efi_mmap[0]; }; struct multiboot_tag_efs32_ih { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 pointer; + u32 type; + u32 size; + u32 pointer; }; struct multiboot_tag_efi64_ih { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u64 pointer; + u32 type; + u32 size; + u64 pointer; }; struct multiboot_tag_load_base_addr { - multiboot_u32 type; - multiboot_u32 size; - multiboot_u32 load_base_addr; + u32 type; + u32 size; + u32 load_base_addr; }; void multiboot_parse(); diff --git a/src/kernel/net/rtl8139.c b/src/kernel/net/rtl8139.c index fce2062..0c69025 100644 --- a/src/kernel/net/rtl8139.c +++ b/src/kernel/net/rtl8139.c @@ -73,7 +73,7 @@ int rtl8139_init(void) } // Set receive buffer - rtl_rx_buffer = (u8 *)kmalloc(8192 + 16); + rtl_rx_buffer = (u8 *)malloc(8192 + 16); outl((u16)(rtl_iobase + 0x30), (u32)rtl_rx_buffer); // Enable ISR diff --git a/src/kernel/syscall/actions/sys_free.c b/src/kernel/syscall/actions/sys_free.c index 79e5096..32e9ba8 100644 --- a/src/kernel/syscall/actions/sys_free.c +++ b/src/kernel/syscall/actions/sys_free.c @@ -3,6 +3,6 @@ u32 sys_free(u32 ptr) { - ufree((void *)ptr); + free((void *)ptr); return 0; }
\ No newline at end of file diff --git a/src/kernel/syscall/actions/sys_malloc.c b/src/kernel/syscall/actions/sys_malloc.c index 750530d..c68606b 100644 --- a/src/kernel/syscall/actions/sys_malloc.c +++ b/src/kernel/syscall/actions/sys_malloc.c @@ -3,5 +3,5 @@ u32 sys_malloc(u32 count) { - return (u32)umalloc(count); + return (u32)malloc(count); }
\ No newline at end of file diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c index ebb7a81..c4ab74a 100644 --- a/src/kernel/tasks/process.c +++ b/src/kernel/tasks/process.c @@ -31,6 +31,7 @@ void scheduler(struct regs *regs) } else { quantum--; locked = 0; + sti(); return; } @@ -57,6 +58,7 @@ void scheduler(struct regs *regs) memcpy(regs, ¤t_proc->registers, sizeof(struct regs)); paging_switch_directory(current_proc->cr3); locked = 0; + cli(); } void process_force_switch() @@ -133,6 +135,7 @@ u32 process_wait_pid(u32 pid, u32 *status) void process_suspend(u32 pid) { debug("Suspending process %d", pid); + process_print_tree(); if (pid == 1) panic("Root process died"); @@ -159,21 +162,6 @@ void process_wake(u32 pid) process_force_switch(); } -u32 process_child(struct process *child, u32 pid) -{ - debug("Spawning child process %d", pid); - process_suspend(pid); - - struct process *parent = process_from_pid(pid); - - if (parent == PID_NOT_FOUND) - panic("Child process spawned without parent"); - - child->parent = parent; - - return process_spawn(child); -} - struct process *process_from_pid(u32 pid) { struct process *proc = root; @@ -191,16 +179,16 @@ struct process *process_from_pid(u32 pid) struct process *process_make_new() { debug("Making new process %d", pid); - struct process *proc = (struct process *)kmalloc_a(sizeof(struct process)); + struct process *proc = (struct process *)malloc(sizeof(struct process)); proc->registers.cs = 0x1B; proc->registers.ds = 0x23; proc->registers.ss = 0x23; - proc->cr3 = paging_make_directory(); + proc->cr3 = paging_make_directory(1); proc->brk = 0x50000000; for (int i = 0; i < 1024; i++) - proc->cr3->tables[i] = paging_root_directory->tables[i]; + proc->cr3->tables[i] = paging_kernel_directory->tables[i]; proc->pid = pid++; return proc; @@ -221,13 +209,13 @@ u32 kexec(char *path) u32 uexec(char *path) { debug("Starting user process %s", path); - process_suspend(current_proc->pid); struct process *proc = elf_load(path); if (proc == NULL) return -1; process_spawn(proc); + process_suspend(current_proc->pid); log("Spawned"); return 0; } diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h index 25b11b2..08b30ed 100644 --- a/src/kernel/tasks/process.h +++ b/src/kernel/tasks/process.h @@ -34,7 +34,6 @@ void process_force_switch(); u32 process_spawn(struct process *process); void process_suspend(u32 pid); void process_wake(u32 pid); -u32 process_child(struct process *process, u32 pid); u32 process_wait_gid(u32 gid, u32 *status); u32 process_wait_pid(u32 pid, u32 *status); diff --git a/src/kernel/tasks/userspace.asm b/src/kernel/tasks/userspace.asm index a708184..ebdcf26 100644 --- a/src/kernel/tasks/userspace.asm +++ b/src/kernel/tasks/userspace.asm @@ -16,9 +16,7 @@ jump_userspace: pushf ; Enable interrupts - pop eax - or eax, 0x200 - push eax + sti push 0x1B push dword [hl_eip] diff --git a/src/kernel/timer/timer.c b/src/kernel/timer/timer.c index ad651f7..6f8ae85 100644 --- a/src/kernel/timer/timer.c +++ b/src/kernel/timer/timer.c @@ -3,7 +3,7 @@ #include <stdint.h> #include <system.h> -unsigned long timer_ticks = 0; +u64 timer_ticks = 0; void timer_phase(int hz) { diff --git a/src/userspace/programs/init.c b/src/userspace/programs/init.c index 724d11e..51aea63 100644 --- a/src/userspace/programs/init.c +++ b/src/userspace/programs/init.c @@ -32,7 +32,7 @@ void main() printf("INTs disabled :(\n"); // TODO: Fix page fault when mallocing - printf("Initializing userspace...\n"); + printf("Initializing userspace... %d\n", 42); // TODO: Fix scheduler turning off after spawn spawn("/bin/sh"); |