Rev 3155 | Rev 3191 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3155 | Rev 3190 | ||
---|---|---|---|
Line 440... | Line 440... | ||
440 | task_ready(t); |
440 | task_ready(t); |
441 | 441 | ||
442 | return EOK; |
442 | return EOK; |
443 | } |
443 | } |
444 | 444 | ||
445 | unative_t sys_task_spawn(void *image, size_t size) |
- | |
446 | { |
- | |
447 | void *kimage = malloc(size, 0); |
- | |
448 | if (kimage == NULL) |
- | |
449 | return ENOMEM; |
- | |
450 | - | ||
451 | int rc = copy_from_uspace(kimage, image, size); |
- | |
452 | if (rc != EOK) |
- | |
453 | return rc; |
- | |
454 | - | ||
455 | /* |
- | |
456 | * Not very efficient and it would be better to call it on code only, |
- | |
457 | * but this whole function is a temporary hack anyway and one day it |
- | |
458 | * will go in favor of the userspace dynamic loader. |
- | |
459 | */ |
- | |
460 | smc_coherence_block(kimage, size); |
- | |
461 | - | ||
462 | uspace_arg_t *kernel_uarg; |
- | |
463 | kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
- | |
464 | if (kernel_uarg == NULL) { |
- | |
465 | free(kimage); |
- | |
466 | return ENOMEM; |
- | |
467 | } |
- | |
468 | - | ||
469 | kernel_uarg->uspace_entry = |
- | |
470 | (void *) ((elf_header_t *) kimage)->e_entry; |
- | |
471 | kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS; |
- | |
472 | kernel_uarg->uspace_thread_function = NULL; |
- | |
473 | kernel_uarg->uspace_thread_arg = NULL; |
- | |
474 | kernel_uarg->uspace_uarg = NULL; |
- | |
475 | - | ||
476 | as_t *as = as_create(0); |
- | |
477 | if (as == NULL) { |
- | |
478 | free(kernel_uarg); |
- | |
479 | free(kimage); |
- | |
480 | return ENOMEM; |
- | |
481 | } |
- | |
482 | - | ||
483 | unsigned int erc = elf_load((elf_header_t *) kimage, as, ELD_F_NONE); |
- | |
484 | if (erc != EE_OK) { |
- | |
485 | as_destroy(as); |
- | |
486 | free(kernel_uarg); |
- | |
487 | free(kimage); |
- | |
488 | return ENOENT; |
- | |
489 | } |
- | |
490 | - | ||
491 | as_area_t *area = as_area_create(as, |
- | |
492 | AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
- | |
493 | LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
- | |
494 | AS_AREA_ATTR_NONE, &anon_backend, NULL); |
- | |
495 | if (area == NULL) { |
- | |
496 | as_destroy(as); |
- | |
497 | free(kernel_uarg); |
- | |
498 | free(kimage); |
- | |
499 | return ENOMEM; |
- | |
500 | } |
- | |
501 | - | ||
502 | task_t *task = task_create(as, "app"); |
- | |
503 | if (task == NULL) { |
- | |
504 | as_destroy(as); |
- | |
505 | free(kernel_uarg); |
- | |
506 | free(kimage); |
- | |
507 | return ENOENT; |
- | |
508 | } |
- | |
509 | - | ||
510 | // FIXME: control the capabilities |
- | |
511 | cap_set(task, cap_get(TASK)); |
- | |
512 | - | ||
513 | thread_t *thread = thread_create(uinit, kernel_uarg, task, |
- | |
514 | THREAD_FLAG_USPACE, "user", false); |
- | |
515 | if (thread == NULL) { |
- | |
516 | task_destroy(task); |
- | |
517 | as_destroy(as); |
- | |
518 | free(kernel_uarg); |
- | |
519 | free(kimage); |
- | |
520 | return ENOENT; |
- | |
521 | } |
- | |
522 | - | ||
523 | thread_ready(thread); |
- | |
524 | - | ||
525 | return EOK; |
- | |
526 | } |
- | |
527 | - | ||
528 | /** Find task structure corresponding to task ID. |
445 | /** Find task structure corresponding to task ID. |
529 | * |
446 | * |
530 | * The tasks_lock must be already held by the caller of this function |
447 | * The tasks_lock must be already held by the caller of this function |
531 | * and interrupts must be disabled. |
448 | * and interrupts must be disabled. |
532 | * |
449 | * |