Changes in kernel/generic/src/proc/program.c [bfe43d5:1ea99cc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/proc/program.c
rbfe43d5 r1ea99cc 34 34 /** 35 35 * @file 36 * @brief 36 * @brief Running userspace programs. 37 37 */ 38 38 … … 50 50 #include <lib/elf.h> 51 51 #include <errno.h> 52 #include <print.h>53 52 #include <syscall/copy.h> 54 53 #include <proc/program.h> … … 66 65 /** Create a program using an existing address space. 67 66 * 68 * @param as Address space containing a binary program image. 69 * @param entry_addr Program entry-point address in program address space. 70 * @param name Name to set for the program's task. 71 * @param prg Buffer for storing program information. 72 * 73 * @return EOK on success or negative error code. 74 * 75 */ 76 int program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *prg) 77 { 67 * @param as Address space containing a binary program image. 68 * @param entry_addr Program entry-point address in program address space. 69 * @param name Name to set for the program's task. 70 * @param p Buffer for storing program information. 71 */ 72 void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p) 73 { 74 as_area_t *a; 78 75 uspace_arg_t *kernel_uarg; 79 76 80 77 kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); 81 78 kernel_uarg->uspace_entry = (void *) entry_addr; … … 85 82 kernel_uarg->uspace_uarg = NULL; 86 83 87 prg->task = task_create(as, name); 88 if (!prg->task) 89 return ELIMIT; 90 84 p->task = task_create(as, name); 85 ASSERT(p->task); 86 91 87 /* 92 * Create the data a ddress spacearea.88 * Create the data as_area. 93 89 */ 94 as_area_t *area = as_area_create(as, 95 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, 90 a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, 96 91 LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, 97 92 AS_AREA_ATTR_NONE, &anon_backend, NULL); 98 if (!area) 99 return ENOMEM; 100 93 101 94 /* 102 95 * Create the main thread. 103 96 */ 104 p rg->main_thread = thread_create(uinit, kernel_uarg, prg->task,97 p->main_thread = thread_create(uinit, kernel_uarg, p->task, 105 98 THREAD_FLAG_USPACE, "uinit", false); 106 if (!prg->main_thread) 107 return ELIMIT; 108 109 return EOK; 99 ASSERT(p->main_thread); 110 100 } 111 101 … … 116 106 * executable image. The task is returned in *task. 117 107 * 118 * @param image_addr 119 * @param name 120 * @param p rgBuffer for storing program info. If image_addr121 * 122 * 108 * @param image_addr Address of an executable program image. 109 * @param name Name to set for the program's task. 110 * @param p Buffer for storing program info. If image_addr 111 * points to a loader image, p->task will be set to 112 * NULL and EOK will be returned. 123 113 * 124 114 * @return EOK on success or negative error code. 125 * 126 */ 127 int program_create_from_image(void *image_addr, char *name, program_t *prg) 128 { 129 as_t *as = as_create(0); 130 if (!as) 131 return ENOMEM; 132 133 unsigned int rc = elf_load((elf_header_t *) image_addr, as, 0); 115 */ 116 int program_create_from_image(void *image_addr, char *name, program_t *p) 117 { 118 as_t *as; 119 unsigned int rc; 120 121 as = as_create(0); 122 ASSERT(as); 123 124 rc = elf_load((elf_header_t *) image_addr, as, 0); 134 125 if (rc != EE_OK) { 135 126 as_destroy(as); 136 prg->task = NULL; 137 prg->main_thread = NULL; 138 127 p->task = NULL; 128 p->main_thread = NULL; 139 129 if (rc != EE_LOADER) 140 130 return ENOTSUP; 141 131 142 132 /* Register image as the program loader */ 143 if (program_loader != NULL) 144 return ELIMIT; 145 133 ASSERT(program_loader == NULL); 146 134 program_loader = image_addr; 147 LOG("Registered program loader at %p",148 (void *) image_addr);149 150 135 return EOK; 151 136 } 152 153 return program_create(as, ((elf_header_t *) image_addr)->e_entry, 154 name, prg); 137 138 program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p); 139 140 return EOK; 155 141 } 156 142 157 143 /** Create a task from the program loader image. 158 144 * 159 * @param p rgBuffer for storing program info.160 * @param name 145 * @param p Buffer for storing program info. 146 * @param name Name to set for the program's task. 161 147 * 162 148 * @return EOK on success or negative error code. 163 * 164 */ 165 int program_create_loader(program_t *prg, char *name) 166 { 167 as_t *as = as_create(0); 168 if (!as) 169 return ENOMEM; 170 171 void *loader = program_loader; 172 if (!loader) { 149 */ 150 int program_create_loader(program_t *p, char *name) 151 { 152 as_t *as; 153 unsigned int rc; 154 void *loader; 155 156 as = as_create(0); 157 ASSERT(as); 158 159 loader = program_loader; 160 if (!loader) return ENOENT; 161 162 rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); 163 if (rc != EE_OK) { 173 164 as_destroy(as); 174 printf("Cannot spawn loader as none was registered\n");175 165 return ENOENT; 176 166 } 177 178 unsigned int rc = elf_load((elf_header_t *) program_loader, as, 179 ELD_F_LOADER); 180 if (rc != EE_OK) { 181 as_destroy(as); 182 printf("Cannot spawn loader (%s)\n", elf_error(rc)); 183 return ENOENT; 184 } 185 186 return program_create(as, ((elf_header_t *) program_loader)->e_entry, 187 name, prg); 167 168 program_create(as, ((elf_header_t *) program_loader)->e_entry, 169 name, p); 170 171 return EOK; 188 172 } 189 173 … … 192 176 * Switch program's main thread to the ready state. 193 177 * 194 * @param prg Program to make ready. 195 * 196 */ 197 void program_ready(program_t *prg) 198 { 199 thread_ready(prg->main_thread); 178 * @param p Program to make ready. 179 */ 180 void program_ready(program_t *p) 181 { 182 thread_ready(p->main_thread); 200 183 } 201 184 … … 205 188 * the task name. 206 189 * 207 * @param uspace_name Name to set on the new task (typically the same 208 * as the command used to execute it). 209 * @param name_len Length of the name. 210 * 211 * @return EOK on success or an error code from @ref errno.h. 212 * 213 */ 214 sysarg_t sys_program_spawn_loader(char *uspace_name, size_t name_len) 215 { 190 * @param name Name to set on the new task (typically the same 191 * as the command used to execute it). 192 * 193 * @return 0 on success or an error code from @ref errno.h. 194 */ 195 unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len) 196 { 197 program_t p; 198 int rc; 199 char namebuf[TASK_NAME_BUFLEN]; 200 216 201 /* Cap length of name and copy it from userspace. */ 202 217 203 if (name_len > TASK_NAME_BUFLEN - 1) 218 204 name_len = TASK_NAME_BUFLEN - 1; 219 220 char namebuf[TASK_NAME_BUFLEN]; 221 int rc = copy_from_uspace(namebuf, uspace_name, name_len); 205 206 rc = copy_from_uspace(namebuf, uspace_name, name_len); 222 207 if (rc != 0) 223 return ( sysarg_t) rc;224 208 return (unative_t) rc; 209 225 210 namebuf[name_len] = 0; 226 211 227 212 /* Spawn the new task. */ 228 program_t prg; 229 rc = program_create_loader(&p rg, namebuf);213 214 rc = program_create_loader(&p, namebuf); 230 215 if (rc != 0) 231 216 return rc; 232 217 233 218 // FIXME: control the capabilities 234 cap_set(prg.task, cap_get(TASK)); 235 program_ready(&prg); 236 219 cap_set(p.task, cap_get(TASK)); 220 221 program_ready(&p); 222 237 223 return EOK; 238 224 }
Note:
See TracChangeset
for help on using the changeset viewer.