/kernel/trunk/generic/src/proc/task.c |
---|
26,6 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <main/uinit.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <mm/as.h> |
39,6 → 40,8 |
#include <ipc/ns.h> |
#include <memstr.h> |
#include <elf.h> |
SPINLOCK_INITIALIZE(tasks_lock); |
LIST_INITIALIZE(tasks_head); |
59,7 → 62,7 |
* |
* @param as Task's address space. |
* |
* @return New task's structure on success, NULL on failure. |
* @return New task's structure |
* |
*/ |
task_t *task_create(as_t *as) |
88,3 → 91,36 |
return ta; |
} |
/** Create new task with 1 thread and run it |
* |
* @return Task of the running program or NULL on error |
*/ |
task_t * task_run_program(void *program_addr) |
{ |
as_t *as; |
as_area_t *a; |
int rc; |
thread_t *t; |
task_t *task; |
as = as_create(0); |
rc = elf_load((elf_header_t *) config.init_addr, as); |
if (rc != EE_OK) { |
as_free(as); |
return NULL; |
} |
task = task_create(as); |
t = thread_create(uinit, (void *)((elf_header_t *) config.init_addr)->e_entry, |
task, THREAD_USER_STACK); |
/* |
* Create the data as_area. |
*/ |
a = as_area_create(as, AS_AREA_STACK, 1, USTACK_ADDRESS); |
thread_ready(t); |
return task; |
} |
/kernel/trunk/generic/src/main/kinit.c |
---|
27,7 → 27,6 |
*/ |
#include <main/kinit.h> |
#include <main/uinit.h> |
#include <config.h> |
#include <arch.h> |
#include <proc/scheduler.h> |
46,7 → 45,6 |
#include <console/console.h> |
#include <interrupt.h> |
#include <console/kconsole.h> |
#include <elf.h> |
#include <ipc/ns.h> |
#ifdef CONFIG_SMP |
71,10 → 69,6 |
void kinit(void *arg) |
{ |
thread_t *t; |
as_t *as; |
as_area_t *a; |
int rc; |
task_t *u; |
interrupts_disable(); |
149,30 → 143,9 |
if (config.init_addr % FRAME_SIZE) |
panic("config.init_addr is not frame aligned"); |
as = as_create(0); |
if (!as) |
panic("as_create\n"); |
rc = elf_load((elf_header_t *) config.init_addr, as); |
if (rc != EE_OK) { |
printf("elf_load failed: %s\n", elf_error(rc)); |
} else { |
u = task_create(as); |
if (!u) |
panic("task_create\n"); |
t = thread_create(uinit, (void *)((elf_header_t *) config.init_addr)->e_entry, u, THREAD_USER_STACK); |
if (!t) |
panic("thread_create\n"); |
/* |
* Create the data as_area. |
*/ |
a = as_area_create(as, AS_AREA_STACK, 1, USTACK_ADDRESS); |
if (!a) |
panic("as_area_create: stack\n"); |
thread_ready(t); |
if (!task_run_program((void *)config.init_addr)) { |
printf("Userspace not started.\n"); |
} |
} |
/kernel/trunk/generic/src/lib/elf.c |
---|
185,16 → 185,14 |
if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr) |
return EE_UNSUPPORTED; |
/* |
* Copying the segment out is certainly necessary for segments with p_filesz < p_memsz |
* because of the effect of .bss-like sections. For security reasons, it looks like a |
* good idea to copy the segment anyway. |
*/ |
segment_size = ALIGN_UP(max(entry->p_filesz, entry->p_memsz), PAGE_SIZE); |
segment = malloc(segment_size, 0); |
if (entry->p_filesz < entry->p_memsz) |
if ((entry->p_flags & PF_W)) { |
/* If writable, copy data (should be COW in the future) */ |
segment = malloc(segment_size, 0); |
memsetb((__address) (segment + entry->p_filesz), segment_size - entry->p_filesz, 0); |
memcpy(segment, (void *) (((__address) elf) + entry->p_offset), entry->p_filesz); |
memcpy(segment, (void *) (((__address) elf) + entry->p_offset), entry->p_filesz); |
} else /* Map identically original data */ |
segment = ((void *) elf) + entry->p_offset; |
a = as_area_create(as, type, SIZE2FRAMES(entry->p_memsz), entry->p_vaddr); |
if (!a) |
/kernel/trunk/generic/src/mm/as.c |
---|
103,6 → 103,16 |
return as; |
} |
/** Free Adress space */ |
void as_free(as_t *as) |
{ |
ASSERT(as->refcount == 0); |
/* TODO: free as_areas and other resources held by as */ |
/* TODO: free page table */ |
free(as); |
} |
/** Create address space area of common attributes. |
* |
* The created address space area is added to the target address space. |