Ignore:
File:
1 edited

Legend:

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

    rbfe43d5 r1ea99cc  
    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>
    5352#include <syscall/copy.h>
    5453#include <proc/program.h>
     
    6665/** Create a program using an existing address space.
    6766 *
    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 */
     72void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p)
     73{
     74        as_area_t *a;
    7875        uspace_arg_t *kernel_uarg;
    79        
     76
    8077        kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    8178        kernel_uarg->uspace_entry = (void *) entry_addr;
     
    8582        kernel_uarg->uspace_uarg = NULL;
    8683       
    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
    9187        /*
    92          * Create the data address space area.
     88         * Create the data as_area.
    9389         */
    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,
    9691            LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
    9792            AS_AREA_ATTR_NONE, &anon_backend, NULL);
    98         if (!area)
    99                 return ENOMEM;
    100        
     93
    10194        /*
    10295         * Create the main thread.
    10396         */
    104         prg->main_thread = thread_create(uinit, kernel_uarg, prg->task,
     97        p->main_thread = thread_create(uinit, kernel_uarg, p->task,
    10598            THREAD_FLAG_USPACE, "uinit", false);
    106         if (!prg->main_thread)
    107                 return ELIMIT;
    108        
    109         return EOK;
     99        ASSERT(p->main_thread);
    110100}
    111101
     
    116106 * executable image. The task is returned in *task.
    117107 *
    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.
     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.
    123113 *
    124114 * @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 */
     116int 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);
    134125        if (rc != EE_OK) {
    135126                as_destroy(as);
    136                 prg->task = NULL;
    137                 prg->main_thread = NULL;
    138                
     127                p->task = NULL;
     128                p->main_thread = NULL;
    139129                if (rc != EE_LOADER)
    140130                        return ENOTSUP;
    141131               
    142132                /* Register image as the program loader */
    143                 if (program_loader != NULL)
    144                         return ELIMIT;
    145                
     133                ASSERT(program_loader == NULL);
    146134                program_loader = image_addr;
    147                 LOG("Registered program loader at %p",
    148                     (void *) image_addr);
    149                
    150135                return EOK;
    151136        }
    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;
    155141}
    156142
    157143/** Create a task from the program loader image.
    158144 *
    159  * @param prg  Buffer for storing program info.
    160  * @param name Name to set for the program's task.
     145 * @param p     Buffer for storing program info.
     146 * @param name  Name to set for the program's task.
    161147 *
    162148 * @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 */
     150int 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) {
    173164                as_destroy(as);
    174                 printf("Cannot spawn loader as none was registered\n");
    175165                return ENOENT;
    176166        }
    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;
    188172}
    189173
     
    192176 * Switch program's main thread to the ready state.
    193177 *
    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 */
     180void program_ready(program_t *p)
     181{
     182        thread_ready(p->main_thread);
    200183}
    201184
     
    205188 * the task name.
    206189 *
    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 */
     195unative_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
    216201        /* Cap length of name and copy it from userspace. */
     202
    217203        if (name_len > TASK_NAME_BUFLEN - 1)
    218204                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);
    222207        if (rc != 0)
    223                 return (sysarg_t) rc;
    224        
     208                return (unative_t) rc;
     209
    225210        namebuf[name_len] = 0;
    226        
     211
    227212        /* Spawn the new task. */
    228         program_t prg;
    229         rc = program_create_loader(&prg, namebuf);
     213
     214        rc = program_create_loader(&p, namebuf);
    230215        if (rc != 0)
    231216                return rc;
    232        
     217
    233218        // 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
    237223        return EOK;
    238224}
Note: See TracChangeset for help on using the changeset viewer.