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); |