- add the support of the system call execve
This commit is contained in:
parent
fc407a3eda
commit
d201c4d1bc
3 changed files with 49 additions and 3 deletions
|
@ -70,6 +70,9 @@ void NORETURN sys_exit(int);
|
|||
/* system call to create a new child process */
|
||||
int sys_fork(void);
|
||||
|
||||
/* system call to execute a program */
|
||||
int sys_execve(const char* fname, char** argv, char** env);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -76,7 +76,14 @@ int syscall_handler(uint32_t sys_nr, ...)
|
|||
ret = wait(status);
|
||||
break;
|
||||
}
|
||||
case __NR_fstat:
|
||||
case __NR_execve: {
|
||||
const char* name = va_arg(vl, const char*);
|
||||
char** argv = va_arg(vl, char**);
|
||||
char** env = va_arg(vl, char**);
|
||||
|
||||
ret = sys_execve(name, argv, env);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
kputs("invalid system call\n");
|
||||
ret = -ENOSYS;
|
||||
|
|
|
@ -191,6 +191,7 @@ int sys_fork(void)
|
|||
spinlock_init(&task_table[i].vma_lock);
|
||||
|
||||
// copy VMA list
|
||||
spinlock_lock(&per_core(current_task)->vma_lock);
|
||||
child = &task_table[i].vma_list;
|
||||
parent = per_core(current_task)->vma_list;
|
||||
tmp = NULL;
|
||||
|
@ -210,6 +211,7 @@ int sys_fork(void)
|
|||
tmp = *child;
|
||||
child = &((*child)->next);
|
||||
}
|
||||
spinlock_unlock(&per_core(current_task)->vma_lock);
|
||||
|
||||
mailbox_wait_msg_init(&task_table[i].inbox);
|
||||
memset(task_table[i].outbox, 0x00, sizeof(mailbox_wait_msg_t*)*MAX_TASKS);
|
||||
|
@ -239,10 +241,9 @@ int create_kernel_task(tid_t* id, entry_point_t ep, void* arg)
|
|||
return create_task(id, ep, arg);
|
||||
}
|
||||
|
||||
static int STDCALL user_entry(void* arg)
|
||||
static int load_task(vfs_node_t* node)
|
||||
{
|
||||
uint32_t i, addr, npages, flags, stack = 0;
|
||||
vfs_node_t* node = (vfs_node_t*) arg;
|
||||
elf_header_t header;
|
||||
elf_program_header_t prog_header;
|
||||
//elf_section_header_t sec_header;
|
||||
|
@ -370,6 +371,11 @@ invalid:
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int STDCALL user_entry(void* arg)
|
||||
{
|
||||
return load_task((vfs_node_t*) arg);
|
||||
}
|
||||
|
||||
int create_user_task(tid_t* id, size_t sz, const char* fname, int argc, char** argv)
|
||||
{
|
||||
vfs_node_t* node;
|
||||
|
@ -381,6 +387,36 @@ int create_user_task(tid_t* id, size_t sz, const char* fname, int argc, char** a
|
|||
return create_task(id, user_entry, node);
|
||||
}
|
||||
|
||||
int sys_execve(const char* fname, char** argv, char** env)
|
||||
{
|
||||
vfs_node_t* node;
|
||||
vma_t* tmp;
|
||||
|
||||
node = findnode_fs((char*) fname);
|
||||
if (!node || !(node->type == FS_FILE))
|
||||
return -EINVAL;
|
||||
|
||||
spinlock_lock(&(per_core(current_task)->vma_lock));
|
||||
|
||||
// remove old program
|
||||
while((tmp = per_core(current_task)->vma_list) != NULL) {
|
||||
kfree((void*) tmp->start, tmp->end - tmp->start + 1);
|
||||
per_core(current_task)->vma_list = tmp->next;
|
||||
kfree((void*) tmp, sizeof(vma_t));
|
||||
}
|
||||
|
||||
spinlock_unlock(&(per_core(current_task)->vma_lock));
|
||||
|
||||
/*
|
||||
* we use a trap gate to enter the kernel
|
||||
* => eflags are not changed
|
||||
* => interrupts are enabled
|
||||
* => we could directly load the new task
|
||||
*/
|
||||
|
||||
return load_task(node);
|
||||
}
|
||||
|
||||
tid_t wait(int32_t* result)
|
||||
{
|
||||
wait_msg_t tmp = { -1, -1};
|
||||
|
|
Loading…
Add table
Reference in a new issue