implemented userspace task loading and userpsace heap management with the new vma_list
This commit is contained in:
parent
a00177ec09
commit
11977e40bc
4 changed files with 90 additions and 88 deletions
|
@ -53,6 +53,7 @@ page_map_t* get_boot_page_map(void)
|
||||||
return &boot_pml4;
|
return &boot_pml4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
size_t virt_to_phys(size_t viraddr) {
|
size_t virt_to_phys(size_t viraddr) {
|
||||||
task_t* task = per_core(current_task);
|
task_t* task = per_core(current_task);
|
||||||
|
|
||||||
|
@ -600,28 +601,25 @@ static void pagefault_handler(struct state *s)
|
||||||
task_t* task = per_core(current_task);
|
task_t* task = per_core(current_task);
|
||||||
size_t viraddr = read_cr2();
|
size_t viraddr = read_cr2();
|
||||||
|
|
||||||
#if 0
|
// on demand userspace heap mapping
|
||||||
if ((viraddr >= task->start_heap) && (viraddr <= task->end_heap) && (viraddr > KERNEL_SPACE)) {
|
if ((task->heap) && (viraddr >= task->heap->start) && (viraddr < task->heap->end)) {
|
||||||
viraddr = viraddr & PAGE_MASK;
|
viraddr &= PAGE_MASK;
|
||||||
|
|
||||||
phyaddr = get_page();
|
|
||||||
if (BUILTIN_EXPECT(!phyaddr, 0))
|
|
||||||
goto oom;
|
|
||||||
|
|
||||||
if (map_region(viraddr, phyaddr, 1, MAP_USER_SPACE) == viraddr) {
|
|
||||||
memset((void*) viraddr, 0x00, PAGE_SIZE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
kprintf("Could not map 0x%x at 0x%x\n", phyaddr, viraddr);
|
|
||||||
put_page(phyaddr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t phyaddr = get_page();
|
size_t phyaddr = get_page();
|
||||||
|
if (BUILTIN_EXPECT(!phyaddr, 0)) {
|
||||||
|
kprintf("out of memory: task = %u\n", task->id);
|
||||||
|
goto default_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
viraddr = map_region(viraddr, phyaddr, 1, MAP_USER_SPACE);
|
||||||
|
if (BUILTIN_EXPECT(!viraddr, 0)) {
|
||||||
|
kprintf("map_region: could not map %#lx to %#lx, task = %u\n", viraddr, phyaddr, task->id);
|
||||||
|
put_page(phyaddr);
|
||||||
|
|
||||||
|
goto default_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset((void*) viraddr, 0x00, PAGE_SIZE); // fill with zeros
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,8 @@ typedef struct task {
|
||||||
size_t start_heap;
|
size_t start_heap;
|
||||||
/// end address of the heap
|
/// end address of the heap
|
||||||
size_t end_heap;
|
size_t end_heap;
|
||||||
|
/// the userspace heap
|
||||||
|
vma_t* heap;
|
||||||
/// LwIP error code
|
/// LwIP error code
|
||||||
int lwip_err;
|
int lwip_err;
|
||||||
/// mail inbox
|
/// mail inbox
|
||||||
|
|
|
@ -236,7 +236,7 @@ static int sys_accept(int s, struct sockaddr* addr, socklen_t* addrlen)
|
||||||
curr_task->fildes_table[fd]->offset = sock2;
|
curr_task->fildes_table[fd]->offset = sock2;
|
||||||
curr_task->fildes_table[fd]->count = 1;
|
curr_task->fildes_table[fd]->count = 1;
|
||||||
curr_task->fildes_table[fd]->node = findnode_fs("/dev/socket");
|
curr_task->fildes_table[fd]->node = findnode_fs("/dev/socket");
|
||||||
|
|
||||||
/* file doesn't exist! */
|
/* file doesn't exist! */
|
||||||
if (curr_task->fildes_table[fd]->node == NULL) {
|
if (curr_task->fildes_table[fd]->node == NULL) {
|
||||||
/* tidy up the fildescriptor */
|
/* tidy up the fildescriptor */
|
||||||
|
@ -381,7 +381,7 @@ static int sys_dup2(int fd, int fd2)
|
||||||
/* If fd and fd2 are equal, then dup2() just returns fd2 */
|
/* If fd and fd2 are equal, then dup2() just returns fd2 */
|
||||||
if (fd == fd2)
|
if (fd == fd2)
|
||||||
return fd2;
|
return fd2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if descriptor fd2 is already in use, it is first deallocated
|
* if descriptor fd2 is already in use, it is first deallocated
|
||||||
* as if a close(2) call had been done first
|
* as if a close(2) call had been done first
|
||||||
|
@ -398,29 +398,25 @@ static int sys_dup2(int fd, int fd2)
|
||||||
static int sys_sbrk(int incr)
|
static int sys_sbrk(int incr)
|
||||||
{
|
{
|
||||||
task_t* task = per_core(current_task);
|
task_t* task = per_core(current_task);
|
||||||
vma_t* tmp = NULL;
|
vma_t* heap = task->heap;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
spinlock_lock(&task->vma_lock);
|
spinlock_lock(&task->vma_lock);
|
||||||
|
|
||||||
// search vma containing the heap
|
if (BUILTIN_EXPECT(!heap,0 )) {
|
||||||
tmp = task->vma_list;
|
kprintf("sys_sbrk: missing heap!\n");
|
||||||
while(tmp && !((task->end_heap >= tmp->start) && (task->end_heap <= tmp->end)))
|
abort();
|
||||||
tmp = tmp->next;
|
}
|
||||||
|
|
||||||
ret = (int) task->end_heap;
|
ret = heap->end;
|
||||||
task->end_heap += incr;
|
heap->end += incr;
|
||||||
if (task->end_heap < task->start_heap)
|
if (heap->end < heap->start)
|
||||||
task->end_heap = task->start_heap;
|
heap->end = heap->start;
|
||||||
|
|
||||||
// resize virtual memory area
|
|
||||||
if (tmp && (tmp->end <= task->end_heap))
|
|
||||||
tmp->end = task->end_heap;
|
|
||||||
|
|
||||||
// allocation and mapping of new pages for the heap
|
// allocation and mapping of new pages for the heap
|
||||||
// is catched by the pagefault handler
|
// is catched by the pagefault handler
|
||||||
|
|
||||||
//kprintf("sys_sbrk: tid=%d, start_heap=%8x, end_heap=%8x, incr=%4x\n", task->id, task->start_heap, task->end_heap, incr);
|
kprintf("sys_sbrk: task = %d, heap->start = %#lx, heap->end = %#lx, incr = %#4x\n", task->id, heap->start, heap->end, incr); // TOD0: remove
|
||||||
|
|
||||||
spinlock_unlock(&task->vma_lock);
|
spinlock_unlock(&task->vma_lock);
|
||||||
|
|
||||||
|
@ -506,7 +502,7 @@ int syscall_handler(size_t sys_nr, ...)
|
||||||
break;
|
break;
|
||||||
case __NR_wait: {
|
case __NR_wait: {
|
||||||
int32_t* status = va_arg(vl, int32_t*);
|
int32_t* status = va_arg(vl, int32_t*);
|
||||||
|
|
||||||
ret = wait(status);
|
ret = wait(status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -555,7 +551,7 @@ int syscall_handler(size_t sys_nr, ...)
|
||||||
ret = -ENOTSOCK;
|
ret = -ENOTSOCK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//kprintf("lwip_connect: %p with lenght %i and Socket %i", name, namelen, per_core(current_task)->fildes_table[fd].offset);
|
//kprintf("lwip_connect: %p with lenght %i and Socket %i", name, namelen, per_core(current_task)->fildes_table[fd].offset); // TODO: remove
|
||||||
|
|
||||||
|
|
||||||
ret = lwip_connect(per_core(current_task)->fildes_table[fd]->offset, name, namelen);
|
ret = lwip_connect(per_core(current_task)->fildes_table[fd]->offset, name, namelen);
|
||||||
|
|
112
kernel/tasks.c
112
kernel/tasks.c
|
@ -586,16 +586,15 @@ static int load_task(load_args_t* largs)
|
||||||
{
|
{
|
||||||
uint32_t i, offset, idx, fd_i;
|
uint32_t i, offset, idx, fd_i;
|
||||||
uint32_t addr, npages, flags;
|
uint32_t addr, npages, flags;
|
||||||
size_t stack = 0;
|
size_t stack = 0, heap = 0;
|
||||||
elf_header_t header;
|
elf_header_t header;
|
||||||
elf_program_header_t prog_header;
|
elf_program_header_t prog_header;
|
||||||
//elf_section_header_t sec_header;
|
//elf_section_header_t sec_header;
|
||||||
///!!! kfree is missing!
|
fildes_t *file = kmalloc(sizeof(fildes_t)); // TODO: kfree is missing!
|
||||||
fildes_t *file = kmalloc(sizeof(fildes_t));
|
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
file->flags = 0;
|
file->flags = 0;
|
||||||
|
|
||||||
//TODO: init the hole fildes_t struct!
|
// TODO: init the hole fildes_t struct!
|
||||||
task_t* curr_task = per_core(current_task);
|
task_t* curr_task = per_core(current_task);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -606,22 +605,22 @@ static int load_task(load_args_t* largs)
|
||||||
if (!file->node)
|
if (!file->node)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* init fildes_table */
|
// init fildes_table
|
||||||
spinlock_irqsave_lock(&table_lock);
|
spinlock_irqsave_lock(&table_lock);
|
||||||
if (!task_table[curr_task->id].fildes_table) {
|
if (!curr_task->fildes_table) {
|
||||||
task_table[curr_task->id].fildes_table = kmalloc(sizeof(filp_t)*NR_OPEN);
|
curr_task->fildes_table = kmalloc(sizeof(filp_t)*NR_OPEN);
|
||||||
if (BUILTIN_EXPECT(!task_table[curr_task->id].fildes_table, 0)) {
|
if (BUILTIN_EXPECT(!curr_task->fildes_table, 0)) {
|
||||||
spinlock_irqsave_unlock(&table_lock);
|
spinlock_irqsave_unlock(&table_lock);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
memset(task_table[curr_task->id].fildes_table, 0x00, sizeof(filp_t)*NR_OPEN);
|
memset(curr_task->fildes_table, 0x00, sizeof(filp_t)*NR_OPEN);
|
||||||
for (fd_i = 0; fd_i < 3; fd_i++) {
|
for (fd_i = 0; fd_i < 3; fd_i++) {
|
||||||
task_table[curr_task->id].fildes_table[fd_i] = kmalloc(sizeof(fildes_t));
|
curr_task->fildes_table[fd_i] = kmalloc(sizeof(fildes_t));
|
||||||
task_table[curr_task->id].fildes_table[fd_i]->count = 1;
|
curr_task->fildes_table[fd_i]->count = 1;
|
||||||
}
|
}
|
||||||
task_table[curr_task->id].fildes_table[0]->node = findnode_fs("/dev/stdin");
|
curr_task->fildes_table[0]->node = findnode_fs("/dev/stdin");
|
||||||
task_table[curr_task->id].fildes_table[1]->node = findnode_fs("/dev/stdout");
|
curr_task->fildes_table[1]->node = findnode_fs("/dev/stdout");
|
||||||
task_table[curr_task->id].fildes_table[2]->node = findnode_fs("/dev/stderr");
|
curr_task->fildes_table[2]->node = findnode_fs("/dev/stderr");
|
||||||
}
|
}
|
||||||
spinlock_irqsave_unlock(&table_lock);
|
spinlock_irqsave_unlock(&table_lock);
|
||||||
|
|
||||||
|
@ -642,43 +641,43 @@ static int load_task(load_args_t* largs)
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_32, 0))
|
if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_32, 0))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
#else
|
#elif defined(CONFIG_X86_64)
|
||||||
if (BUILTIN_EXPECT(header.machine != ELF_EM_X86_64, 0))
|
if (BUILTIN_EXPECT(header.machine != ELF_EM_X86_64, 0))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_64, 0))
|
if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_64, 0))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
|
#else
|
||||||
|
#error "unknown arch"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(header.ident.data != ELF_DATA_2LSB, 0))
|
if (BUILTIN_EXPECT(header.ident.data != ELF_DATA_2LSB, 0))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
|
|
||||||
if (header.entry <= KERNEL_SPACE)
|
if (header.entry < KERNEL_SPACE)
|
||||||
goto invalid;
|
goto invalid;
|
||||||
|
|
||||||
// interpret program header table
|
// interpret program header table
|
||||||
for (i=0; i<header.ph_entry_count; i++) {
|
for (i=0; i<header.ph_entry_count; i++) {
|
||||||
file->offset = header.ph_offset+i*header.ph_entry_size;
|
file->offset = header.ph_offset+i*header.ph_entry_size;
|
||||||
if (read_fs(file, (uint8_t*)&prog_header, sizeof(elf_program_header_t)) == 0) {
|
if (read_fs(file, (uint8_t*) &prog_header, sizeof(elf_program_header_t)) == 0) {
|
||||||
kprintf("Could not read programm header!\n");
|
kprintf("Could not read programm header!\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(prog_header.type)
|
switch(prog_header.type) {
|
||||||
{
|
|
||||||
case ELF_PT_LOAD: // load program segment
|
case ELF_PT_LOAD: // load program segment
|
||||||
if (!prog_header.virt_addr)
|
if (!prog_header.virt_addr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
npages = (prog_header.mem_size >> PAGE_SHIFT);
|
npages = PAGE_FLOOR(prog_header.mem_size) >> PAGE_BITS;
|
||||||
if (prog_header.mem_size & (PAGE_SIZE-1))
|
|
||||||
npages++;
|
|
||||||
|
|
||||||
addr = get_pages(npages);
|
addr = get_pages(npages);
|
||||||
|
|
||||||
flags = MAP_USER_SPACE;
|
flags = MAP_USER_SPACE;
|
||||||
if (prog_header.flags & PF_X)
|
if (prog_header.flags & PF_X)
|
||||||
flags |= MAP_CODE;
|
flags |= MAP_CODE;
|
||||||
|
if (!(prog_header.flags & PF_W))
|
||||||
|
flags |= MAP_READ_ONLY;
|
||||||
|
|
||||||
// map page frames in the address space of the current task
|
// map page frames in the address space of the current task
|
||||||
if (!map_region(prog_header.virt_addr, addr, npages, flags)) {
|
if (!map_region(prog_header.virt_addr, addr, npages, flags)) {
|
||||||
|
@ -687,35 +686,30 @@ static int load_task(load_args_t* largs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear pages
|
// clear pages
|
||||||
memset((void*) prog_header.virt_addr, 0x00, npages*PAGE_SIZE);
|
memset((void*) prog_header.virt_addr, 0x00, npages * PAGE_SIZE);
|
||||||
|
|
||||||
// set starting point of the heap
|
// update heap location
|
||||||
if (curr_task->start_heap < prog_header.virt_addr+prog_header.mem_size)
|
if (heap < prog_header.virt_addr + prog_header.mem_size)
|
||||||
curr_task->start_heap = curr_task->end_heap = prog_header.virt_addr+prog_header.mem_size;
|
heap = prog_header.virt_addr+prog_header.mem_size;
|
||||||
|
|
||||||
// load program
|
// load program
|
||||||
file->offset = prog_header.offset;
|
file->offset = prog_header.offset;
|
||||||
read_fs(file, (uint8_t*)prog_header.virt_addr, prog_header.file_size);
|
read_fs(file, (uint8_t*) prog_header.virt_addr, prog_header.file_size);
|
||||||
|
|
||||||
flags = VMA_CACHEABLE;
|
flags = VMA_CACHEABLE | VMA_USER;
|
||||||
if (prog_header.flags & PF_R)
|
if (prog_header.flags & PF_R)
|
||||||
flags |= VMA_READ;
|
flags |= VMA_READ;
|
||||||
if (prog_header.flags & PF_W)
|
if (prog_header.flags & PF_W)
|
||||||
flags |= VMA_WRITE;
|
flags |= VMA_WRITE;
|
||||||
if (prog_header.flags & PF_X)
|
if (prog_header.flags & PF_X)
|
||||||
flags |= VMA_EXECUTE;
|
flags |= VMA_EXECUTE;
|
||||||
vma_add(prog_header.virt_addr, prog_header.virt_addr+npages*PAGE_SIZE-1, flags);
|
|
||||||
|
|
||||||
if (!(prog_header.flags & PF_W))
|
vma_add(prog_header.virt_addr, prog_header.virt_addr+npages*PAGE_SIZE, flags);
|
||||||
change_page_permissions(prog_header.virt_addr, prog_header.virt_addr+npages*PAGE_SIZE-1, flags);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELF_PT_GNU_STACK: // Indicates stack executability
|
case ELF_PT_GNU_STACK: // Indicates stack executability
|
||||||
// create user-level stack
|
// create user-level stack
|
||||||
npages = DEFAULT_STACK_SIZE >> PAGE_SHIFT;
|
npages = PAGE_FLOOR(DEFAULT_STACK_SIZE) >> PAGE_BITS;
|
||||||
if (DEFAULT_STACK_SIZE & (PAGE_SIZE-1))
|
|
||||||
npages++;
|
|
||||||
|
|
||||||
addr = get_pages(npages);
|
addr = get_pages(npages);
|
||||||
stack = header.entry*2; // virtual address of the stack
|
stack = header.entry*2; // virtual address of the stack
|
||||||
|
|
||||||
|
@ -733,7 +727,8 @@ static int load_task(load_args_t* largs)
|
||||||
flags |= VMA_WRITE;
|
flags |= VMA_WRITE;
|
||||||
if (prog_header.flags & PF_X)
|
if (prog_header.flags & PF_X)
|
||||||
flags |= VMA_EXECUTE;
|
flags |= VMA_EXECUTE;
|
||||||
vma_add(stack, stack+npages*PAGE_SIZE-1, flags);
|
|
||||||
|
vma_add(stack, stack+npages*PAGE_SIZE, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -751,8 +746,23 @@ static int load_task(load_args_t* largs)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// setup heap
|
||||||
|
if (!curr_task->heap)
|
||||||
|
curr_task->heap = (vma_t*) kmalloc(sizeof(vma_t));
|
||||||
|
|
||||||
|
if (BUILTIN_EXPECT(!curr_task->heap || !heap, 0)) {
|
||||||
|
kprintf("load_task: heap is missing!\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr_task->heap->flags = VMA_HEAP|VMA_USER;
|
||||||
|
curr_task->heap->start = heap;
|
||||||
|
curr_task->heap->end = heap;
|
||||||
|
|
||||||
|
// TODO: insert into list
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(!stack, 0)) {
|
if (BUILTIN_EXPECT(!stack, 0)) {
|
||||||
kprintf("Stack is missing!\n");
|
kprintf("load_task: stack is missing!\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,9 +775,9 @@ static int load_task(load_args_t* largs)
|
||||||
|
|
||||||
// push argv on the stack
|
// push argv on the stack
|
||||||
offset -= largs->argc * sizeof(char*);
|
offset -= largs->argc * sizeof(char*);
|
||||||
for(i=0; i<largs->argc; i++) {
|
for (i=0; i<largs->argc; i++) {
|
||||||
((char**) (stack+offset))[i] = (char*) (stack+idx);
|
((char**) (stack+offset))[i] = (char*) (stack+idx);
|
||||||
|
|
||||||
while(((char*) stack)[idx] != '\0')
|
while(((char*) stack)[idx] != '\0')
|
||||||
idx++;
|
idx++;
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -775,7 +785,7 @@ static int load_task(load_args_t* largs)
|
||||||
|
|
||||||
// push env on the stack
|
// push env on the stack
|
||||||
offset -= (largs->envc+1) * sizeof(char*);
|
offset -= (largs->envc+1) * sizeof(char*);
|
||||||
for(i=0; i<largs->envc; i++) {
|
for (i=0; i<largs->envc; i++) {
|
||||||
((char**) (stack+offset))[i] = (char*) (stack+idx);
|
((char**) (stack+offset))[i] = (char*) (stack+idx);
|
||||||
|
|
||||||
while(((char*) stack)[idx] != '\0')
|
while(((char*) stack)[idx] != '\0')
|
||||||
|
@ -796,7 +806,7 @@ static int load_task(load_args_t* largs)
|
||||||
*((char***) (stack+offset)) = (char**) (stack + offset + 2*sizeof(char**) + (largs->envc+1) * sizeof(char*));
|
*((char***) (stack+offset)) = (char**) (stack + offset + 2*sizeof(char**) + (largs->envc+1) * sizeof(char*));
|
||||||
|
|
||||||
// push argc on the stack
|
// push argc on the stack
|
||||||
offset -= sizeof(int);
|
offset -= sizeof(size_t);
|
||||||
*((int*) (stack+offset)) = largs->argc;
|
*((int*) (stack+offset)) = largs->argc;
|
||||||
|
|
||||||
kfree(largs);
|
kfree(largs);
|
||||||
|
@ -810,12 +820,12 @@ static int load_task(load_args_t* largs)
|
||||||
|
|
||||||
invalid:
|
invalid:
|
||||||
kprintf("Invalid executable!\n");
|
kprintf("Invalid executable!\n");
|
||||||
kprintf("magic number 0x%x\n", (uint32_t) header.ident.magic);
|
kprintf("Magic number: 0x%x\n", (uint32_t) header.ident.magic);
|
||||||
kprintf("header type 0x%x\n", (uint32_t) header.type);
|
kprintf("Header type: 0x%x\n", (uint32_t) header.type);
|
||||||
kprintf("machine type 0x%x\n", (uint32_t) header.machine);
|
kprintf("Machine type: 0x%x\n", (uint32_t) header.machine);
|
||||||
kprintf("elf ident class 0x%x\n", (uint32_t) header.ident._class);
|
kprintf("ELF ident class: 0x%x\n", (uint32_t) header.ident._class);
|
||||||
kprintf("elf identdata !0x%x\n", header.ident.data);
|
kprintf("ELF ident data: 0x%x\n", header.ident.data);
|
||||||
kprintf("program entry point 0x%x\n", (size_t) header.entry);
|
kprintf("Program entry point: 0x%x\n", (size_t) header.entry);
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -849,7 +859,6 @@ static int user_entry(void* arg)
|
||||||
*/
|
*/
|
||||||
int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint32_t core_id)
|
int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint32_t core_id)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
vfs_node_t* node;
|
vfs_node_t* node;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
size_t i, buffer_size = 0;
|
size_t i, buffer_size = 0;
|
||||||
|
@ -885,11 +894,8 @@ int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint32_t
|
||||||
while ((*dest++ = *src++) != 0);
|
while ((*dest++ = *src++) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create new task */
|
// create new task
|
||||||
return create_task(id, user_entry, load_args, NORMAL_PRIO, core_id);
|
return create_task(id, user_entry, load_args, NORMAL_PRIO, core_id);
|
||||||
#else
|
|
||||||
return -EINVAL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Used by the execve-Systemcall */
|
/** @brief Used by the execve-Systemcall */
|
||||||
|
|
Loading…
Add table
Reference in a new issue