From bbf700a0c6b2f8ca9a73c2a334973286d5b8afcc Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Fri, 12 Mar 2021 19:11:26 +0100 Subject: Started basic ioctl fb interface --- libc/inc/sys.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libc/inc/sys.h') diff --git a/libc/inc/sys.h b/libc/inc/sys.h index 5858579..c20eabc 100644 --- a/libc/inc/sys.h +++ b/libc/inc/sys.h @@ -16,6 +16,7 @@ enum sys { SYS_STAT, // Get file information SYS_READ, // Read file SYS_WRITE, // Write to file + SYS_IOCTL, // Interact with a file/device SYS_POLL, // Wait for multiple files SYS_EXEC, // Execute path SYS_EXIT, // Exit current process // TODO: Free all memory of process @@ -70,6 +71,7 @@ int sysv(enum sys num, ...); (s32) sys4(SYS_READ, (int)(path), (int)(buf), (int)(offset), (int)(count)) #define write(path, buf, offset, count) \ (s32) sys4(SYS_WRITE, (int)(path), (int)(buf), (int)(offset), (int)(count)) +#define ioctl(path, ...) (s32) sysv(SYS_IOCTL, (int)(path), ##__VA_ARGS__) #define stat(path, stat) (s32) sys2(SYS_STAT, (int)(path), (int)(stat)) #define poll(files) (s32) sys1(SYS_POLL, (int)(files)) #define exec(path, ...) (s32) sysv(SYS_EXEC, (int)(path), ##__VA_ARGS__) -- cgit v1.2.3 From e8f17844d05fdc0e44d3793dc73996c7c09e44d6 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Fri, 12 Mar 2021 23:56:42 +0100 Subject: New memory allocation algorithms --- README.md | 4 +- apps/init.c | 3 +- kernel/features/mm.c | 6 - kernel/features/proc.c | 1 + kernel/features/syscall.c | 8 +- libc/alloc.c | 573 +++++++++++++++++++++++++--------------------- libc/inc/mem.h | 3 - libc/inc/sys.h | 2 +- 8 files changed, 327 insertions(+), 273 deletions(-) (limited to 'libc/inc/sys.h') diff --git a/README.md b/README.md index 4a320c4..745555b 100644 --- a/README.md +++ b/README.md @@ -84,14 +84,14 @@ This project is somewhat of a coding playground for me. It doesn't have any usef Melvix is released under the MIT License and uses parts of the following 3rd party projects: -Inspiration/usage: +Inspiration/usage (documented in the respective files): - [OSDev wiki](https://wiki.osdev.org) - Very helpful! - [James Molloy's tutorials](http://jamesmolloy.co.uk/tutorial_html/) - [virtix - tasking inspiration](https://github.com/16Bitt/virtix/) - [MIT License](https://github.com/16Bitt/virtix/blob/85a3c58f3d3b8932354e85a996a79c377139c201/LICENSE) - [studix - FS inspiration](https://github.com/orodley/studix) - [MIT License](https://github.com/orodley/studix/blob/d1b1d006010120551df58ff3faaf97484dfa9806/LICENSE) +- [skiftOS - Memory management inspiration](https://github.com/skiftOS/skift) - [MIT License](https://github.com/skiftOS/skift/blob/ea0e1cf0d7b07302370fc1519be2e072a4cad70c/license.md) - [ToAruOS - PCI and network driver inspiration](https://github.com/klange/toaruos) - [NCSA License](https://github.com/klange/toaruos/blob/351d5d38f22b570459931475d36468bf4e37f45a/LICENSE) -- [SHMALL - Heap allocator inspiration](https://github.com/CCareaga/heap_allocator) - [MIT License](https://github.com/CCareaga/heap_allocator/blob/fc423c6113df598ac8d10bc1f2954d51248e6443/LICENSE) Resources: diff --git a/apps/init.c b/apps/init.c index 6503022..705f178 100644 --- a/apps/init.c +++ b/apps/init.c @@ -8,7 +8,8 @@ int main(int argc, char **argv) { - log("%s loaded\n", argv[0]); + UNUSED(argc); + UNUSED(argv); while (1) { }; diff --git a/kernel/features/mm.c b/kernel/features/mm.c index 5fe70fd..b5fd33c 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -448,8 +448,6 @@ static struct memory_range kernel_memory_range(void) void memory_install(struct mem_info *mem_info) { - heap_init(HEAP_START); - for (struct mmap_boot *p = mem_info->start; (u32)(p - mem_info->start) < mem_info->size; p++) { if (p->hbase || !p->acpi || !p->type) @@ -486,10 +484,6 @@ void memory_install(struct mem_info *mem_info) memory_map_identity(&kernel_dir, memory_range_around(STACK_START - STACK_SIZE, STACK_SIZE), MEMORY_NONE); - // Map kernel heap - memory_map_identity(&kernel_dir, memory_range_around(HEAP_START, HEAP_INIT_SIZE), - MEMORY_NONE); - // TODO: Triple fault prevention? Probably bootloader stuff or something memory_map_identity(&kernel_dir, memory_range_around(0x7000, 0x1000), MEMORY_NONE); diff --git a/kernel/features/proc.c b/kernel/features/proc.c index e4b5105..e7ddf4b 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -487,6 +487,7 @@ void proc_init(void) struct node *new = list_add(proc_list, proc_make(PROC_PRIV_ROOT)); bin_load("/bin/init", new->data); current = new; + proc_stack_push(new->data, 0); _eip = ((struct proc *)new->data)->regs.eip; _esp = ((struct proc *)new->data)->regs.useresp; diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index bac1738..486da6c 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -25,12 +26,13 @@ static void syscall_handler(struct regs *r) loop(); break; } - case SYS_MALLOC: { - r->eax = (u32)malloc(r->ebx); + case SYS_ALLOC: { + r->eax = (u32)memory_alloc(proc_current()->page_dir, r->ebx, + MEMORY_CLEAR | MEMORY_USER); break; } case SYS_FREE: { - free((void *)r->ebx); + memory_free(proc_current()->page_dir, memory_range(r->ebx, r->ecx)); break; } case SYS_STAT: { diff --git a/libc/alloc.c b/libc/alloc.c index f621c4e..083f2c0 100644 --- a/libc/alloc.c +++ b/libc/alloc.c @@ -1,297 +1,383 @@ // MIT License, Copyright (c) 2021 Marvin Borner +// Mostly by Durand Miller, released into public domain #include -#include +#include #include -#include -#include - -/** - * Kernel heap allocator - * Inspired by SHMALL (MIT License) - * Copyright (c) 2017 Chris Careaga - * Copyright (c) 2021 Marvin Borner - */ #ifdef kernel -#define HEAP_MAGIC 0x424242 -#define HEAP_MIN_SIZE HEAP_INIT_SIZE -#define MIN_ALLOC_SZ 4 -#define BIN_COUNT 9 -#define BIN_MAX_IDX (BIN_COUNT - 1) -#define OVERHEAD (sizeof(struct h_footer) + sizeof(struct h_node)) -/* #define MIN_WILDERNESS 0x2000 */ -/* #define MAX_WILDERNESS 0x1000000 */ - -struct h_node { - u32 magic; - u32 hole; - u32 size; - struct h_node *next; - struct h_node *prev; -}; - -struct h_footer { - struct h_node *header; -}; +#include -struct h_bin { - struct h_node *head; -}; - -struct heap { - u32 start; - u32 end; - struct h_bin bins[BIN_COUNT]; -}; - -static void node_add(struct h_bin *bin, struct h_node *node) +static void *liballoc_alloc(u32 p) { - node->magic = HEAP_MAGIC; - node->next = NULL; - node->prev = NULL; - if (!bin->head) { - bin->head = node; - return; - } - struct h_node *curr = bin->head; - struct h_node *prev = NULL; - while (curr && curr->size <= node->size) { - prev = curr; - curr = curr->next; - } - if (!curr) { - prev->next = node; - node->prev = prev; - } else if (prev) { - node->next = curr; - prev->next = node; - node->prev = prev; - curr->prev = node; - } else { - node->next = bin->head; - bin->head->prev = node; - bin->head = node; - } + return memory_alloc(virtual_kernel_dir(), p, MEMORY_CLEAR); } -static void node_remove(struct h_bin *bin, struct h_node *node) +static int liballoc_free(void *ptr, u32 p) { - if (!bin->head) - return; - if (bin->head == node) { - bin->head = bin->head->next; - return; - } - - struct h_node *temp = bin->head->next; - while (temp) { - if (temp == node) { - if (!temp->next) { - temp->prev->next = NULL; - } else { - temp->prev->next = temp->next; - temp->next->prev = temp->prev; - } - return; - } - temp = temp->next; - } + memory_free(virtual_kernel_dir(), memory_range((u32)ptr, (u32)p)); + return 0; } -static struct h_node *node_best_fit(struct h_bin *bin, u32 size) -{ - if (!bin->head) - return NULL; +#else - struct h_node *temp = bin->head; - while (temp) { - if (temp->size >= size) - return temp; - temp = temp->next; - } - return NULL; -} +#include -/* static struct h_node *node_last(struct h_bin *bin) */ -/* { */ -/* struct h_node *temp = bin->head; */ -/* while (temp->next) */ -/* temp = temp->next; */ -/* return temp; */ -/* } */ +#define sys_alloc(size) (void *)sys1(SYS_ALLOC, size) +#define sys_free(ptr, size) (u32) sys2(SYS_FREE, ptr, size) -static struct h_footer *node_foot(struct h_node *node) +static void *liballoc_alloc(u32 p) { - return (struct h_footer *)((char *)node + sizeof(*node) + node->size); + return sys_alloc((u32)p); } -static void node_create_foot(struct h_node *head) +static int liballoc_free(void *ptr, u32 p) { - struct h_footer *foot = node_foot(head); - foot->header = head; + sys_free((u32)ptr, (u32)p); + return 0; } -static u32 bin_index(u32 sz) +#endif + +static int locked = 0; + +static int liballoc_lock(void) { - u32 index = 0; - sz = sz < 4 ? 4 : sz; - while (sz >>= 1) - index++; - index -= 2; - if (index > BIN_MAX_IDX) - index = BIN_MAX_IDX; - return index; + spinlock(&locked); + return 0; } -/* struct h_node *wilderness_get(struct heap *heap) */ -/* { */ -/* struct h_footer *wild_foot = (struct h_footer *)((char *)heap->end - sizeof(*wild_foot)); */ -/* return wild_foot->header; */ -/* } */ - -/* static u32 expand(struct heap *heap, u32 sz) */ -/* { */ -/* (void)heap; */ -/* (void)sz; */ -/* return 0; */ -/* } */ - -/* static u32 contract(struct heap *heap, u32 sz) */ -/* { */ -/* (void)heap; */ -/* (void)sz; */ -/* return 0; */ -/* } */ - -static struct heap heap = { 0 }; -void heap_init(u32 start) +static int liballoc_unlock(void) { - struct h_node *init_region = (struct h_node *)start; - init_region->hole = 1; - init_region->size = HEAP_INIT_SIZE - OVERHEAD; - node_create_foot(init_region); - node_add(&heap.bins[bin_index(init_region->size)], init_region); - heap.start = (u32)start; - heap.end = (u32)start + HEAP_INIT_SIZE; + locked = 0; + return 0; } -#define ALIGN sizeof(long) -static void *_malloc(u32 size) -{ - size = ((size + ALIGN - 1) / ALIGN) * ALIGN; // Alignment - u32 index = bin_index(size); - struct h_bin *temp = (struct h_bin *)&heap.bins[index]; - struct h_node *found = node_best_fit(temp, size); +#define ALIGNMENT 16 +#define ALIGN_UP(__addr, __align) (((__addr) + (__align)-1) & ~((__align)-1)) +#define ALIGN_DOWN(__addr, __align) ((__addr) & ~((__align)-1)) + +#define USE_CASE1 +#define USE_CASE2 +#define USE_CASE3 +#define USE_CASE4 +#define USE_CASE5 +#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; +}; - while (!found) { - assert(index + 1 < BIN_COUNT); +struct liballoc_minor { + struct liballoc_minor *prev; + struct liballoc_minor *next; + struct liballoc_major *block; + u32 magic; + u32 size; + u32 req_size; +}; - temp = &heap.bins[++index]; - found = node_best_fit(temp, size); - } +#define MAJOR_SIZE (ALIGN_UP(sizeof(struct liballoc_major), 16)) +#define MINOR_SIZE (ALIGN_UP(sizeof(struct liballoc_minor), 16)) +#define MIN(__x, __y) ((__x) < (__y) ? (__x) : (__y)) +#define MAX(__x, __y) ((__x) > (__y) ? (__x) : (__y)) - assert(found->magic == HEAP_MAGIC); +static struct liballoc_major *l_mem_root = NULL; +static struct liballoc_major *l_best_bet = NULL; - if ((found->size - size) > (OVERHEAD + MIN_ALLOC_SZ)) { - struct h_node *split = (struct h_node *)(((char *)found + OVERHEAD) + size); - split->magic = HEAP_MAGIC; - split->size = found->size - size - OVERHEAD; - split->hole = 1; +static u32 l_page_size = 4096; +static u32 l_page_count = 16; - node_create_foot(split); +static struct liballoc_major *allocate_new_page(u32 size) +{ + u32 st = size + MAJOR_SIZE + MINOR_SIZE; - u32 new_idx = bin_index(split->size); + if ((st % l_page_size) == 0) + st = st / (l_page_size); + else + st = st / (l_page_size) + 1; - node_add(&heap.bins[new_idx], split); + st = MAX(st, l_page_count); - found->size = size; - node_create_foot(found); - } + struct liballoc_major *maj = (struct liballoc_major *)liballoc_alloc(st * l_page_size); - found->hole = 0; - node_remove(&heap.bins[index], found); + if (maj == NULL) + return NULL; - // TODO: Implement expand/contract - /* struct h_node *wild = wilderness_get(&heap); */ - /* if (wild->size < MIN_WILDERNESS) { */ - /* assert(expand(&heap, 0x1000)); */ - /* } else if (wild->size > MAX_WILDERNESS) { */ - /* assert(contract(&heap, 0x1000)); */ - /* } */ + maj->prev = NULL; + maj->next = NULL; + maj->pages = st; + maj->size = st * l_page_size; + maj->usage = MAJOR_SIZE; + maj->first = NULL; - found->prev = NULL; - found->next = NULL; - return &found->next; + return maj; } -static void _free(void *p) +static void *_malloc(u32 req_size) { - if (!p) - return; + req_size = ALIGN_UP(req_size, 16); - struct h_bin *list; - struct h_footer *new_foot, *old_foot; + u32 best_size = 0; + u32 size = req_size; - struct h_node *head = (struct h_node *)((char *)p - 12); - assert(head->magic == HEAP_MAGIC && head->hole == 0); - if (head == (struct h_node *)(u32 *)heap.start) { - head->hole = 1; - node_add(&heap.bins[bin_index(head->size)], head); - return; + liballoc_lock(); + + if (size == 0) { + liballoc_unlock(); + return malloc(1); } - struct h_node *next = (struct h_node *)((char *)node_foot(head) + sizeof(struct h_footer)); - struct h_footer *f = (struct h_footer *)((char *)head - sizeof(struct h_footer)); - struct h_node *prev = f->header; + if (l_mem_root == NULL) { + l_mem_root = allocate_new_page(size); + if (l_mem_root == NULL) { + liballoc_unlock(); + return NULL; + } + } - if (prev->hole) { - list = &heap.bins[bin_index(prev->size)]; - node_remove(list, prev); + struct liballoc_major *maj = l_mem_root; + u8 started_bet = 0; - prev->size += OVERHEAD + head->size; - new_foot = node_foot(head); - new_foot->header = prev; + if (l_best_bet != NULL) { + best_size = l_best_bet->size - l_best_bet->usage; - head = prev; + if (best_size > (size + MINOR_SIZE)) { + maj = l_best_bet; + started_bet = 1; + } } - if (next->hole) { - list = &heap.bins[bin_index(next->size)]; - node_remove(list, next); + while (maj != NULL) { + u32 diff = maj->size - maj->usage; + if (best_size < diff) { + l_best_bet = maj; + best_size = diff; + } - head->size += OVERHEAD + next->size; +#ifdef USE_CASE1 + if (diff < (size + MINOR_SIZE)) { + if (maj->next != NULL) { + maj = maj->next; + continue; + } - old_foot = node_foot(next); - old_foot->header = 0; - next->size = 0; - next->hole = 0; + if (started_bet == 1) { + maj = l_mem_root; + started_bet = 0; + continue; + } - new_foot = node_foot(head); - new_foot->header = head; - } + maj->next = allocate_new_page(size); + if (maj->next == NULL) + break; + maj->next->prev = maj; + maj = maj->next; + } +#endif - head->hole = 1; - node_add(&heap.bins[bin_index(head->size)], head); -} +#ifdef USE_CASE2 + if (maj->first == NULL) { + maj->first = (struct liballoc_minor *)((u32)maj + MAJOR_SIZE); + + 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 + MINOR_SIZE; + void *p = (void *)((u32)(maj->first) + MINOR_SIZE); + liballoc_unlock(); + return p; + } +#endif + +#ifdef USE_CASE3 + diff = (u32)(maj->first); + diff -= (u32)maj; + diff -= MAJOR_SIZE; + + if (diff >= (size + MINOR_SIZE)) { + maj->first->prev = (struct liballoc_minor *)((u32)maj + MAJOR_SIZE); + 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 + MINOR_SIZE; + void *p = (void *)((u32)(maj->first) + MINOR_SIZE); + liballoc_unlock(); + return p; + } +#endif -#elif defined(userspace) +#ifdef USE_CASE4 + struct liballoc_minor *min = maj->first; + + while (min != NULL) { + if (min->next == NULL) { + diff = (u32)(maj) + maj->size; + diff -= (u32)min; + diff -= MINOR_SIZE; + diff -= min->size; + if (diff >= (size + MINOR_SIZE)) { + min->next = + (struct liballoc_minor *)((u32)min + MINOR_SIZE + + 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 + MINOR_SIZE; + void *p = (void *)((u32)min + MINOR_SIZE); + liballoc_unlock(); + return p; + } + } -#define kmalloc(n) (void *)sys1(SYS_MALLOC, n) -#define kfree(ptr) (void)(sys1(SYS_FREE, (int)ptr)) + if (min->next != NULL) { + diff = (u32)(min->next); + diff -= (u32)min; + diff -= MINOR_SIZE; + diff -= min->size; + + if (diff >= (size + MINOR_SIZE)) { + struct liballoc_minor *new_min = + (struct liballoc_minor *)((u32)min + MINOR_SIZE + + 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 + MINOR_SIZE; + void *p = (void *)((u32)new_min + MINOR_SIZE); + liballoc_unlock(); + return p; + } + } -static void *_malloc(u32 size) -{ - return kmalloc(size); + min = min->next; + } +#endif + +#ifdef USE_CASE5 + if (maj->next == NULL) { + if (started_bet == 1) { + maj = l_mem_root; + started_bet = 0; + continue; + } + maj->next = allocate_new_page(size); + if (maj->next == NULL) + break; + maj->next->prev = maj; + } +#endif + maj = maj->next; + } + + liballoc_unlock(); + + return NULL; } static void _free(void *ptr) { - kfree(ptr); + if (ptr == NULL) { + return; + } + + liballoc_lock(); + + struct liballoc_minor *min = (struct liballoc_minor *)((u32)ptr - MINOR_SIZE); + + if (min->magic != LIBALLOC_MAGIC) { + liballoc_unlock(); + return; + } + + struct liballoc_major *maj = min->block; + maj->usage -= (min->size + MINOR_SIZE); + 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; + liballoc_free(maj, maj->pages * l_page_size); + } 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(); } -#endif +static void *_realloc(void *ptr, u32 size) +{ + size = ALIGN_UP(size, 16); + + if (size == 0) { + free(ptr); + return NULL; + } + + if (ptr == NULL) + return malloc(size); + + liballoc_lock(); + struct liballoc_minor *min = (struct liballoc_minor *)((u32)ptr - MINOR_SIZE); + + if (min->magic != LIBALLOC_MAGIC) { + liballoc_unlock(); + return NULL; + } + + if (min->size >= size) { + min->req_size = size; + liballoc_unlock(); + return ptr; + } + + liballoc_unlock(); + + void *new_ptr = malloc(size); + memcpy(new_ptr, ptr, min->req_size); + free(ptr); + + return new_ptr; +} #ifdef kernel #define PREFIX "K" @@ -303,42 +389,18 @@ static void _free(void *ptr) void *zalloc(u32 size) { -#ifdef userspace - panic("AAH!\n"); -#endif void *ret = malloc(size); memset(ret, 0, size); return ret; } -// Naive realloc implementation - TODO! void *realloc(void *ptr, u32 size) { -#ifdef userspace - panic("AAH!\n"); -#endif - if (!ptr) - return malloc(size); - - FUNC("Realloc not implemented!\n"); - return NULL; - /* // This could work; untested - struct h_node *node = (struct h_node *)((char *)ptr - 12); - u32 old_size = node->size; - - void *new = malloc(size); - memcpy(new, ptr, old_size); - - free(ptr); - return new; - */ + return _realloc(ptr, size); } void *malloc_debug(u32 size, const char *file, int line, const char *func, const char *inp) { -#ifdef userspace - panic("AAH!\n"); -#endif assert(size < (100 << 20)); // Don't brag with memory pls void *ret = _malloc(size); @@ -352,9 +414,6 @@ void *malloc_debug(u32 size, const char *file, int line, const char *func, const void free_debug(void *ptr, const char *file, int line, const char *func, const char *inp) { -#ifdef userspace - panic("AAH!\n"); -#endif if (ptr) _free(ptr); diff --git a/libc/inc/mem.h b/libc/inc/mem.h index e93f4d2..ec00628 100644 --- a/libc/inc/mem.h +++ b/libc/inc/mem.h @@ -15,9 +15,6 @@ void *zalloc(u32 size); #ifdef kernel #define STACK_START 0x00500000 // Defined it bootloader #define STACK_SIZE 0x1000 // idk -#define HEAP_START 0x00f00000 -#define HEAP_INIT_SIZE 0x0f00000 -void heap_init(u32 start); #elif defined(userspace) #else #error "No lib target specified. Please use -Dkernel or -Duserspace" diff --git a/libc/inc/sys.h b/libc/inc/sys.h index c20eabc..c100e6a 100644 --- a/libc/inc/sys.h +++ b/libc/inc/sys.h @@ -11,7 +11,7 @@ enum sys { SYS_LOOP, // To infinity and beyond (debug)! - SYS_MALLOC, // Allocate memory + SYS_ALLOC, // Allocate memory SYS_FREE, // Free memory SYS_STAT, // Get file information SYS_READ, // Read file -- cgit v1.2.3 From 606774e6b0e0a2d36139983b85c8675b2228a9ff Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 13 Mar 2021 00:38:36 +0100 Subject: Fixed test suite --- .github/workflows/build.yml | 2 +- apps/test.c | 6 +----- kernel/features/syscall.c | 25 ++++++++++++++++++++++++- libc/crt/crt0.asm | 2 +- libc/inc/sys.h | 10 ++++++++-- 5 files changed, 35 insertions(+), 10 deletions(-) (limited to 'libc/inc/sys.h') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d909e45..9e9c29f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: - name: Checkout uses: actions/checkout@v2 - name: Install - run: sudo apt-get update && sudo apt-get install -y build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo libcloog-isl-dev libisl-0.18-dev ccache curl nasm grub-common qemu qemu-kvm mtools ctags + run: sudo apt-get update && sudo apt-get install -y build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo ccache curl nasm grub-common qemu qemu-kvm mtools ctags - name: Get cross compiler id: cache-cross uses: actions/cache@v1 diff --git a/apps/test.c b/apps/test.c index 80f24ad..d64e224 100644 --- a/apps/test.c +++ b/apps/test.c @@ -82,11 +82,7 @@ int main(void) else log("All tests passed\n"); - // Try emulator shutdown - outw(0xB004, 0x2000); - outw(0x604, 0x2000); - outw(0x4004, 0x3400); + boot(SYS_BOOT_SHUTDOWN); - loop(); return 0; } diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index 486da6c..31cdf5f 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -86,9 +86,32 @@ static void syscall_handler(struct regs *r) break; } case SYS_EXIT: { + print("EXIT!\n"); proc_exit(proc_current(), (int)r->ebx); break; } + case SYS_BOOT: { // TODO: Move + if (r->ebx != SYS_BOOT_MAGIC || !proc_super()) { + r->eax = -1; + break; + } + switch (r->ecx) { + case SYS_BOOT_REBOOT: + print("Rebooting...\n"); + __asm__ volatile("ud2"); + break; + case SYS_BOOT_SHUTDOWN: + print("Shutting down...\n"); + outw(0xB004, 0x2000); + outw(0x604, 0x2000); + outw(0x4004, 0x3400); + __asm__ volatile("ud2"); + break; + default: + r->eax = -1; + } + break; + } case SYS_YIELD: { proc_yield(r); break; @@ -130,7 +153,7 @@ static void syscall_handler(struct regs *r) break; } default: { - print("Unknown syscall!\n"); + printf("Unknown syscall %d!\n", num); break; } } diff --git a/libc/crt/crt0.asm b/libc/crt/crt0.asm index a0621ff..0f8024d 100644 --- a/libc/crt/crt0.asm +++ b/libc/crt/crt0.asm @@ -10,6 +10,6 @@ _start: call main push eax - push 8 + push 9 call sys1 jmp $ diff --git a/libc/inc/sys.h b/libc/inc/sys.h index c100e6a..3125cb0 100644 --- a/libc/inc/sys.h +++ b/libc/inc/sys.h @@ -9,6 +9,10 @@ #define KEYBOARD_MAGIC 0x555555 #define MOUSE_MAGIC 0xaaaaaa +#define SYS_BOOT_MAGIC 0x18122002 +#define SYS_BOOT_REBOOT 0xeeb007 +#define SYS_BOOT_SHUTDOWN 0xdead + enum sys { SYS_LOOP, // To infinity and beyond (debug)! SYS_ALLOC, // Allocate memory @@ -19,7 +23,8 @@ enum sys { SYS_IOCTL, // Interact with a file/device SYS_POLL, // Wait for multiple files SYS_EXEC, // Execute path - SYS_EXIT, // Exit current process // TODO: Free all memory of process + SYS_EXIT, // Exit current process + SYS_BOOT, // Boot functions (e.g. reboot/shutdown) SYS_YIELD, // Switch to next process SYS_TIME, // Get kernel time SYS_NET_OPEN, // Open network socket @@ -82,7 +87,8 @@ int sysv(enum sys num, ...); yield(); \ } \ } -#define yield(void) (int)sys0(SYS_YIELD) +#define boot(cmd) (s32) sys2(SYS_BOOT, SYS_BOOT_MAGIC, cmd) +#define yield(void) (s32) sys0(SYS_YIELD) #define time(void) (u32) sys0(SYS_TIME) static inline u32 getpid(void) -- cgit v1.2.3 From 6dec7db5158447b66f31a3f786ce2916cab83cec Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sun, 14 Mar 2021 16:06:57 +0100 Subject: Maaany fixes :) I don't have the motivation to write better commit messages... --- apps/init.c | 6 ++-- apps/window.c | 4 +++ apps/wm.c | 71 ++++++++++++++++++++------------------------- kernel/drivers/interrupts.c | 4 +++ kernel/drivers/keyboard.c | 6 ++-- kernel/drivers/mouse.c | 6 ++-- kernel/features/fs.c | 4 +-- kernel/features/mm.c | 4 +-- kernel/features/proc.c | 20 ++++++++++--- kernel/inc/mm.h | 3 ++ libc/alloc.c | 2 -- libc/inc/def.h | 3 ++ libc/inc/sys.h | 4 ++- libgui/gfx.c | 9 +++--- libgui/gui.c | 18 ++++++++---- libgui/inc/gfx.h | 7 ++--- libgui/inc/gui.h | 3 +- libgui/inc/msg.h | 24 +++++++++++---- libgui/msg.c | 22 +++++++------- run | 9 +++++- 20 files changed, 135 insertions(+), 94 deletions(-) (limited to 'libc/inc/sys.h') diff --git a/apps/init.c b/apps/init.c index f854a81..c59e3bf 100644 --- a/apps/init.c +++ b/apps/init.c @@ -6,13 +6,15 @@ #include #include +#include + int main(int argc, char **argv) { UNUSED(argc); UNUSED(argv); int wm = exec("/bin/wm", "wm", NULL); - /* int test = exec("/bin/window", "test", NULL); */ + int test = exec("/bin/window", "test", NULL); - return wm; //+ test; + return wm + test; } diff --git a/apps/window.c b/apps/window.c index ac29ba1..90a414c 100644 --- a/apps/window.c +++ b/apps/window.c @@ -8,6 +8,9 @@ int main(void) { struct gui_window win = { 0 }; assert(gui_new_window(&win) > 0); + while (1) + ; +#if 0 gfx_fill(win.ctx, COLOR_GREEN); // Professional testing for (int i = 0; i < 12; i++) { @@ -16,5 +19,6 @@ int main(void) } assert(gui_redraw_window(win.id) > 0); log("%d\n", win.ctx->size.x); +#endif return 0; } diff --git a/apps/wm.c b/apps/wm.c index 8eb6f70..ecc7cb2 100644 --- a/apps/wm.c +++ b/apps/wm.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -308,46 +309,34 @@ static void handle_event_mouse(struct event_mouse *event) window_redraw(cursor); } -static void handle_message_new_window(struct message *msg) +static void handle_message_new_window(struct message_new_window *msg) { - if (!msg->data) { - msg_send(msg->src, GUI_NEW_WINDOW | MSG_FAILURE, NULL); - return; - } - struct gui_window *buf = msg->data; - struct window *win = window_new((struct client){ .pid = msg->src }, "idk", vec2(500, 600), - vec2(600, 400), 0); - buf->id = win->id; - buf->ctx = &win->ctx; - buf->pos = &win->pos; - msg_send(msg->src, GUI_NEW_WINDOW | MSG_SUCCESS, NULL); + struct window *win = window_new((struct client){ .pid = msg->header.src }, "idk", + vec2(500, 600), vec2(600, 400), 0); + msg->ctx = win->ctx; + msg->id = win->id; + msg_send(msg->header.src, GUI_NEW_WINDOW | MSG_SUCCESS, msg, sizeof(*msg)); /* window_redraw(win); */ } -static void handle_message_redraw_window(struct message *msg) +static void handle_message_redraw_window(struct message_redraw_window *msg) { - if (!msg->data) { - msg_send(msg->src, GUI_REDRAW_WINDOW | MSG_FAILURE, NULL); - return; - } - u32 id = *(u32 *)msg->data; + u32 id = msg->id; struct window *win = window_find(id); if (!win) { - msg_send(msg->src, GUI_REDRAW_WINDOW | MSG_FAILURE, NULL); + msg_send(msg->header.src, GUI_REDRAW_WINDOW | MSG_FAILURE, NULL, + sizeof(msg->header)); return; } - msg_send(msg->src, GUI_REDRAW_WINDOW | MSG_SUCCESS, NULL); + msg_send(msg->header.src, GUI_REDRAW_WINDOW | MSG_SUCCESS, NULL, sizeof(msg->header)); window_redraw(win); } -static void handle_message(struct message *msg) +static void handle_message(void *msg) { - if (msg->magic != MSG_MAGIC) { - log("Message magic doesn't match!\n"); - return; - } + struct message_header *header = msg; - switch (msg->type) { + switch (header->type) { case GUI_NEW_WINDOW: handle_message_new_window(msg); break; @@ -355,8 +344,8 @@ static void handle_message(struct message *msg) handle_message_redraw_window(msg); break; default: - log("Message type %d not implemented!\n", msg->type); - msg_send(msg->src, MSG_FAILURE, NULL); + log("Message type %d not implemented!\n", header->type); + msg_send(header->src, MSG_FAILURE, NULL, sizeof(*header)); } } @@ -389,32 +378,34 @@ int main(int argc, char **argv) gfx_load_wallpaper(&cursor->ctx, "/res/cursor.png"); window_redraw(wallpaper); - struct message msg = { 0 }; + u8 msg[1024] = { 0 }; struct event_keyboard event_keyboard = { 0 }; struct event_mouse event_mouse = { 0 }; - const char *listeners[] = { "/dev/kbd", "/dev/mouse", "/proc/self/msg" }; + const char *listeners[] = { "/dev/kbd", "/dev/mouse", "/proc/self/msg", NULL }; while (1) { int poll_ret = 0; if ((poll_ret = poll(listeners)) >= 0) { if (poll_ret == 0) { if (read(listeners[poll_ret], &event_keyboard, 0, - sizeof(event_keyboard)) > 0) + sizeof(event_keyboard)) > 0) { handle_event_keyboard(&event_keyboard); - continue; + continue; + } } else if (poll_ret == 1) { if (read(listeners[poll_ret], &event_mouse, 0, - sizeof(event_mouse)) > 0) + sizeof(event_mouse)) > 0) { handle_event_mouse(&event_mouse); - continue; + continue; + } } else if (poll_ret == 2) { - if (read(listeners[poll_ret], &msg, 0, sizeof(msg)) > 0) - handle_message(&msg); - continue; + if (msg_receive(msg, 1024) > 0) { + handle_message(msg); + continue; + } } - } else { - err(1, "POLL ERROR!\n"); } - }; + panic("Poll/read error!\n"); + } // TODO: Execute? free(keymap); diff --git a/kernel/drivers/interrupts.c b/kernel/drivers/interrupts.c index fe2321a..2e1444f 100644 --- a/kernel/drivers/interrupts.c +++ b/kernel/drivers/interrupts.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -236,6 +237,9 @@ static void isr_install(void) // Set default routines for (u32 i = 0; i < 256; i++) isr_routines[i] = isr_panic; + + // Set page fault handler + isr_install_handler(14, page_fault_handler); } /** diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index 3ae3c0e..dbee8e1 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -66,10 +66,10 @@ static s32 keyboard_read(void *buf, u32 offset, u32 count, struct device *dev) if (stack_empty(queue)) return -1; - struct event *e = stack_pop(queue); - memcpy(buf, (u8 *)e + offset, count); + struct event_keyboard *e = stack_pop(queue); + memcpy(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); free(e); - return count; + return MIN(count, sizeof(*e)); } static u8 keyboard_ready(void) diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c index 40094d1..5c481da 100644 --- a/kernel/drivers/mouse.c +++ b/kernel/drivers/mouse.c @@ -94,10 +94,10 @@ static s32 mouse_read(void *buf, u32 offset, u32 count, struct device *dev) if (stack_empty(queue)) return -1; - struct event *e = stack_pop(queue); - memcpy(buf, (u8 *)e + offset, count); + struct event_mouse *e = stack_pop(queue); + memcpy(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); free(e); - return count; + return MIN(count, sizeof(*e)); } void mouse_install(void) diff --git a/kernel/features/fs.c b/kernel/features/fs.c index 20d00e5..c8ad317 100644 --- a/kernel/features/fs.c +++ b/kernel/features/fs.c @@ -122,7 +122,7 @@ s32 vfs_mount(struct device *dev, const char *path) s32 vfs_read(const char *path, void *buf, u32 offset, u32 count) { - /* printf("%s READ: %s\n", proc_current()->name, path); */ + /* printf("%s READ: %s\n", proc_current() ? proc_current()->name : "Unknown", path); */ if (!count) return 0; @@ -148,7 +148,7 @@ s32 vfs_read(const char *path, void *buf, u32 offset, u32 count) s32 vfs_write(const char *path, void *buf, u32 offset, u32 count) { - /* printf("%s WRITE: %s\n", proc_current()->name, path); */ + /* printf("%s WRITE: %s\n", proc_current() ? proc_current()->name : "Unknown", path); */ if (!count) return 0; diff --git a/kernel/features/mm.c b/kernel/features/mm.c index bd32683..9eca438 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -32,7 +32,7 @@ static void paging_switch_dir(u32 dir) extern void paging_invalidate_tlb(void); -static void page_fault(struct regs *r) +void page_fault_handler(struct regs *r) { // Check error code const char *type = (r->err_code & 1) ? "present" : "non-present"; @@ -495,6 +495,4 @@ void memory_install(struct mem_info *mem_info, struct vid_info *vid_info) memory_switch_dir(&kernel_dir); paging_enable(); - - isr_install_handler(14, page_fault); } diff --git a/kernel/features/proc.c b/kernel/features/proc.c index 6bbe894..b93f7c8 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -305,6 +305,11 @@ static enum stream_defaults procfs_stream(const char *path) } } +struct procfs_message { + u8 *data; + u32 size; +}; + static s32 procfs_write(const char *path, void *buf, u32 offset, u32 count, struct device *dev) { u32 pid = 0; @@ -318,7 +323,10 @@ static s32 procfs_write(const char *path, void *buf, u32 offset, u32 count, stru if (!memcmp(path, "msg", 4)) { void *msg_data = malloc(count); memcpy(msg_data, buf, count); - stack_push_bot(p->messages, msg_data); // TODO: Use offset + struct procfs_message *msg = malloc(sizeof(*msg)); + msg->data = msg_data; + msg->size = count; + stack_push_bot(p->messages, msg); // TODO: Use offset proc_enable_waiting(pid, PROC_WAIT_MSG); return count; } else if (!memcmp(path, "io/", 3)) { @@ -371,12 +379,13 @@ static s32 procfs_read(const char *path, void *buf, u32 offset, u32 count, struc if (stack_empty(p->messages)) { return -1; // This shouldn't happen } else { - u8 *msg = stack_pop(p->messages); + struct procfs_message *msg = stack_pop(p->messages); if (!msg) return -1; - memcpy(buf, msg + offset, count); + memcpy(buf, msg->data + offset, MIN(count, msg->size)); + free(msg->data); free(msg); - return count; + return MIN(count, msg->size); } } else if (!memcmp(path, "io/", 3)) { path += 3; @@ -500,7 +509,10 @@ void proc_init(void) printf("Jumping to userspace!\n"); memory_switch_dir(((struct proc *)new->data)->page_dir); + + // You're waiting for a train. A train that will take you far away... proc_jump_userspace(); + while (1) { }; } diff --git a/kernel/inc/mm.h b/kernel/inc/mm.h index 590875c..d3e37f6 100644 --- a/kernel/inc/mm.h +++ b/kernel/inc/mm.h @@ -5,6 +5,7 @@ #include #include +#include struct memory_range { u32 base; @@ -102,4 +103,6 @@ void memory_backup_dir(struct page_dir **backup); void memory_install(struct mem_info *mem_info, struct vid_info *vid_info); +void page_fault_handler(struct regs *r); + #endif diff --git a/libc/alloc.c b/libc/alloc.c index 4ccf35f..be986dc 100644 --- a/libc/alloc.c +++ b/libc/alloc.c @@ -86,8 +86,6 @@ struct liballoc_minor { #define MAJOR_SIZE (ALIGN_UP(sizeof(struct liballoc_major), 16)) #define MINOR_SIZE (ALIGN_UP(sizeof(struct liballoc_minor), 16)) -#define MIN(__x, __y) ((__x) < (__y) ? (__x) : (__y)) -#define MAX(__x, __y) ((__x) > (__y) ? (__x) : (__y)) static struct liballoc_major *l_mem_root = NULL; static struct liballoc_major *l_best_bet = NULL; diff --git a/libc/inc/def.h b/libc/inc/def.h index db1c95e..c334fcb 100644 --- a/libc/inc/def.h +++ b/libc/inc/def.h @@ -25,6 +25,9 @@ typedef unsigned long long u64; #define UNUSED(a) ((void)(a)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + #define NORETURN __attribute__((noreturn)) #define NO_SANITIZE __attribute__((no_sanitize("undefined"))) #define PACKED __attribute__((packed)) diff --git a/libc/inc/sys.h b/libc/inc/sys.h index 3125cb0..8add0de 100644 --- a/libc/inc/sys.h +++ b/libc/inc/sys.h @@ -93,7 +93,9 @@ int sysv(enum sys num, ...); static inline u32 getpid(void) { - u32 buf = 0; + static u32 buf = 0; + if (buf) + return buf; read("/proc/self/pid", &buf, 0, sizeof(buf)); return buf; } diff --git a/libgui/gfx.c b/libgui/gfx.c index d9457c7..dad8b88 100644 --- a/libgui/gfx.c +++ b/libgui/gfx.c @@ -98,10 +98,11 @@ static void draw_rectangle(struct context *ctx, vec2 pos1, vec2 pos2, u32 c) struct context *gfx_new_ctx(struct context *ctx) { - struct message msg = { 0 }; - assert(msg_send(pidof(WM_PATH), GFX_NEW_CONTEXT, ctx) > 0); - assert(msg_receive(&msg) > 0); - memcpy(ctx, msg.data, sizeof(*ctx)); + /* struct message msg = { 0 }; */ + assert(0); + /* assert(msg_send(pidof(WM_PATH), GFX_NEW_CONTEXT, ctx) > 0); */ + /* assert(msg_receive(&msg) > 0); */ + /* memcpy(ctx, msg.data, sizeof(*ctx)); */ return ctx; } diff --git a/libgui/gui.c b/libgui/gui.c index 2083f23..bc8adb1 100644 --- a/libgui/gui.c +++ b/libgui/gui.c @@ -2,24 +2,30 @@ #include #include +#include #include #define WM_PATH "/bin/wm" s32 gui_new_window(struct gui_window *win) { - struct message msg = { 0 }; - if (msg_send(pidof(WM_PATH), GUI_NEW_WINDOW, win) > 0 && msg_receive(&msg) > 0 && - msg.type == (GUI_NEW_WINDOW | MSG_SUCCESS)) + struct message_new_window msg = { 0 }; + if (msg_send(pidof(WM_PATH), GUI_NEW_WINDOW, &msg, sizeof(msg)) > 0 && + msg_receive(&msg, sizeof(msg)) > 0 && + msg.header.type == (GUI_NEW_WINDOW | MSG_SUCCESS)) { + win->id = msg.id; + win->ctx = msg.ctx; return win->id; + } return -1; } s32 gui_redraw_window(u32 id) { - struct message msg = { 0 }; - if (msg_send(pidof(WM_PATH), GUI_REDRAW_WINDOW, &id) > 0 && msg_receive(&msg) > 0 && - msg.type == (GUI_REDRAW_WINDOW | MSG_SUCCESS)) + struct message_redraw_window msg = { .id = id }; + if (msg_send(pidof(WM_PATH), GUI_REDRAW_WINDOW, &msg, sizeof(msg)) > 0 && + msg_receive(&msg, sizeof(msg)) > 0 && + msg.header.type == (GUI_REDRAW_WINDOW | MSG_SUCCESS)) return id; return -1; } diff --git a/libgui/inc/gfx.h b/libgui/inc/gfx.h index 4a358ca..f3555a4 100644 --- a/libgui/inc/gfx.h +++ b/libgui/inc/gfx.h @@ -5,7 +5,6 @@ #define GFX_H #include -#include #include #include #include @@ -82,8 +81,8 @@ int gfx_font_width(enum font_type); * Wrappers */ -#define gfx_redraw() \ - (msg_send(pidof(WM_PATH), GFX_REDRAW, NULL)) // TODO: Partial redraw (optimization) -#define gfx_redraw_focused() (msg_send(pidof(WM_PATH), GFX_REDRAW_FOCUSED, NULL)) +/* #define gfx_redraw() \ */ +/* (msg_send(pidof(WM_PATH), GFX_REDRAW, NULL)) // TODO: Partial redraw (optimization) */ +/* #define gfx_redraw_focused() (msg_send(pidof(WM_PATH), GFX_REDRAW_FOCUSED, NULL)) */ #endif diff --git a/libgui/inc/gui.h b/libgui/inc/gui.h index 460bf88..d160333 100644 --- a/libgui/inc/gui.h +++ b/libgui/inc/gui.h @@ -8,8 +8,7 @@ struct gui_window { u32 id; - struct context *ctx; - vec2 *pos; + struct context ctx; }; s32 gui_new_window(struct gui_window *win); diff --git a/libgui/inc/msg.h b/libgui/inc/msg.h index db00460..7cbfa2c 100644 --- a/libgui/inc/msg.h +++ b/libgui/inc/msg.h @@ -4,16 +4,28 @@ #define MSG_H #include +#include #define MSG_MAGIC 0x42042069 #define MSG_SUCCESS (1 << 29) #define MSG_FAILURE (1 << 30) -struct message { +struct message_header { u32 magic; - int src; - int type; - void *data; + u32 src; + u32 type; + u32 size; +}; + +struct message_new_window { + struct message_header header; + u32 id; + struct context ctx; +}; + +struct message_redraw_window { + struct message_header header; + u32 id; }; enum message_type { @@ -32,7 +44,7 @@ enum message_type { GUI_MAX }; -int msg_send(u32 pid, enum message_type, void *data); -int msg_receive(struct message *msg); +int msg_send(u32 pid, enum message_type type, void *data, u32 size); +int msg_receive(void *buf, u32 size); #endif diff --git a/libgui/msg.c b/libgui/msg.c index 8448e73..3f58267 100644 --- a/libgui/msg.c +++ b/libgui/msg.c @@ -5,23 +5,23 @@ #include #include -int msg_send(u32 pid, enum message_type type, void *data) +int msg_send(u32 pid, enum message_type type, void *data, u32 size) { - struct message msg = { 0 }; - assert((signed)pid != -1); + assert((signed)pid != -1 && size >= sizeof(struct message_header)); char path[32] = { 0 }; sprintf(path, "/proc/%d/msg", pid); - msg.magic = MSG_MAGIC; - msg.src = getpid(); - msg.type = type; - msg.data = data; - return write(path, &msg, 0, sizeof(msg)); + struct message_header *header = data; + header->magic = MSG_MAGIC; + header->src = getpid(); + header->type = type; + return write(path, data, 0, size); } -int msg_receive(struct message *msg) +int msg_receive(void *buf, u32 size) { - int ret = read("/proc/self/msg", msg, 0, sizeof(*msg)); - if (msg->magic == MSG_MAGIC && ret == sizeof(*msg)) + int ret = read("/proc/self/msg", buf, 0, size); + struct message_header *header = buf; + if (header->magic == MSG_MAGIC) return ret; else return -1; diff --git a/run b/run index 1a8202a..cd03ba3 100755 --- a/run +++ b/run @@ -26,7 +26,7 @@ no_ask="${2}" # TODO: Support -enable-kvm: GPF?! qemu_with_flags() { network="rtl8139" - qemu-system-i386 -cpu max -no-reboot -vga std -rtc base=localtime -m 256M -netdev user,id=net0,hostfwd=tcp:127.0.0.1:8000-10.0.2.15:8000 -device $network,netdev=net0 -object filter-dump,id=dump,netdev=net0,file=dump.pcap "$@" + qemu-system-i386 -d guest_errors -cpu max -no-reboot -vga std -rtc base=localtime -m 256M -netdev user,id=net0,hostfwd=tcp:127.0.0.1:8000-10.0.2.15:8000 -device $network,netdev=net0 -object filter-dump,id=dump,netdev=net0,file=dump.pcap "$@" } make_cross() { @@ -189,6 +189,10 @@ make_addr() { addr2line -e build/"$1".elf -f -p "$2" } +make_cloc() { + cloc . --exclude-dir=build,iso,disk,res,cross +} + make_append_commands() { s="" while read -r data; do @@ -239,6 +243,8 @@ elif [ "${mode}" = "disasm" ]; then make_disasm "$2" "$3" elif [ "${mode}" = "addr" ]; then make_addr "$2" "$3" +elif [ "${mode}" = "cloc" ]; then + make_cloc elif [ "${mode}" = "sync" ]; then make_sync elif [ "${mode}" = "disk" ]; then @@ -267,6 +273,7 @@ else printf "again\t\tOpens QEMU again using the previous build\n" printf "disasm\t\tDisassembles a given part of Melvix\n" printf "addr\t\tResolves an address to a line of code\n" + printf "cloc\t\tCount the total lines of code\n" printf "sync\t\tSyncs the 'tags' and 'compile_commands.json' file\n" printf "disk\t\tPrepares the userspace disk (e.g. fonts)\n" printf "*\t\tAnything else prints this help\n" -- cgit v1.2.3