Create a program using an existing address space. * * @param as Address space containing a binary program image. * @param entry_addr Program entry-point address in program address space. * @param name Name to set for the program's task. * @param prg Buffer for storing program information. * * @return EOK on success or an error code. * */
| 69 | * |
| 70 | */ |
| 71 | errno_t program_create(as_t *as, uspace_addr_t entry_addr, char *name, program_t *prg) |
| 72 | { |
| 73 | uspace_arg_t *kernel_uarg = (uspace_arg_t *) |
| 74 | malloc(sizeof(uspace_arg_t)); |
| 75 | if (!kernel_uarg) |
| 76 | return ENOMEM; |
| 77 | |
| 78 | prg->loader_status = EOK; |
| 79 | prg->task = task_create(as, name); |
| 80 | if (!prg->task) { |
| 81 | free(kernel_uarg); |
| 82 | return ELIMIT; |
| 83 | } |
| 84 | |
| 85 | /* |
| 86 | * Create the stack address space area. |
| 87 | */ |
| 88 | uintptr_t virt = (uintptr_t) AS_AREA_ANY; |
| 89 | uintptr_t bound = USER_ADDRESS_SPACE_END - (STACK_SIZE_USER - 1); |
| 90 | |
| 91 | /* Adjust bound to create space for the desired guard page. */ |
| 92 | bound -= PAGE_SIZE; |
| 93 | |
| 94 | as_area_t *area = as_area_create(as, |
| 95 | AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD | |
| 96 | AS_AREA_LATE_RESERVE, STACK_SIZE_USER, AS_AREA_ATTR_NONE, |
| 97 | &anon_backend, NULL, &virt, bound); |
| 98 | if (!area) { |
| 99 | free(kernel_uarg); |
| 100 | task_destroy(prg->task); |
| 101 | prg->task = NULL; |
| 102 | return ENOMEM; |
| 103 | } |
| 104 | |
| 105 | kernel_uarg->uspace_entry = entry_addr; |
| 106 | kernel_uarg->uspace_stack = virt; |
| 107 | kernel_uarg->uspace_stack_size = STACK_SIZE_USER; |
| 108 | kernel_uarg->uspace_thread_function = USPACE_NULL; |
| 109 | kernel_uarg->uspace_thread_arg = USPACE_NULL; |
| 110 | kernel_uarg->uspace_uarg = USPACE_NULL; |
| 111 | |
| 112 | /* |
| 113 | * Create the main thread. |
| 114 | */ |
| 115 | prg->main_thread = thread_create(uinit, kernel_uarg, prg->task, |
| 116 | THREAD_FLAG_USPACE, "uinit"); |
| 117 | if (!prg->main_thread) { |
| 118 | free(kernel_uarg); |
| 119 | as_area_destroy(as, virt); |
| 120 | task_destroy(prg->task); |
| 121 | prg->task = NULL; |
| 122 | return ELIMIT; |
| 123 | } |
| 124 | |
| 125 | return EOK; |
| 126 | } |
| 127 | |
| 128 | /** Parse an executable image in the kernel memory. |
no test coverage detected