Subversion Repositories HelenOS

Rev

Rev 3186 | Rev 3359 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3186 Rev 3222
Line 33... Line 33...
33
/**
33
/**
34
 * @file
34
 * @file
35
 * @brief   Task management.
35
 * @brief   Task management.
36
 */
36
 */
37
 
37
 
38
#include <main/uinit.h>
-
 
39
#include <proc/thread.h>
38
#include <proc/thread.h>
40
#include <proc/task.h>
39
#include <proc/task.h>
41
#include <proc/uarg.h>
-
 
42
#include <mm/as.h>
40
#include <mm/as.h>
43
#include <mm/slab.h>
41
#include <mm/slab.h>
44
#include <atomic.h>
42
#include <atomic.h>
45
#include <synch/spinlock.h>
43
#include <synch/spinlock.h>
46
#include <synch/waitq.h>
44
#include <synch/waitq.h>
47
#include <arch.h>
45
#include <arch.h>
48
#include <arch/barrier.h>
46
#include <arch/barrier.h>
49
#include <panic.h>
-
 
50
#include <adt/avl.h>
47
#include <adt/avl.h>
51
#include <adt/btree.h>
48
#include <adt/btree.h>
52
#include <adt/list.h>
49
#include <adt/list.h>
53
#include <ipc/ipc.h>
50
#include <ipc/ipc.h>
54
#include <security/cap.h>
51
#include <ipc/ipcrsc.h>
55
#include <memstr.h>
-
 
56
#include <print.h>
52
#include <print.h>
57
#include <lib/elf.h>
-
 
58
#include <errno.h>
53
#include <errno.h>
59
#include <func.h>
54
#include <func.h>
60
#include <syscall/copy.h>
55
#include <syscall/copy.h>
61
 
56
 
62
#ifndef LOADED_PROG_STACK_PAGES_NO
-
 
63
#define LOADED_PROG_STACK_PAGES_NO 1
-
 
64
#endif
-
 
65
 
-
 
66
/** Spinlock protecting the tasks_tree AVL tree. */
57
/** Spinlock protecting the tasks_tree AVL tree. */
67
SPINLOCK_INITIALIZE(tasks_lock);
58
SPINLOCK_INITIALIZE(tasks_lock);
68
 
59
 
69
/** AVL tree of active tasks.
60
/** AVL tree of active tasks.
70
 *
61
 *
Line 249... Line 240...
249
     */
240
     */
250
    return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid,
241
    return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid,
251
        sizeof(TASK->taskid));
242
        sizeof(TASK->taskid));
252
}
243
}
253
 
244
 
254
unative_t sys_task_spawn(void *image, size_t size)
-
 
255
{
-
 
256
    void *kimage = malloc(size, 0);
-
 
257
    if (kimage == NULL)
-
 
258
        return ENOMEM;
-
 
259
   
-
 
260
    int rc = copy_from_uspace(kimage, image, size);
-
 
261
    if (rc != EOK)
-
 
262
        return rc;
-
 
263
 
-
 
264
    /*
-
 
265
     * Not very efficient and it would be better to call it on code only,
-
 
266
     * but this whole function is a temporary hack anyway and one day it
-
 
267
     * will go in favor of the userspace dynamic loader.
-
 
268
     */
-
 
269
    smc_coherence_block(kimage, size);
-
 
270
   
-
 
271
    uspace_arg_t *kernel_uarg;
-
 
272
    kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
-
 
273
    if (kernel_uarg == NULL) {
-
 
274
        free(kimage);
-
 
275
        return ENOMEM;
-
 
276
    }
-
 
277
   
-
 
278
    kernel_uarg->uspace_entry =
-
 
279
        (void *) ((elf_header_t *) kimage)->e_entry;
-
 
280
    kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
-
 
281
    kernel_uarg->uspace_thread_function = NULL;
-
 
282
    kernel_uarg->uspace_thread_arg = NULL;
-
 
283
    kernel_uarg->uspace_uarg = NULL;
-
 
284
   
-
 
285
    as_t *as = as_create(0);
-
 
286
    if (as == NULL) {
-
 
287
        free(kernel_uarg);
-
 
288
        free(kimage);
-
 
289
        return ENOMEM;
-
 
290
    }
-
 
291
   
-
 
292
    unsigned int erc = elf_load((elf_header_t *) kimage, as);
-
 
293
    if (erc != EE_OK) {
-
 
294
        as_destroy(as);
-
 
295
        free(kernel_uarg);
-
 
296
        free(kimage);
-
 
297
        return ENOENT;
-
 
298
    }
-
 
299
   
-
 
300
    as_area_t *area = as_area_create(as,
-
 
301
        AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
-
 
302
        LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
-
 
303
        AS_AREA_ATTR_NONE, &anon_backend, NULL);
-
 
304
    if (area == NULL) {
-
 
305
        as_destroy(as);
-
 
306
        free(kernel_uarg);
-
 
307
        free(kimage);
-
 
308
        return ENOMEM;
-
 
309
    }
-
 
310
   
-
 
311
    task_t *task = task_create(as, "app");
-
 
312
    if (task == NULL) {
-
 
313
        as_destroy(as);
-
 
314
        free(kernel_uarg);
-
 
315
        free(kimage);
-
 
316
        return ENOENT;
-
 
317
    }
-
 
318
   
-
 
319
    // FIXME: control the capabilities
-
 
320
    cap_set(task, cap_get(TASK));
-
 
321
   
-
 
322
    thread_t *thread = thread_create(uinit, kernel_uarg, task,
-
 
323
        THREAD_FLAG_USPACE, "user", false);
-
 
324
    if (thread == NULL) {
-
 
325
        task_destroy(task);
-
 
326
        as_destroy(as);
-
 
327
        free(kernel_uarg);
-
 
328
        free(kimage);
-
 
329
        return ENOENT;
-
 
330
    }
-
 
331
   
-
 
332
    thread_ready(thread);
-
 
333
   
-
 
334
    return EOK;
-
 
335
}
-
 
336
 
-
 
337
/** Find task structure corresponding to task ID.
245
/** Find task structure corresponding to task ID.
338
 *
246
 *
339
 * The tasks_lock must be already held by the caller of this function
247
 * The tasks_lock must be already held by the caller of this function
340
 * and interrupts must be disabled.
248
 * and interrupts must be disabled.
341
 *
249
 *