Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/program.c

    r1ea99cc rbfe43d5  
    3434/**
    3535 * @file
    36  * @brief       Running userspace programs.
     36 * @brief Running userspace programs.
    3737 */
    3838
     
    5050#include <lib/elf.h>
    5151#include <errno.h>
     52#include <print.h>
    5253#include <syscall/copy.h>
    5354#include <proc/program.h>
     
    6566/** Create a program using an existing address space.
    6667 *
    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;
     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 */
     76int program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *prg)
     77{
    7578        uspace_arg_t *kernel_uarg;
    76 
     79       
    7780        kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    7881        kernel_uarg->uspace_entry = (void *) entry_addr;
     
    8285        kernel_uarg->uspace_uarg = NULL;
    8386       
    84         p->task = task_create(as, name);
    85         ASSERT(p->task);
    86 
     87        prg->task = task_create(as, name);
     88        if (!prg->task)
     89                return ELIMIT;
     90       
    8791        /*
    88          * Create the data as_area.
     92         * Create the data address space area.
    8993         */
    90         a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
     94        as_area_t *area = as_area_create(as,
     95            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
    9196            LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
    9297            AS_AREA_ATTR_NONE, &anon_backend, NULL);
    93 
     98        if (!area)
     99                return ENOMEM;
     100       
    94101        /*
    95102         * Create the main thread.
    96103         */
    97         p->main_thread = thread_create(uinit, kernel_uarg, p->task,
     104        prg->main_thread = thread_create(uinit, kernel_uarg, prg->task,
    98105            THREAD_FLAG_USPACE, "uinit", false);
    99         ASSERT(p->main_thread);
     106        if (!prg->main_thread)
     107                return ELIMIT;
     108       
     109        return EOK;
    100110}
    101111
     
    106116 * executable image. The task is returned in *task.
    107117 *
    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.
     118 * @param image_addr Address of an executable program image.
     119 * @param name       Name to set for the program's task.
     120 * @param prg        Buffer for storing program info. If image_addr
     121 *                   points to a loader image, p->task will be set to
     122 *                   NULL and EOK will be returned.
    113123 *
    114124 * @return EOK on success or negative error code.
    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);
     125 *
     126 */
     127int 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);
    125134        if (rc != EE_OK) {
    126135                as_destroy(as);
    127                 p->task = NULL;
    128                 p->main_thread = NULL;
     136                prg->task = NULL;
     137                prg->main_thread = NULL;
     138               
    129139                if (rc != EE_LOADER)
    130140                        return ENOTSUP;
    131141               
    132142                /* Register image as the program loader */
    133                 ASSERT(program_loader == NULL);
     143                if (program_loader != NULL)
     144                        return ELIMIT;
     145               
    134146                program_loader = image_addr;
     147                LOG("Registered program loader at %p",
     148                    (void *) image_addr);
     149               
    135150                return EOK;
    136151        }
    137 
    138         program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p);
    139 
    140         return EOK;
     152       
     153        return program_create(as, ((elf_header_t *) image_addr)->e_entry,
     154            name, prg);
    141155}
    142156
    143157/** Create a task from the program loader image.
    144158 *
    145  * @param p     Buffer for storing program info.
    146  * @param name  Name to set for the program's task.
     159 * @param prg  Buffer for storing program info.
     160 * @param name Name to set for the program's task.
    147161 *
    148162 * @return EOK on success or negative error code.
    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 *
     164 */
     165int 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) {
     173                as_destroy(as);
     174                printf("Cannot spawn loader as none was registered\n");
     175                return ENOENT;
     176        }
     177       
     178        unsigned int rc = elf_load((elf_header_t *) program_loader, as,
     179            ELD_F_LOADER);
    163180        if (rc != EE_OK) {
    164181                as_destroy(as);
     182                printf("Cannot spawn loader (%s)\n", elf_error(rc));
    165183                return ENOENT;
    166184        }
    167 
    168         program_create(as, ((elf_header_t *) program_loader)->e_entry,
    169             name, p);
    170 
    171         return EOK;
     185       
     186        return program_create(as, ((elf_header_t *) program_loader)->e_entry,
     187            name, prg);
    172188}
    173189
     
    176192 * Switch program's main thread to the ready state.
    177193 *
    178  * @param p Program to make ready.
    179  */
    180 void program_ready(program_t *p)
    181 {
    182         thread_ready(p->main_thread);
     194 * @param prg Program to make ready.
     195 *
     196 */
     197void program_ready(program_t *prg)
     198{
     199        thread_ready(prg->main_thread);
    183200}
    184201
     
    188205 * the task name.
    189206 *
    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 
     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 */
     214sysarg_t sys_program_spawn_loader(char *uspace_name, size_t name_len)
     215{
    201216        /* Cap length of name and copy it from userspace. */
    202 
    203217        if (name_len > TASK_NAME_BUFLEN - 1)
    204218                name_len = TASK_NAME_BUFLEN - 1;
    205 
    206         rc = copy_from_uspace(namebuf, uspace_name, name_len);
     219       
     220        char namebuf[TASK_NAME_BUFLEN];
     221        int rc = copy_from_uspace(namebuf, uspace_name, name_len);
    207222        if (rc != 0)
    208                 return (unative_t) rc;
    209 
     223                return (sysarg_t) rc;
     224       
    210225        namebuf[name_len] = 0;
    211 
     226       
    212227        /* Spawn the new task. */
    213 
    214         rc = program_create_loader(&p, namebuf);
     228        program_t prg;
     229        rc = program_create_loader(&prg, namebuf);
    215230        if (rc != 0)
    216231                return rc;
    217 
     232       
    218233        // FIXME: control the capabilities
    219         cap_set(p.task, cap_get(TASK));
    220 
    221         program_ready(&p);
    222 
     234        cap_set(prg.task, cap_get(TASK));
     235        program_ready(&prg);
     236       
    223237        return EOK;
    224238}
Note: See TracChangeset for help on using the changeset viewer.