Changeset c98e6ee in mainline


Ignore:
Timestamp:
2008-07-08T16:05:45Z (16 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f93f168
Parents:
b7f9087
Message:

Merge program-loader related stuff from dynload branch to trunk. (huge)

Files:
39 added
50 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/amd64/Makefile.inc

    rb7f9087 rc98e6ee  
    2929INIT_TASKS = \
    3030        $(USPACEDIR)/srv/ns/ns \
     31        $(USPACEDIR)/srv/loader/loader \
    3132        $(USPACEDIR)/app/init/init \
    3233        $(USPACEDIR)/srv/devmap/devmap \
    3334        $(USPACEDIR)/srv/rd/rd \
    3435        $(USPACEDIR)/srv/vfs/vfs \
    35         $(USPACEDIR)/srv/fs/tmpfs/tmpfs
     36        $(USPACEDIR)/srv/fs/tmpfs/tmpfs \
    3637
    3738RD_TASKS = \
     
    4344        $(USPACEDIR)/app/tetris/tetris \
    4445        $(USPACEDIR)/app/tester/tester \
    45         $(USPACEDIR)/app/klog/klog
     46        $(USPACEDIR)/app/klog/klog \
     47        $(USPACEDIR)/app/cli/cli
    4648
    4749build: $(BASE)/image.iso
  • boot/arch/amd64/grub/menu.lst

    rb7f9087 rc98e6ee  
    1111        module /boot/vfs
    1212        module /boot/tmpfs
     13        module /boot/loader
    1314        module /boot/initrd.img
  • boot/arch/arm32/loader/Makefile

    rb7f9087 rc98e6ee  
    8181        $(KERNELDIR)/kernel.bin \
    8282        $(USPACEDIR)/srv/ns/ns \
     83        $(USPACEDIR)/srv/loader/loader \
    8384        $(USPACEDIR)/app/init/init \
    8485        $(USPACEDIR)/srv/devmap/devmap \
     
    9495        $(USPACEDIR)/app/tetris/tetris \
    9596        $(USPACEDIR)/app/tester/tester \
    96         $(USPACEDIR)/app/klog/klog
     97        $(USPACEDIR)/app/klog/klog \
     98        $(USPACEDIR)/app/cli/cli
    9799
    98100OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
  • boot/arch/ia32/Makefile.inc

    rb7f9087 rc98e6ee  
    2929INIT_TASKS = \
    3030        $(USPACEDIR)/srv/ns/ns \
     31        $(USPACEDIR)/srv/loader/loader \
    3132        $(USPACEDIR)/app/init/init \
    3233        $(USPACEDIR)/srv/devmap/devmap \
     
    4344        $(USPACEDIR)/app/tetris/tetris \
    4445        $(USPACEDIR)/app/tester/tester \
     46        $(USPACEDIR)/app/cli/cli \
    4547        $(USPACEDIR)/app/klog/klog
    4648
  • boot/arch/ia32/grub/menu.lst

    rb7f9087 rc98e6ee  
    1111        module /boot/vfs
    1212        module /boot/tmpfs
     13        module /boot/loader
    1314        module /boot/initrd.img
  • boot/arch/ia64/loader/Makefile

    rb7f9087 rc98e6ee  
    8787        $(KERNELDIR)/kernel.bin \
    8888        $(USPACEDIR)/srv/ns/ns \
     89        $(USPACEDIR)/srv/loader/loader \
    8990        $(USPACEDIR)/srv/fb/fb \
    9091        $(USPACEDIR)/srv/kbd/kbd \
  • boot/arch/mips32/loader/Makefile

    rb7f9087 rc98e6ee  
    8181        $(KERNELDIR)/kernel.bin \
    8282        $(USPACEDIR)/srv/ns/ns \
     83        $(USPACEDIR)/srv/loader/loader \
    8384        $(USPACEDIR)/app/init/init \
    8485        $(USPACEDIR)/srv/devmap/devmap \
     
    9495        $(USPACEDIR)/app/tetris/tetris \
    9596        $(USPACEDIR)/app/tester/tester \
     97        $(USPACEDIR)/app/cli/cli \
    9698        $(USPACEDIR)/app/klog/klog
     99
    97100
    98101OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
  • boot/arch/ppc32/loader/Makefile

    rb7f9087 rc98e6ee  
    7676        $(KERNELDIR)/kernel.bin \
    7777        $(USPACEDIR)/srv/ns/ns \
     78        $(USPACEDIR)/srv/loader/loader \
    7879        $(USPACEDIR)/app/init/init \
    7980        $(USPACEDIR)/srv/devmap/devmap \
     
    8990        $(USPACEDIR)/app/tetris/tetris \
    9091        $(USPACEDIR)/app/tester/tester \
    91         $(USPACEDIR)/app/klog/klog
     92        $(USPACEDIR)/app/klog/klog \
     93        $(USPACEDIR)/app/cli/cli
    9294
    9395OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
  • boot/arch/sparc64/loader/Makefile

    rb7f9087 rc98e6ee  
    8080        $(USPACEDIR)/srv/ns/ns \
    8181        $(USPACEDIR)/app/init/init \
     82        $(USPACEDIR)/srv/loader/loader \
    8283        $(USPACEDIR)/srv/devmap/devmap \
    8384        $(USPACEDIR)/srv/rd/rd \
     
    9293        $(USPACEDIR)/app/tetris/tetris \
    9394        $(USPACEDIR)/app/tester/tester \
     95        $(USPACEDIR)/app/cli/cli \
    9496        $(USPACEDIR)/app/klog/klog
    9597
  • kernel/Makefile

    rb7f9087 rc98e6ee  
    233233        generic/src/main/version.c \
    234234        generic/src/main/shutdown.c \
     235        generic/src/proc/program.c \
    235236        generic/src/proc/scheduler.c \
    236237        generic/src/proc/thread.c \
     
    271272        generic/src/synch/mutex.c \
    272273        generic/src/synch/semaphore.c \
     274        generic/src/synch/smc.c \
    273275        generic/src/synch/waitq.c \
    274276        generic/src/synch/futex.c \
  • kernel/arch/amd64/src/userspace.c

    rb7f9087 rc98e6ee  
    6262                          "pushq %4\n"
    6363                          "movq %5, %%rax\n"
     64                          /* %rdi is defined to hold pcb_ptr - set it to 0 */
     65                          "xorq %%rdi, %%rdi\n"
    6466                          "iretq\n"
    6567                          : :
  • kernel/arch/arm32/src/userspace.c

    rb7f9087 rc98e6ee  
    7171        ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg;
    7272
     73        /* %r1 is defined to hold pcb_ptr - set it to 0 */
     74        ustate.r1 = 0;
     75
    7376        /* clear other registers */
    74         ustate.r1 = ustate.r2 = ustate.r3  = ustate.r4  = ustate.r5 =
     77        ustate.r2 = ustate.r3  = ustate.r4  = ustate.r5 =
    7578            ustate.r6  = ustate.r7  = ustate.r8  = ustate.r9 = ustate.r10 =
    7679            ustate.r11 = ustate.r12 = ustate.lr = 0;
  • kernel/arch/ia32/src/userspace.c

    rb7f9087 rc98e6ee  
    7171                "pushl %4\n"
    7272                "movl %5, %%eax\n"
     73
     74                /* %ebx is defined to hold pcb_ptr - set it to 0 */
     75                "xorl %%ebx, %%ebx\n"   
     76
    7377                "iret\n"
    7478                :
  • kernel/arch/ia32xen/src/userspace.c

    rb7f9087 rc98e6ee  
    6969                "pushl %4\n"
    7070                "movl %5, %%eax\n"
     71
     72                /* %ebx is defined to hold pcb_ptr - set it to 0 */
     73                "xorl %%ebx, %%ebx\n"
     74
    7175                "iret\n"
    7276                :
  • kernel/arch/ia64/src/asm.S

    rb7f9087 rc98e6ee  
    164164        xor r1 = r1, r1
    165165       
     166        /* r2 is defined to hold pcb_ptr - set it to 0 */
     167        xor r2 = r2, r2
     168       
    166169        mov loc1 = cr.ifs
    167170        movl loc2 = PFM_MASK ;;
  • kernel/arch/mips32/src/start.S

    rb7f9087 rc98e6ee  
    350350        add $sp, $a0, 0
    351351        add $v0, $a1, 0
    352         add $t9, $a2, 0                 # Set up correct entry into PIC code
    353         eret
     352        add $t9, $a2, 0                 # Set up correct entry into PIC code
     353        xor $a0, $a0, $a0               # $a0 is defined to hold pcb_ptr
     354                                        # set it to 0
     355        eret
  • kernel/arch/ppc32/src/asm.S

    rb7f9087 rc98e6ee  
    6666       
    6767        mr sp, r4
     68
     69        # %r3 is defined to hold pcb_ptr - set it to 0
     70
     71        xor r3, r3, r3
    6872       
    6973        # jump to userspace
  • kernel/arch/ppc64/src/asm.S

    rb7f9087 rc98e6ee  
    6767        mr sp, r4
    6868       
     69        # %r3 is defined to hold pcb_ptr - set it to 0
     70
     71        xor r3, r3, r3
     72
    6973        # jump to userspace
    7074       
  • kernel/arch/sparc64/src/asm.S

    rb7f9087 rc98e6ee  
    275275
    276276        mov %i2, %o0                    ! uarg
     277        xor %o1, %o1, %o1               ! %o1 is defined to hold pcb_ptr
     278                                        ! set it to 0
    277279
    278280        clr %i2
  • kernel/generic/include/lib/elf.h

    rb7f9087 rc98e6ee  
    115115#define EE_INCOMPATIBLE         3       /* ELF image is not compatible with current architecture */
    116116#define EE_UNSUPPORTED          4       /* Non-supported ELF (e.g. dynamic ELFs) */
    117 #define EE_IRRECOVERABLE        5
     117#define EE_LOADER               5       /* The image is actually a program loader */
     118#define EE_IRRECOVERABLE        6
    118119
    119120/**
     
    339340extern char *elf_error(unsigned int rc);
    340341
     342/* Interpreter string used to recognize the program loader */
     343#define ELF_INTERP_ZSTR "kernel"
     344#define ELF_INTERP_ZLEN  sizeof(ELF_INTERP_ZSTR)
     345
    341346#endif
    342347
  • kernel/generic/include/mm/as.h

    rb7f9087 rc98e6ee  
    270270int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
    271271    as_t *dst_as, uintptr_t dst_base, int dst_flags_mask);
     272extern int as_area_change_flags(as_t *as, int flags, uintptr_t address);
    272273
    273274extern int as_area_get_flags(as_area_t *area);
     
    300301extern mem_backend_t phys_backend;
    301302
    302 extern unsigned int elf_load(elf_header_t *header, as_t *as);
     303/**
     304 * This flags is passed when running the loader, otherwise elf_load()
     305 * would return with a EE_LOADER error code.
     306 */
     307#define ELD_F_NONE      0
     308#define ELD_F_LOADER    1
     309
     310extern unsigned int elf_load(elf_header_t *header, as_t *as, int flags);
    303311
    304312/* Address space area related syscalls. */
    305313extern unative_t sys_as_area_create(uintptr_t address, size_t size, int flags);
    306314extern unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags);
     315extern unative_t sys_as_area_change_flags(uintptr_t address, int flags);
    307316extern unative_t sys_as_area_destroy(uintptr_t address);
    308317
  • kernel/generic/include/proc/task.h

    rb7f9087 rc98e6ee  
    133133
    134134extern unative_t sys_task_get_id(task_id_t *uspace_task_id);
    135 extern unative_t sys_task_spawn(void *image, size_t size);
    136135
    137136#endif
  • kernel/generic/include/proc/thread.h

    rb7f9087 rc98e6ee  
    249249extern bool thread_exists(thread_t *t);
    250250
    251 extern thread_t *thread_create_program(void *program_addr, char *name);
    252 
    253251/** Fpu context slab cache. */
    254252extern slab_cache_t *fpu_context_slab;
  • kernel/generic/include/syscall/syscall.h

    rb7f9087 rc98e6ee  
    4545       
    4646        SYS_TASK_GET_ID,
    47         SYS_TASK_SPAWN,
     47        SYS_PROGRAM_SPAWN_LOADER,
    4848       
    4949        SYS_FUTEX_SLEEP,
    5050        SYS_FUTEX_WAKEUP,
     51        SYS_SMC_COHERENCE,
    5152       
    5253        SYS_AS_AREA_CREATE,
    5354        SYS_AS_AREA_RESIZE,
     55        SYS_AS_AREA_CHANGE_FLAGS,
    5456        SYS_AS_AREA_DESTROY,
    5557       
  • kernel/generic/src/lib/elf.c

    rb7f9087 rc98e6ee  
    5858
    5959static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
    60     as_t *as);
     60    as_t *as, int flags);
    6161static int section_header(elf_section_header_t *entry, elf_header_t *elf,
    6262    as_t *as);
     
    6868 * @param header Pointer to ELF header in memory
    6969 * @param as Created and properly mapped address space
     70 * @param flags A combination of ELD_F_*
    7071 * @return EE_OK on success
    7172 */
    72 unsigned int elf_load(elf_header_t *header, as_t * as)
     73unsigned int elf_load(elf_header_t *header, as_t * as, int flags)
    7374{
    7475        int i, rc;
     
    111112                seghdr = &((elf_segment_header_t *)(((uint8_t *) header) +
    112113                    header->e_phoff))[i];
    113                 rc = segment_header(seghdr, header, as);
     114                rc = segment_header(seghdr, header, as, flags);
    114115                if (rc != EE_OK)
    115116                        return rc;
     
    152153 */
    153154static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
    154     as_t *as)
    155 {
     155    as_t *as, int flags)
     156{
     157        char *interp;
     158
    156159        switch (entry->p_type) {
    157160        case PT_NULL:
     
    163166        case PT_DYNAMIC:
    164167        case PT_INTERP:
     168                interp = (char *)elf + entry->p_offset;
     169                /* FIXME */
     170                /*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR,
     171                    ELF_INTERP_ZLEN) != 0) {
     172                        return EE_UNSUPPORTED;
     173                }*/
     174                if ((flags & ELD_F_LOADER) == 0) {
     175                        return EE_LOADER;
     176                }
     177                break;
    165178        case PT_SHLIB:
    166179        case PT_NOTE:
  • kernel/generic/src/main/kinit.c

    rb7f9087 rc98e6ee  
    4848#include <proc/task.h>
    4949#include <proc/thread.h>
     50#include <proc/program.h>
    5051#include <panic.h>
    5152#include <func.h>
     
    160161         */
    161162        count_t i;
    162         thread_t *threads[CONFIG_INIT_TASKS];
     163        program_t programs[CONFIG_INIT_TASKS];
    163164       
    164165        for (i = 0; i < init.cnt; i++) {
     
    168169                }
    169170
    170                 threads[i] = thread_create_program((void *) init.tasks[i].addr,
    171                     "uspace");
    172                
    173                 if (threads[i] != NULL) {
     171                int rc = program_create_from_image((void *) init.tasks[i].addr,
     172                    &programs[i]);
     173
     174                if (rc == 0 && programs[i].task != NULL) {
    174175                        /*
    175176                         * Set capabilities to init userspace tasks.
    176177                         */
    177                         cap_set(threads[i]->task, CAP_CAP | CAP_MEM_MANAGER |
     178                        cap_set(programs[i].task, CAP_CAP | CAP_MEM_MANAGER |
    178179                            CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG);
     180
    179181                       
    180182                        if (!ipc_phone_0)
    181                                 ipc_phone_0 = &threads[i]->task->answerbox;
     183                                ipc_phone_0 = &programs[i].task->answerbox;
     184                } else if (rc == 0) {
     185                        /* It was the program loader and was registered */
    182186                } else {
     187                        /* RAM disk image */
    183188                        int rd = init_rd((rd_header_t *) init.tasks[i].addr,
    184189                            init.tasks[i].size);
     
    194199         */
    195200        for (i = 0; i < init.cnt; i++) {
    196                 if (threads[i] != NULL) {
     201                if (programs[i].task != NULL) {
    197202                        thread_usleep(50000);
    198                         thread_ready(threads[i]);
     203                        program_ready(&programs[i]);
    199204                }
    200205        }
  • kernel/generic/src/mm/as.c

    rb7f9087 rc98e6ee  
    772772}
    773773
     774/** Change adress area flags.
     775 *
     776 * The idea is to have the same data, but with a different access mode.
     777 * This is needed e.g. for writing code into memory and then executing it.
     778 * In order for this to work properly, this may copy the data
     779 * into private anonymous memory (unless it's already there).
     780 *
     781 * @param as Address space.
     782 * @param flags Flags of the area memory.
     783 * @param address Address withing the area to be changed.
     784 *
     785 * @return Zero on success or a value from @ref errno.h on failure.
     786 */
     787int as_area_change_flags(as_t *as, int flags, uintptr_t address)
     788{
     789        as_area_t *area;
     790        uintptr_t base;
     791        link_t *cur;
     792        ipl_t ipl;
     793        int page_flags;
     794        uintptr_t *old_frame;
     795        index_t frame_idx;
     796        count_t used_pages;
     797
     798        /* Flags for the new memory mapping */
     799        page_flags = area_flags_to_page_flags(flags);
     800
     801        ipl = interrupts_disable();
     802        mutex_lock(&as->lock);
     803
     804        area = find_area_and_lock(as, address);
     805        if (!area) {
     806                mutex_unlock(&as->lock);
     807                interrupts_restore(ipl);
     808                return ENOENT;
     809        }
     810
     811        if (area->sh_info || area->backend != &anon_backend) {
     812                /* Copying shared areas not supported yet */
     813                /* Copying non-anonymous memory not supported yet */
     814                mutex_unlock(&area->lock);
     815                mutex_unlock(&as->lock);
     816                interrupts_restore(ipl);
     817                return ENOTSUP;
     818        }
     819
     820        base = area->base;
     821
     822        /*
     823         * Compute total number of used pages in the used_space B+tree
     824         */
     825        used_pages = 0;
     826
     827        for (cur = area->used_space.leaf_head.next;
     828            cur != &area->used_space.leaf_head; cur = cur->next) {
     829                btree_node_t *node;
     830                unsigned int i;
     831               
     832                node = list_get_instance(cur, btree_node_t, leaf_link);
     833                for (i = 0; i < node->keys; i++) {
     834                        used_pages += (count_t) node->value[i];
     835                }
     836        }
     837
     838        /* An array for storing frame numbers */
     839        old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
     840
     841        /*
     842         * Start TLB shootdown sequence.
     843         */
     844        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
     845
     846        /*
     847         * Remove used pages from page tables and remember their frame
     848         * numbers.
     849         */
     850        frame_idx = 0;
     851
     852        for (cur = area->used_space.leaf_head.next;
     853            cur != &area->used_space.leaf_head; cur = cur->next) {
     854                btree_node_t *node;
     855                unsigned int i;
     856               
     857                node = list_get_instance(cur, btree_node_t, leaf_link);
     858                for (i = 0; i < node->keys; i++) {
     859                        uintptr_t b = node->key[i];
     860                        count_t j;
     861                        pte_t *pte;
     862                       
     863                        for (j = 0; j < (count_t) node->value[i]; j++) {
     864                                page_table_lock(as, false);
     865                                pte = page_mapping_find(as, b + j * PAGE_SIZE);
     866                                ASSERT(pte && PTE_VALID(pte) &&
     867                                    PTE_PRESENT(pte));
     868                                old_frame[frame_idx++] = PTE_GET_FRAME(pte);
     869
     870                                /* Remove old mapping */
     871                                page_mapping_remove(as, b + j * PAGE_SIZE);
     872                                page_table_unlock(as, false);
     873                        }
     874                }
     875        }
     876
     877        /*
     878         * Finish TLB shootdown sequence.
     879         */
     880
     881        tlb_invalidate_pages(as->asid, area->base, area->pages);
     882        /*
     883         * Invalidate potential software translation caches (e.g. TSB on
     884         * sparc64).
     885         */
     886        as_invalidate_translation_cache(as, area->base, area->pages);
     887        tlb_shootdown_finalize();
     888
     889        /*
     890         * Map pages back in with new flags. This step is kept separate
     891         * so that there's no instant when the memory area could be
     892         * accesed with both the old and the new flags at once.
     893         */
     894        frame_idx = 0;
     895
     896        for (cur = area->used_space.leaf_head.next;
     897            cur != &area->used_space.leaf_head; cur = cur->next) {
     898                btree_node_t *node;
     899                unsigned int i;
     900               
     901                node = list_get_instance(cur, btree_node_t, leaf_link);
     902                for (i = 0; i < node->keys; i++) {
     903                        uintptr_t b = node->key[i];
     904                        count_t j;
     905                       
     906                        for (j = 0; j < (count_t) node->value[i]; j++) {
     907                                page_table_lock(as, false);
     908
     909                                /* Insert the new mapping */
     910                                page_mapping_insert(as, b + j * PAGE_SIZE,
     911                                    old_frame[frame_idx++], page_flags);
     912
     913                                page_table_unlock(as, false);
     914                        }
     915                }
     916        }
     917
     918        free(old_frame);
     919
     920        mutex_unlock(&area->lock);
     921        mutex_unlock(&as->lock);
     922        interrupts_restore(ipl);
     923
     924        return 0;
     925}
     926
     927
    774928/** Handle page fault within the current address space.
    775929 *
     
    17671921}
    17681922
     1923/** Wrapper for as_area_change_flags(). */
     1924unative_t sys_as_area_change_flags(uintptr_t address, int flags)
     1925{
     1926        return (unative_t) as_area_change_flags(AS, flags, address);
     1927}
     1928
    17691929/** Wrapper for as_area_destroy(). */
    17701930unative_t sys_as_area_destroy(uintptr_t address)
  • kernel/generic/src/proc/task.c

    rb7f9087 rc98e6ee  
    3636 */
    3737
    38 #include <main/uinit.h>
    3938#include <proc/thread.h>
    4039#include <proc/task.h>
    41 #include <proc/uarg.h>
    4240#include <mm/as.h>
    4341#include <mm/slab.h>
     
    4745#include <arch.h>
    4846#include <arch/barrier.h>
    49 #include <panic.h>
    5047#include <adt/avl.h>
    5148#include <adt/btree.h>
    5249#include <adt/list.h>
    5350#include <ipc/ipc.h>
    54 #include <security/cap.h>
    55 #include <memstr.h>
     51#include <ipc/ipcrsc.h>
    5652#include <print.h>
    57 #include <lib/elf.h>
    5853#include <errno.h>
    5954#include <func.h>
    6055#include <syscall/copy.h>
    61 
    62 #ifndef LOADED_PROG_STACK_PAGES_NO
    63 #define LOADED_PROG_STACK_PAGES_NO 1
    64 #endif
    6556
    6657/** Spinlock protecting the tasks_tree AVL tree. */
     
    252243}
    253244
    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 
    337245/** Find task structure corresponding to task ID.
    338246 *
  • kernel/generic/src/proc/thread.c

    rb7f9087 rc98e6ee  
    673673}
    674674
    675 
    676 /** Create new user task with 1 thread from image
    677  *
    678  * @param program_addr Address of program executable image.
    679  * @param name Program name.
    680  *
    681  * @return Initialized main thread of the task or NULL on error.
    682  */
    683 thread_t *thread_create_program(void *program_addr, char *name)
    684 {
    685         as_t *as;
    686         as_area_t *area;
    687         unsigned int rc;
    688         task_t *task;
    689         uspace_arg_t *kernel_uarg;
    690        
    691         kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    692         if (kernel_uarg == NULL)
    693                 return NULL;
    694        
    695         kernel_uarg->uspace_entry =
    696             (void *) ((elf_header_t *) program_addr)->e_entry;
    697         kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
    698         kernel_uarg->uspace_thread_function = NULL;
    699         kernel_uarg->uspace_thread_arg = NULL;
    700         kernel_uarg->uspace_uarg = NULL;
    701 
    702         as = as_create(0);
    703         if (as == NULL) {
    704                 free(kernel_uarg);
    705                 return NULL;
    706         }
    707 
    708         rc = elf_load((elf_header_t *) program_addr, as);
    709         if (rc != EE_OK) {
    710                 free(kernel_uarg);
    711                 as_destroy(as);
    712                 return NULL;
    713         }
    714        
    715         /*
    716          * Create the data as_area.
    717          */
    718         area = as_area_create(as,
    719                 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
    720                 LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
    721                 AS_AREA_ATTR_NONE, &anon_backend, NULL);
    722         if (area == NULL) {
    723                 free(kernel_uarg);
    724                 as_destroy(as);
    725                 return NULL;
    726         }
    727        
    728         task = task_create(as, name);
    729         if (task == NULL) {
    730                 free(kernel_uarg);
    731                 as_destroy(as);
    732                 return NULL;
    733         }
    734        
    735         /*
    736          * Create the main thread.
    737          */
    738         return thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,
    739             "uinit", false);
    740 }
    741 
    742 
    743675/** Update accounting of current thread.
    744676 *
  • kernel/generic/src/syscall/syscall.c

    rb7f9087 rc98e6ee  
    3939#include <proc/thread.h>
    4040#include <proc/task.h>
     41#include <proc/program.h>
    4142#include <mm/as.h>
    4243#include <print.h>
     
    4748#include <ipc/sysipc.h>
    4849#include <synch/futex.h>
     50#include <synch/smc.h>
    4951#include <ddi/ddi.h>
    5052#include <security/cap.h>
     
    124126       
    125127        (syshandler_t) sys_task_get_id,
    126         (syshandler_t) sys_task_spawn,
     128        (syshandler_t) sys_program_spawn_loader,
    127129       
    128130        /* Synchronization related syscalls. */
    129131        (syshandler_t) sys_futex_sleep_timeout,
    130132        (syshandler_t) sys_futex_wakeup,
     133        (syshandler_t) sys_smc_coherence,
    131134       
    132135        /* Address space related syscalls. */
    133136        (syshandler_t) sys_as_area_create,
    134137        (syshandler_t) sys_as_area_resize,
     138        (syshandler_t) sys_as_area_change_flags,
    135139        (syshandler_t) sys_as_area_destroy,
    136140       
  • uspace/Makefile

    rb7f9087 rc98e6ee  
    3838        lib/softfloat \
    3939        srv/ns \
     40        srv/loader \
    4041        srv/fb \
    4142        srv/kbd \
     
    4849        app/tetris \
    4950        app/tester \
     51        app/cli \
    5052        app/klog \
    5153        app/init
  • uspace/app/init/init.c

    rb7f9087 rc98e6ee  
    4646#include "version.h"
    4747
    48 #define BUF_SIZE 150000
    49 
    50 static char *buf;
    51 
    5248static void console_wait(void)
    5349{
     
    8379static void spawn(char *fname)
    8480{
     81        char *argv[2];
     82
    8583        printf(NAME ": Spawning %s\n", fname);
    86        
    87         int fd = open(fname, O_RDONLY);
    88         if (fd >= 0) {
    89        
    90                 ssize_t rd;
    91                 size_t len = 0;
    92                
    93                 // FIXME: cannot do long reads yet
    94                 do {
    95                         rd = read(fd, buf + len, 1024);
    96                         if (rd > 0)
    97                                 len += rd;
    98                        
    99                 } while (rd > 0);
    100                
    101                 if (len > 0) {
    102                         task_spawn(buf, len);
    103                         sleep(1);       // FIXME
    104                 }
    105                
    106                 close(fd);
     84
     85        argv[0] = fname;
     86        argv[1] = NULL;
     87
     88        if (task_spawn(fname, argv) != 0) {
     89                /* Success */
     90                sleep(1);
    10791        }
    10892}
     
    118102        }
    119103       
    120         buf = malloc(BUF_SIZE);
    121        
    122104        // FIXME: spawn("/sbin/pci");
    123105        spawn("/sbin/fb");
     
    130112        spawn("/sbin/fat");
    131113        spawn("/sbin/tetris");
     114        spawn("/sbin/cli");
    132115        // FIXME: spawn("/sbin/tester");
    133116        spawn("/sbin/klog");
    134117       
    135         free(buf);
    136118        return 0;
    137119}
  • uspace/app/tester/tester.c

    rb7f9087 rc98e6ee  
    108108}
    109109
    110 int main(void)
     110int main(int argc, char **argv)
    111111{
     112        printf("Number of arguments: %d\n", argc);
     113        if (argv) {
     114                printf("Arguments:");
     115                while (*argv) {
     116                        printf(" '%s'", *argv++);
     117                }
     118                printf("\n");
     119        }
     120
    112121        while (1) {
    113122                char c;
  • uspace/lib/libc/Makefile

    rb7f9087 rc98e6ee  
    5252        generic/string.c \
    5353        generic/fibril.c \
     54        generic/pcb.c \
     55        generic/smc.c \
    5456        generic/thread.c \
    5557        generic/tls.c \
  • uspace/lib/libc/arch/amd64/src/entry.s

    rb7f9087 rc98e6ee  
    3535## User-space task entry point
    3636#
     37# %rdi contains the PCB pointer
    3738#
    3839__entry:
     40        # %rdi was deliberately chosen as the first argument is also in %rdi
     41        # Pass PCB pointer to __main (no operation)
    3942        call __main
    40         call main
     43
    4144        call __exit
  • uspace/lib/libc/arch/arm32/src/entry.s

    rb7f9087 rc98e6ee  
    3535## User-space task entry point
    3636#
     37# r1 contains the PCB pointer
    3738#
    3839__entry:
     40        # Pass pcb_ptr to __main as the first argument (in r0)
     41        mov r0, r1
    3942        bl __main
    40         bl main
     43
    4144        bl __exit
  • uspace/lib/libc/arch/ia32/src/entry.s

    rb7f9087 rc98e6ee  
    3535## User-space task entry point
    3636#
     37# %ebx contains the PCB pointer
    3738#
    3839__entry:
     
    4243        mov %ax, %fs
    4344        # Do not set %gs, it contains descriptor that can see TLS
    44        
     45
     46        # Pass the PCB pointer to __main as the first argument
     47        pushl %ebx
    4548        call __main
    46         call main
     49
    4750        call __exit
  • uspace/lib/libc/arch/ia64/src/entry.s

    rb7f9087 rc98e6ee  
    3535## User-space task entry point
    3636#
     37# r2 contains the PCB pointer
    3738#
    3839__entry:
    3940        alloc loc0 = ar.pfs, 0, 1, 2, 0
    40         mov r1 = _gp
     41        mov r1 = _gp
     42
     43        # Pass PCB pointer as the first argument to __main
     44        mov out0 = r2
    4145        br.call.sptk.many b0 = __main
    42460:
    43         br.call.sptk.many b0 = main
    44 1:
    4547        br.call.sptk.many b0 = __exit
  • uspace/lib/libc/arch/mips32/src/entry.s

    rb7f9087 rc98e6ee  
    3636## User-space task entry point
    3737#
     38# $a0 ($4) contains the PCB pointer
    3839#
    3940.ent __entry
     
    4142        .frame $sp, 32, $31
    4243        .cpload $25
    43        
    44        
     44
    4545        # Mips o32 may store its arguments on stack, make space (16 bytes),
    4646        # so that it could work with -O0
     
    4949        addiu $sp, -32
    5050        .cprestore 16   # Allow PIC code
    51        
     51
     52        # Pass pcb_ptr to __main() as the first argument. pcb_ptr is already
     53        # in $a0. As the first argument is passed in $a0, no operation
     54        # is needed.
     55
    5256        jal __main
    53         nop
    54        
    55         jal main
    5657        nop
    5758       
  • uspace/lib/libc/arch/ppc32/src/entry.s

    rb7f9087 rc98e6ee  
    3535## User-space task entry point
    3636#
     37# r3 contains the PCB pointer
    3738#
    3839__entry:
     40        # Pass the PCB pointer to __main() as the first argument.
     41        # Since the first argument is passed in r3, no operation is needed.
    3942        bl __main
    40         bl main
     43
    4144        bl __exit
  • uspace/lib/libc/arch/ppc64/src/entry.s

    rb7f9087 rc98e6ee  
    3232
    3333.globl __entry
    34 .globl __entry_driver
    3534
    3635## User-space task entry point
     
    3938__entry:
    4039        bl __main
    41         bl __io_init
    42         bl main
    4340        bl __exit
    44 
    45 __entry_driver:
    46         bl __main
    47         bl main
    48         bl __exit
  • uspace/lib/libc/arch/sparc64/src/entry.s

    rb7f9087 rc98e6ee  
    3535## User-space task entry point
    3636#
     37# %o0 contains uarg
     38# %o1 contains pcb_ptr
    3739#
    3840__entry:
     41        # Pass pcb_ptr as the first argument to __main()
     42        mov %o1, %o0
    3943        sethi %hi(_gp), %l7
    4044        call __main
    4145        or %l7, %lo(_gp), %l7
    42         call main
    43         nop
     46
    4447        call __exit
    4548        nop
  • uspace/lib/libc/generic/as.c

    rb7f9087 rc98e6ee  
    8484{
    8585        return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address);
     86}
     87
     88/** Change address-space area flags.
     89 *
     90 * @param address Virtual address pointing into the address space area being
     91 *      modified.
     92 * @param flags New flags describing type of the area.
     93 *
     94 * @return Zero on success or a code from @ref errno.h on failure.
     95 */
     96int as_area_change_flags(void *address, int flags)
     97{
     98        return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address,
     99            (sysarg_t) flags);
    86100}
    87101
  • uspace/lib/libc/generic/io/stream.c

    rb7f9087 rc98e6ee  
    9797}
    9898
     99void close_console(void)
     100{
     101        if (console_phone >= 0) {
     102                if (ipc_hangup(console_phone) == 0) {
     103                        console_phone = -1;
     104                }
     105        }
     106}
     107
    99108void klog_update(void)
    100109{
  • uspace/lib/libc/generic/libc.c

    rb7f9087 rc98e6ee  
    4949#include <async.h>
    5050#include <as.h>
     51#include <loader/pcb.h>
    5152
    5253extern char _heap;
     54extern int main(int argc, char *argv[]);
    5355
    5456void _exit(int status)
     
    5759}
    5860
    59 void __main(void)
     61void __main(void *pcb_ptr)
    6062{
    6163        fibril_t *f;
     64        int argc;
     65        char **argv;
    6266
    6367        (void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
     
    6771       
    6872        open_console();
     73
     74        /* Save the PCB pointer */
     75        __pcb = (pcb_t *)pcb_ptr;
     76
     77        if (__pcb == NULL) {
     78                argc = 0;
     79                argv = NULL;
     80        } else {
     81                argc = __pcb->argc;
     82                argv = __pcb->argv;
     83        }
     84
     85        main(argc, argv);
    6986}
    7087
  • uspace/lib/libc/generic/task.c

    rb7f9087 rc98e6ee  
    11/*
    22 * Copyright (c) 2006 Jakub Jermar
     3 * Copyright (c) 2008 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3435
    3536#include <task.h>
     37#include <ipc/ipc.h>
     38#include <ipc/loader.h>
    3639#include <libc.h>
     40#include <string.h>
     41#include <stdlib.h>
     42#include <async.h>
     43#include <errno.h>
    3744
    3845task_id_t task_get_id(void)
     
    4552}
    4653
    47 int task_spawn(void *image, size_t size)
     54static int task_spawn_loader(void)
    4855{
    49         return __SYSCALL2(SYS_TASK_SPAWN, (sysarg_t) image, (sysarg_t) size);
     56        int phone_id, rc;
     57
     58        rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
     59        if (rc != 0)
     60                return rc;
     61
     62        return phone_id;
     63}
     64
     65static int loader_set_args(int phone_id, const char *argv[])
     66{
     67        aid_t req;
     68        ipc_call_t answer;
     69        ipcarg_t rc;
     70
     71        const char **ap;
     72        char *dp;
     73        char *arg_buf;
     74        size_t buffer_size;
     75        size_t len;
     76
     77        /*
     78         * Serialize the arguments into a single array. First
     79         * compute size of the buffer needed.
     80         */
     81        ap = argv;
     82        buffer_size = 0;
     83        while (*ap != NULL) {
     84                buffer_size += strlen(*ap) + 1;
     85                ++ap;
     86        }
     87
     88        arg_buf = malloc(buffer_size);
     89        if (arg_buf == NULL) return ENOMEM;
     90
     91        /* Now fill the buffer with null-terminated argument strings */
     92        ap = argv;
     93        dp = arg_buf;
     94        while (*ap != NULL) {
     95                strcpy(dp, *ap);
     96                dp += strlen(*ap) + 1;
     97
     98                ++ap;
     99        }
     100
     101        /* Send serialized arguments to the loader */
     102
     103        req = async_send_0(phone_id, LOADER_SET_ARGS, &answer);
     104        rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size);
     105        if (rc != EOK) {
     106                async_wait_for(req, NULL);
     107                return rc;
     108        }
     109
     110        async_wait_for(req, &rc);
     111        if (rc != EOK) return rc;
     112
     113        /* Free temporary buffer */
     114        free(arg_buf);
     115
     116        return EOK;
     117}
     118
     119/** Create a new task by running an executable from VFS.
     120 *
     121 * @param path  pathname of the binary to execute
     122 * @param argv  command-line arguments
     123 * @return      ID of the newly created task or zero on error.
     124 */
     125task_id_t task_spawn(const char *path, const char *argv[])
     126{
     127        int phone_id;
     128        ipc_call_t answer;
     129        aid_t req;
     130        int rc;
     131        ipcarg_t retval;
     132
     133        /* Spawn a program loader */   
     134        phone_id = task_spawn_loader();
     135        if (phone_id < 0) return 0;
     136
     137        /*
     138         * Say hello so that the loader knows the incoming connection's
     139         * phone hash.
     140         */
     141        rc = async_req_0_0(phone_id, LOADER_HELLO);
     142        if (rc != EOK) return 0;
     143
     144        /* Send program pathname */
     145        req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer);
     146        rc = ipc_data_write_start(phone_id, (void *)path, strlen(path));
     147        if (rc != EOK) {
     148                async_wait_for(req, NULL);
     149                return 1;
     150        }
     151
     152        async_wait_for(req, &retval);
     153        if (retval != EOK) goto error;
     154
     155        /* Send arguments */
     156        rc = loader_set_args(phone_id, argv);
     157        if (rc != EOK) goto error;
     158
     159        /* Request loader to start the program */       
     160        rc = async_req_0_0(phone_id, LOADER_RUN);
     161        if (rc != EOK) goto error;
     162
     163        /* Success */
     164        ipc_hangup(phone_id);
     165        return 1;
     166
     167        /* Error exit */
     168error:
     169        ipc_hangup(phone_id);
     170        return 0;
    50171}
    51172
  • uspace/lib/libc/include/as.h

    rb7f9087 rc98e6ee  
    4343extern void *as_area_create(void *address, size_t size, int flags);
    4444extern int as_area_resize(void *address, size_t size, int flags);
     45extern int as_area_change_flags(void *address, int flags);
    4546extern int as_area_destroy(void *address);
    4647extern void *set_maxheapsize(size_t mhs);
  • uspace/lib/libc/include/io/stream.h

    rb7f9087 rc98e6ee  
    4141
    4242extern void open_console(void);
     43extern void close_console(void);
    4344extern void klog_update(void);
    4445
  • uspace/lib/libc/include/libc.h

    rb7f9087 rc98e6ee  
    4949    __syscall(p1, p2, p3, p4, p5, p6,id)
    5050
    51 extern void __main(void);
     51extern void __main(void *pcb_ptr);
    5252extern void __exit(void);
    5353
  • uspace/lib/libc/include/task.h

    rb7f9087 rc98e6ee  
    4141
    4242extern task_id_t task_get_id(void);
    43 extern int task_spawn(void *image, size_t size);
     43extern task_id_t task_spawn(const char *path, const char *argv[]);
    4444
    4545#endif
Note: See TracChangeset for help on using the changeset viewer.