Loading sys/mem_area.c 0 → 100644 +104 −0 Original line number Diff line number Diff line #include "mem_area.h" #include <sys/process.h> #include <utils/pool_alloc.h> #include <fs/vfs_file.h> #include <utils/log.h> // pool allocation data static struct pool_alloc _mem_area_pool = POOL_INIT(struct mem_area); void mem_area_init() { printk(LOG_DEBUG, "mem_area: area/page=%d\n", _mem_area_pool.perpage); } struct mem_area *mem_area_alloc() { struct mem_area *ret; ret = pool_alloc(&_mem_area_pool); if(ret != NULL) { ret->flags = 0; ret->address = NULL; ret->max_size = 0; } return ret; } void mem_area_free(struct mem_area *area) { pool_free(&_mem_area_pool, area); } struct mem_area *mem_area_find(struct process *proc, void *address) { // for now, the list is not sorted, so check for each struct list_head *cur; struct mem_area *ret = NULL; list_for_each(cur, &(proc->mem_areas)) { // check if address is inside this area struct mem_area *area = container_of(cur, struct mem_area, list); if(address >= area->address && address < (area->address + area->max_size)) { ret = area; break; } } return ret; } /** * internal function, check if an area is defined in the given address range * Return 0 if this range is empty, 1 if an area exists. */ static int mem_area_check_range(struct process *proc, void *addr_begin, size_t size) { struct list_head *cur; list_for_each(cur, &(proc->mem_areas)) { // check if address range intersects with this area struct mem_area *area = container_of(cur, struct mem_area, list); if(area->address < (addr_begin + size) && (area->address + area->max_size) > addr_begin) return 1; } return 0; } int mem_area_insert(struct process *proc, struct mem_area *area) { // check for any overlayed area if(!mem_area_check_range(proc, area->address, area->max_size)) { // not sorted, insert in front list_push_front(& proc->mem_areas, & area->list); return 0; } printk(LOG_ERR, "mem_area: unable to insert area (overlay)\n"); return -1; } int mem_area_copy_raw(struct mem_area *area, size_t offset, void *dest, size_t size) { int ret = -1; if(area->flags & MEM_AREA_TYPE_ANON) { // anonymous area, the current implementation do nothing... ret = 0; } else if(area->flags & MEM_AREA_TYPE_FILE) { // file mapped to memory, for now use a generic way to handle them // TODO improve this with map_area_ops struct to allow "override" size_t nbread; vfs_lseek(area->file.filep, SEEK_SET, offset); nbread = vfs_read(area->file.filep, dest, size); ret = nbread == size ? 0 : -1; } return ret; } sys/mem_area.h +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ struct mem_area { union { struct { // file structure of the file mapped to this area struct file *f; struct file *filep; // origin's position in the file size_t origin; Loading Loading @@ -61,6 +61,7 @@ void mem_area_init(); * Return a newly allocated memory area, not initialized. */ struct mem_area *mem_area_alloc(); void mem_area_free(struct mem_area *area); /** Loading sys/process.c +2 −2 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ #include <utils/bitfield.h> #include <interface/fixos/fcntl.h> #include <interface/fixos/errno.h> #include <sys/mem_areas.h> #include <sys/mem_area.h> #include <loader/elfloader/loader.h> #include <fs/vfs_file.h> Loading Loading @@ -111,7 +111,7 @@ struct process *process_alloc() { arch_adrsp_init(& proc->addr_space); proc->dir_list = NULL; INIT_LIST_HEAD(proc->mem_areas); INIT_LIST_HEAD(& proc->mem_areas); sigemptyset(& proc->sig_blocked); Loading sys/subdir.mk +2 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,8 @@ C_SRC_L:= \ kdebug.c \ sysctl.c \ waitqueue.c \ tty.c tty.c \ mem_area.c CURDIR:=sys Loading Loading
sys/mem_area.c 0 → 100644 +104 −0 Original line number Diff line number Diff line #include "mem_area.h" #include <sys/process.h> #include <utils/pool_alloc.h> #include <fs/vfs_file.h> #include <utils/log.h> // pool allocation data static struct pool_alloc _mem_area_pool = POOL_INIT(struct mem_area); void mem_area_init() { printk(LOG_DEBUG, "mem_area: area/page=%d\n", _mem_area_pool.perpage); } struct mem_area *mem_area_alloc() { struct mem_area *ret; ret = pool_alloc(&_mem_area_pool); if(ret != NULL) { ret->flags = 0; ret->address = NULL; ret->max_size = 0; } return ret; } void mem_area_free(struct mem_area *area) { pool_free(&_mem_area_pool, area); } struct mem_area *mem_area_find(struct process *proc, void *address) { // for now, the list is not sorted, so check for each struct list_head *cur; struct mem_area *ret = NULL; list_for_each(cur, &(proc->mem_areas)) { // check if address is inside this area struct mem_area *area = container_of(cur, struct mem_area, list); if(address >= area->address && address < (area->address + area->max_size)) { ret = area; break; } } return ret; } /** * internal function, check if an area is defined in the given address range * Return 0 if this range is empty, 1 if an area exists. */ static int mem_area_check_range(struct process *proc, void *addr_begin, size_t size) { struct list_head *cur; list_for_each(cur, &(proc->mem_areas)) { // check if address range intersects with this area struct mem_area *area = container_of(cur, struct mem_area, list); if(area->address < (addr_begin + size) && (area->address + area->max_size) > addr_begin) return 1; } return 0; } int mem_area_insert(struct process *proc, struct mem_area *area) { // check for any overlayed area if(!mem_area_check_range(proc, area->address, area->max_size)) { // not sorted, insert in front list_push_front(& proc->mem_areas, & area->list); return 0; } printk(LOG_ERR, "mem_area: unable to insert area (overlay)\n"); return -1; } int mem_area_copy_raw(struct mem_area *area, size_t offset, void *dest, size_t size) { int ret = -1; if(area->flags & MEM_AREA_TYPE_ANON) { // anonymous area, the current implementation do nothing... ret = 0; } else if(area->flags & MEM_AREA_TYPE_FILE) { // file mapped to memory, for now use a generic way to handle them // TODO improve this with map_area_ops struct to allow "override" size_t nbread; vfs_lseek(area->file.filep, SEEK_SET, offset); nbread = vfs_read(area->file.filep, dest, size); ret = nbread == size ? 0 : -1; } return ret; }
sys/mem_area.h +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ struct mem_area { union { struct { // file structure of the file mapped to this area struct file *f; struct file *filep; // origin's position in the file size_t origin; Loading Loading @@ -61,6 +61,7 @@ void mem_area_init(); * Return a newly allocated memory area, not initialized. */ struct mem_area *mem_area_alloc(); void mem_area_free(struct mem_area *area); /** Loading
sys/process.c +2 −2 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ #include <utils/bitfield.h> #include <interface/fixos/fcntl.h> #include <interface/fixos/errno.h> #include <sys/mem_areas.h> #include <sys/mem_area.h> #include <loader/elfloader/loader.h> #include <fs/vfs_file.h> Loading Loading @@ -111,7 +111,7 @@ struct process *process_alloc() { arch_adrsp_init(& proc->addr_space); proc->dir_list = NULL; INIT_LIST_HEAD(proc->mem_areas); INIT_LIST_HEAD(& proc->mem_areas); sigemptyset(& proc->sig_blocked); Loading
sys/subdir.mk +2 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,8 @@ C_SRC_L:= \ kdebug.c \ sysctl.c \ waitqueue.c \ tty.c tty.c \ mem_area.c CURDIR:=sys Loading