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 | * |