[USER] brk syscall

This commit is contained in:
2016-12-21 08:55:27 +01:00
parent 19df873615
commit a2cba95346
8 changed files with 73 additions and 7 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

19
kernel/syscall/sys_mem.c Normal file
View File

@@ -0,0 +1,19 @@
#include <syscall.h>
#include <scheduler.h>
#include <debug.h>
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;
}
}

View File

@@ -57,6 +57,7 @@ void syscall_init()
SYSCALL_REGISTER(debug, SYS_DEBUG);
SYSCALL_REGISTER(write, SYS_WRITE);
SYSCALL_REGISTER(brk, SYS_BRK);
}
}