Rev 3001 | Rev 3149 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3001 | Rev 3004 | ||
---|---|---|---|
Line 48... | Line 48... | ||
48 | #include <panic.h> |
48 | #include <panic.h> |
49 | #include <adt/avl.h> |
49 | #include <adt/avl.h> |
50 | #include <adt/btree.h> |
50 | #include <adt/btree.h> |
51 | #include <adt/list.h> |
51 | #include <adt/list.h> |
52 | #include <ipc/ipc.h> |
52 | #include <ipc/ipc.h> |
- | 53 | #include <ipc/ipcrsc.h> |
|
53 | #include <security/cap.h> |
54 | #include <security/cap.h> |
54 | #include <memstr.h> |
55 | #include <memstr.h> |
55 | #include <print.h> |
56 | #include <print.h> |
56 | #include <lib/elf.h> |
57 | #include <lib/elf.h> |
57 | #include <errno.h> |
58 | #include <errno.h> |
Line 321... | Line 322... | ||
321 | return EOK; |
322 | return EOK; |
322 | } |
323 | } |
323 | 324 | ||
324 | /** Create a task from the program loader image. |
325 | /** Create a task from the program loader image. |
325 | * |
326 | * |
326 | * @param program_addr Address of program executable image. |
- | |
327 | * @param name Program name. |
327 | * @param name Program name. |
- | 328 | * @param t Buffer for storing pointer to the newly created task. |
|
328 | * |
329 | * |
329 | * @return Task of the running program or NULL on error. |
330 | * @return Task of the running program or NULL on error. |
330 | */ |
331 | */ |
331 | task_t *task_create_from_loader(char *name) |
332 | int task_create_from_loader(char *name, task_t **t) |
332 | { |
333 | { |
333 | as_t *as; |
334 | as_t *as; |
334 | unsigned int rc; |
335 | unsigned int rc; |
- | 336 | void *loader; |
|
335 | 337 | ||
336 | as = as_create(0); |
338 | as = as_create(0); |
337 | ASSERT(as); |
339 | ASSERT(as); |
338 | 340 | ||
- | 341 | loader = program_loader; |
|
- | 342 | if (!loader) return ENOENT; |
|
- | 343 | ||
339 | rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); |
344 | rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); |
340 | if (rc != EE_OK) { |
345 | if (rc != EE_OK) { |
341 | as_destroy(as); |
346 | as_destroy(as); |
342 | return NULL; |
347 | return ENOENT; |
343 | } |
348 | } |
344 | 349 | ||
345 | return task_create_from_as( |
350 | *t = task_create_from_as( |
346 | as, ((elf_header_t *) program_loader)->e_entry, name); |
351 | as, ((elf_header_t *) program_loader)->e_entry, name); |
- | 352 | ||
- | 353 | return EOK; |
|
347 | } |
354 | } |
348 | 355 | ||
349 | /** Make task ready. |
356 | /** Make task ready. |
350 | * |
357 | * |
351 | * Switch task's thread to the ready state. |
358 | * Switch task's thread to the ready state. |
Line 377... | Line 384... | ||
377 | sizeof(TASK->taskid)); |
384 | sizeof(TASK->taskid)); |
378 | } |
385 | } |
379 | 386 | ||
380 | /** Syscall for creating a new task from userspace. |
387 | /** Syscall for creating a new task from userspace. |
381 | * |
388 | * |
382 | * Creates a new task from the program loader image and stores its |
389 | * Creates a new task from the program loader image, connects a phone |
383 | * task id into the provided buffer. |
390 | * to it and stores the phone id into the provided buffer. |
384 | * |
391 | * |
385 | * @param uspace_task_id Userspace address of 8-byte buffer where to store |
392 | * @param uspace_phone_id Userspace address where to store the phone id. |
386 | * current task ID. |
- | |
387 | * |
393 | * |
388 | * @return 0 on success or an error code from @ref errno.h. |
394 | * @return 0 on success or an error code from @ref errno.h. |
389 | */ |
395 | */ |
390 | unative_t sys_task_spawn(task_id_t *uspace_task_id) |
396 | unative_t sys_task_spawn(int *uspace_phone_id) |
391 | { |
397 | { |
392 | task_t *t; |
398 | task_t *t; |
393 | task_id_t fake_id; |
399 | int fake_id; |
394 | int rc; |
400 | int rc; |
- | 401 | int phone_id; |
|
- | 402 | ||
- | 403 | fake_id = 0; |
|
395 | 404 | ||
396 | /* Before we even try creating the task, see if we can write the id */ |
405 | /* Before we even try creating the task, see if we can write the id */ |
397 | rc = (unative_t) copy_to_uspace(uspace_task_id, &fake_id, |
406 | rc = (unative_t) copy_to_uspace(uspace_phone_id, &fake_id, |
398 | sizeof(fake_id)); |
407 | sizeof(fake_id)); |
399 | if (rc != 0) |
408 | if (rc != 0) |
400 | return rc; |
409 | return rc; |
401 | 410 | ||
- | 411 | phone_id = phone_alloc(); |
|
- | 412 | if (phone_id < 0) |
|
- | 413 | return ELIMIT; |
|
- | 414 | ||
402 | t = task_create_from_loader("loader"); |
415 | rc = task_create_from_loader("loader", &t); |
- | 416 | if (rc != 0) |
|
- | 417 | return rc; |
|
- | 418 | ||
- | 419 | phone_connect(phone_id, &t->answerbox); |
|
403 | 420 | ||
404 | /* No need to aquire lock before task_ready() */ |
421 | /* No need to aquire lock before task_ready() */ |
405 | rc = (unative_t) copy_to_uspace(uspace_task_id, &t->taskid, |
422 | rc = (unative_t) copy_to_uspace(uspace_phone_id, &phone_id, |
406 | sizeof(t->taskid)); |
423 | sizeof(phone_id)); |
407 | if (rc != 0) { |
424 | if (rc != 0) { |
408 | /* Ooops */ |
425 | /* Ooops */ |
- | 426 | ipc_phone_hangup(&TASK->phones[phone_id]); |
|
409 | task_kill(t->taskid); |
427 | task_kill(t->taskid); |
410 | return rc; |
428 | return rc; |
411 | } |
429 | } |
412 | 430 | ||
413 | task_ready(t); |
431 | task_ready(t); |