diff --git a/init/init.c b/init/init.c index 7cc42fa..cd8539e 100644 --- a/init/init.c +++ b/init/init.c @@ -5,14 +5,18 @@ int main(int argc, char **argv) { (void) argc; (void) argv; - printf("Hello, world!\n"); - printf("Some numbers:%d\n", 12345); - printf("And hex:%#x\n", 0xabcdef); - printf("And a string:%s\n", "Hello!"); - printf("Arguments passed to init:\n"); - for(int i=0; i < argc; i++) - printf("%d: %s\n", i, argv[i]); + char *a = malloc(0x100); + printf("Pointer: %p\n", a); + char *b = malloc(0x100); + printf("Pointer: %p\n", b); + char *c = malloc(0x10); + printf("Pointer: %p\n", c); + c[0] = 5; + free(a); + free(b); + free(c); + for(;;); return 0; } diff --git a/kernel/include/process.h b/kernel/include/process.h index 56edc07..2d5ed42 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -62,5 +62,6 @@ void procmm_free_map(process_t *proc); void procmm_print_map(procmm_mmap_t *map); procmm_area_t *procmm_map(procmm_mmap_t *map, uintptr_t start, uintptr_t end, uint64_t flags); void procmm_unmap(procmm_area_t *a); +size_t procmm_resize(process_t *p, procmm_area_t *a, size_t len); int procmm_setup(process_t *proc, size_t brk_size); registers_t *procmm_page_fault(registers_t *r); diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 87dca0f..358d199 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -41,3 +41,4 @@ typedef long (*syscall_handler_t)(long num, long, long, long, long, long, long); #define SYSCALL_REGISTER(name, num) syscall_handlers[num] = syscall_##name SYSCALL_DECL(write); +SYSCALL_DECL(brk); diff --git a/kernel/proc/procmm.c b/kernel/proc/procmm.c index eb320af..c70f4f4 100644 --- a/kernel/proc/procmm.c +++ b/kernel/proc/procmm.c @@ -103,6 +103,35 @@ void procmm_unmap(procmm_area_t *a) kfree(a); } +size_t procmm_resize(process_t *p, procmm_area_t *a, size_t len) +{ + procmm_mmap_t *map = p->mmap; + size_t old_len = a->end - a->start; + size_t old_end = a->end; + if(old_len < len) + { + procmm_area_t *next = a->areas.next; + uintptr_t max = next->start; + max = (max < a->start)?KERNEL_OFFSET:max; + if((a->start + len) > max) + len = max - a->start; + + a->end = a->start + len; + + uintptr_t page = (old_end + PAGE_SIZE) & ~(PAGE_SIZE-1); + while(page < a->end) + { + vmm_set_page(map->P4, page, pmm_alloc(), PAGE_PRESENT | PAGE_WRITE | PAGE_USER); + page += PAGE_SIZE; + } + + } else { + debug_error("Decreasing memory area size is not implemented yet\n"); + for(;;); + } + return len; +} + int procmm_setup(process_t *proc, size_t brk_size) { procmm_mmap_t *map = proc->mmap; diff --git a/kernel/syscall/sys_mem.c b/kernel/syscall/sys_mem.c new file mode 100644 index 0000000..99fcf31 --- /dev/null +++ b/kernel/syscall/sys_mem.c @@ -0,0 +1,19 @@ +#include +#include +#include + + +SYSCALL_DEF(brk) +{ + SYSCALL_INIT(uint64_t, addr); + procmm_area_t *brk = get_current_process()->mmap->brk; + + if(addr) + { + size_t len = addr - brk->start; + procmm_resize(get_current_process(), brk, len); + return brk->end; + } else { + return brk->end; + } +} diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 40ea3f4..491dde2 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -57,6 +57,7 @@ void syscall_init() SYSCALL_REGISTER(debug, SYS_DEBUG); SYSCALL_REGISTER(write, SYS_WRITE); + SYSCALL_REGISTER(brk, SYS_BRK); } } diff --git a/libc/mem.c b/libc/mem.c new file mode 100644 index 0000000..2d1b08d --- /dev/null +++ b/libc/mem.c @@ -0,0 +1,10 @@ +#include "syscalls.h" + +long kernel_syscall(int num, ...); + +SYSCALL_DEF(brk) +{ + SYSCALL_INIT(unsigned long, brk); + + return kernel_syscall(SYS_BRK, brk); +} diff --git a/libc/syscall_num.h b/libc/syscall_num.h index 5b473fc..c3bf36f 100644 --- a/libc/syscall_num.h +++ b/libc/syscall_num.h @@ -1,4 +1,5 @@ #pragma once #define SYS_WRITE 0x001 +#define SYS_BRK 0x002 #define SYS_DEBUG 0x3FF