Beispiel #1
0
/*
   read the next line of the bootmodule, and return info about what to
   spawn in *si
   return:
   1: line read succesfully
   0: end of file reached
   -1: error
*/
static int prepare_spawn(size_t *bmpos, struct spawn_info *si)
{
    assert(bmpos != NULL);
    assert(si != NULL);

    const char *bootmodules = gbootmodules;

    // find the start/end of the next line
    const char *start = &bootmodules[*bmpos];
    const char *end = strchr(start, '\n');
    if (end == NULL) {
        return 0;
    } else {
        *bmpos = end - bootmodules + 1;
    }

    // ignore arguments for name comparison
    const char *args = memchr(start, ' ', end - start);

    // where's the end of the full name?
    const char *nameend = args == NULL ? end : args;

    si->shortname = (char *)get_shortname(start, nameend, &si->shortnamelen);

    si->cmdargs = malloc(end - si->shortname + 1);
    if (si->cmdargs == NULL) {
        return -1;
    }
    si->name = malloc(nameend - start + 1);
    if (si->name == NULL) {
        free(si->cmdargs);
        return -1;
    }

    /* Get the command line arguments of the domain: args plus shortname */
    memcpy(si->cmdargs, si->shortname, end - si->shortname);
    si->cmdargs[end - si->shortname] = '\0';
    si->argc = spawn_tokenize_cmdargs(si->cmdargs, si->argv,
                                      ARRAY_LENGTH(si->argv));
    if (si->argc >= MAX_CMDLINE_ARGS) {
        free(si->cmdargs);
        free(si->name);
        return -1;
    }

    /* grab a copy of the full name as a separate string */
    memcpy(si->name, start, nameend - start);
    si->name[nameend - start] = '\0';

    return 1;
}
Beispiel #2
0
/**
 * \brief Initialize monitor running on bsp core
 */
static errval_t boot_bsp_core(int argc, char *argv[])
{
    errval_t err;

    // First argument contains the bootinfo location
    bi = (struct bootinfo*)strtol(argv[1], NULL, 10);

    bsp_monitor = true;

    err = monitor_client_setup_mem_serv();
    assert(err_is_ok(err));

    /* Wait for mem_serv to advertise its iref to us */
    while (mem_serv_iref == 0) {
        messages_wait_and_handle_next();
    }
    update_ram_alloc_binding = false;

    /* Can now connect to and use mem_serv */
    err = ram_alloc_set(NULL);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_RAM_ALLOC_SET);
    }

    // Export ram_alloc service
    err = mon_ram_alloc_serve();
    assert(err_is_ok(err));

    /* Set up monitor rpc channel */
    err = monitor_rpc_init();
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "monitor rpc init failed");
        return err;
    }

    /* SKB needs vfs for ECLiPSe so we need to start ramfsd first... */
    err = spawn_domain("ramfsd");
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "failed spawning ramfsd");
        return err;
    }
    // XXX: Wait for ramfsd to initialize
    while (ramfs_serv_iref == 0) {
        messages_wait_and_handle_next();
    }

    /* Spawn skb (new nameserver) before other domains */
    err = spawn_domain("skb");
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "failed spawning skb");
        return err;
    }
    // XXX: Wait for name_server to initialize
    while (name_serv_iref == 0) {
        messages_wait_and_handle_next();
    }
#ifdef __k1om__
    char args[40];
    snprintf(args, sizeof(args), "0x%016lx 0x%02x", bi->host_msg,
             bi->host_msg_bits);
    char *mgr_argv[MAX_CMDLINE_ARGS + 1];
    spawn_tokenize_cmdargs(args, mgr_argv, ARRAY_LENGTH(mgr_argv));
    err = spawn_domain_with_args("xeon_phi", mgr_argv,environ);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "failed spawning xeon_phi");
        return err;
    }
#endif

    /* Spawn boot domains in menu.lst */
    err = spawn_all_domains();
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "spawn_all_domains failed");
        return err;
    }

    return SYS_ERR_OK;
}
Beispiel #3
0
/**
 * \brief Spawn a domain and give it the bootinfo struct.
 * Just monitor and memserv should be spawned using this.
 */
errval_t spawn_load_with_bootinfo(struct spawninfo *si, struct bootinfo *bi,
                                  const char *name, coreid_t coreid)
{
    errval_t err;

    /* Get the module from the multiboot */
    struct mem_region *module = multiboot_find_module(bi, name);
    if (module == NULL) {
        return SPAWN_ERR_FIND_MODULE;
    }

    /* Lookup and map the elf image */
    lvaddr_t binary;
    size_t binary_size;
    err = spawn_map_module(module, &binary_size, &binary, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_ELF_MAP);
    }


    /* Determine cpu type */
    err = spawn_determine_cputype(si, binary);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_DETERMINE_CPUTYPE);
    }

    /* Initialize cspace */
    err = spawn_setup_cspace(si);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_SETUP_CSPACE);
    }

    /* Initialize vspace */
    err = spawn_setup_vspace(si);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_VSPACE_INIT);
    }

    /* Load the image */
    genvaddr_t entry;
    void* arch_info;
    si->name = name;
    err = spawn_arch_load(si, binary, binary_size, &entry, &arch_info);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_LOAD);
    }

    /* Setup dispatcher frame */
    err = spawn_setup_dispatcher(si, coreid, name, entry, arch_info);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_SETUP_DISPATCHER);
    }

    /* Map bootinfo */
    // XXX: Confusion address translation about l/gen/addr in entry
    genvaddr_t vaddr;
    err = spawn_map_bootinfo(si, &vaddr);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_MAP_BOOTINFO);
    }

    /* Construct cmdline args, 0 is name, 1 is bootinfo address,
       remaining are from the multiboot */
    // Name
    char args[1024];
    strcpy(args, name);
    strcat(args, " ");

    // bootinfo addr
    char vaddr_char[32];

    // NB format here should be PRIuGENVADDR, but our ARM compiler has
    // an out-by-4 bytes issue when rendering 64-bit numbers using
    // __builtin_va_start/__builtin_va_arg.
    // [ gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67) ]
    snprintf(vaddr_char, sizeof(vaddr_char), "%" PRIuPTR, (uintptr_t)vaddr);

    strcat(args, vaddr_char);
    strcat(args, " ");

#ifdef __scc__
    if(si->codeword == 0xcafebabe) {
        strcat(args, si->append_args);
        strcat(args, " ");
    }

    if(!strcmp(name, "scc/sbin/monitor")) {
        printf("starting monitor as '%s'\n", args);
    }
#endif

    // Multiboot args
    char *multiboot_args;
    err = spawn_get_cmdline_args(module, &multiboot_args);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_GET_CMDLINE_ARGS);
    }
    // Lop off the name
    char *multiboot_args_lop = strchr(multiboot_args, ' ');
    if (multiboot_args_lop) {
        multiboot_args_lop++;
        strcat(args, multiboot_args_lop);
    }

    // Tokenize
    char *argv[MAX_CMDLINE_ARGS + 1];
    spawn_tokenize_cmdargs(args, argv, ARRAY_LENGTH(argv));

    // Setup
    err = spawn_setup_env(si, argv, environ);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_SETUP_ENV);
    }
    free(multiboot_args);

    // unmap bootinfo module pages
    spawn_unmap_module(binary);

    return SYS_ERR_OK;
}