static void user_bootstrap_compat(void) { exec_info_t boot_exec_info; char host_string[12]; char device_string[12]; char flag_string[1024]; char root_string[1024]; /* * Copy the bootstrap code from boot_exec into the user task. */ copy_bootstrap(current_thread()->saved.other, &boot_exec_info); /* * Convert the host and device ports to strings, * to put in the argument list. */ itoa(host_string, boot_host_port); itoa(device_string, boot_device_port); /* * Get the (compatibility) boot flags and root name strings. */ get_compat_strings(flag_string, root_string); /* * Build the argument list and insert in the user task. * Argument list is * "bootstrap -<boothowto> <host_port> <device_port> <root_name>" $0 ${boot-args} ${host-port} ${device-port} ${root-device} $(task-create) $(task-resume) */ { char *argv[] = { "bootstrap", flag_string, host_string, device_string, root_string, 0 }; char *envp[] = { 0, 0 }; if (kernel_cmdline[0] != '\0') { static const char cmdline_var[] = "MULTIBOOT_CMDLINE="; envp[0] = alloca (sizeof cmdline_var + strlen (kernel_cmdline)); memcpy (envp[0], cmdline_var, sizeof cmdline_var - 1); strcpy (envp[0] + sizeof cmdline_var - 1, kernel_cmdline); } build_args_and_stack(&boot_exec_info, argv, envp); } /* * Exit to user thread. */ thread_bootstrap_return(); /*NOTREACHED*/ }
static void user_bootstrap() { struct exec_info boot_exec_info; char host_string[12]; char device_string[12]; char flag_string[12]; char root_string[12]; /* * Copy the bootstrap code from boot_exec into the user task. */ copy_bootstrap(boot_exec, &boot_exec_info); /* * Convert the host and device ports to strings, * to put in the argument list. */ itoa(host_string, boot_host_port); itoa(device_string, boot_device_port); /* * Get the (compatibility) boot flags and root name strings. */ get_compat_strings(flag_string, root_string); /* * Build the argument list and insert in the user task. * Argument list is * "bootstrap -<boothowto> <host_port> <device_port> <root_name>" */ build_args_and_stack(&boot_exec_info, "bootstrap", flag_string, host_string, device_string, root_string, (char *)0); printf("Starting bootstrap at %x\n", boot_exec_info.entry); /* * Exit to user thread. */ thread_bootstrap_return(); /*NOTREACHED*/ }
void bootstrap_create(void) { int compat; int n = 0; #ifdef MACH_XEN struct multiboot_module *bmods = ((struct multiboot_module *) boot_info.mod_start); if (bmods) for (n = 0; bmods[n].mod_start; n++) { bmods[n].mod_start = kvtophys(bmods[n].mod_start + (vm_offset_t) bmods); bmods[n].mod_end = kvtophys(bmods[n].mod_end + (vm_offset_t) bmods); bmods[n].string = kvtophys(bmods[n].string + (vm_offset_t) bmods); } boot_info.mods_count = n; boot_info.flags |= MULTIBOOT_MODS; #else /* MACH_XEN */ struct multiboot_module *bmods = ((struct multiboot_module *) phystokv(boot_info.mods_addr)); #endif /* MACH_XEN */ if (!(boot_info.flags & MULTIBOOT_MODS) || (boot_info.mods_count == 0)) panic ("No bootstrap code loaded with the kernel!"); compat = boot_info.mods_count == 1; if (compat) { char *p = strchr((char*)phystokv(bmods[0].string), ' '); if (p != 0) do ++p; while (*p == ' ' || *p == '\n'); compat = p == 0 || *p == '\0'; } if (compat) { printf("Loading single multiboot module in compat mode: %s\n", (char*)phystokv(bmods[0].string)); bootstrap_exec_compat(&bmods[0]); } else { int i, losers; /* Initialize boot script variables. We leak these send rights. */ losers = boot_script_set_variable ("host-port", VAL_PORT, (long) realhost.host_priv_self); if (losers) panic ("cannot set boot-script variable host-port: %s", boot_script_error_string (losers)); losers = boot_script_set_variable ("device-port", VAL_PORT, (long) master_device_port); if (losers) panic ("cannot set boot-script variable device-port: %s", boot_script_error_string (losers)); losers = boot_script_set_variable ("kernel-command-line", VAL_STR, (long) kernel_cmdline); if (losers) panic ("cannot set boot-script variable %s: %s", "kernel-command-line", boot_script_error_string (losers)); { /* Set the same boot script variables that the old Hurd's serverboot did, so an old Hurd and boot script previously used with serverboot can be used directly with this kernel. */ char *flag_string = alloca(1024); char *root_string = alloca(1024); /* * Get the (compatibility) boot flags and root name strings. */ get_compat_strings(flag_string, root_string); losers = boot_script_set_variable ("boot-args", VAL_STR, (long) flag_string); if (losers) panic ("cannot set boot-script variable %s: %s", "boot-args", boot_script_error_string (losers)); losers = boot_script_set_variable ("root-device", VAL_STR, (long) root_string); if (losers) panic ("cannot set boot-script variable %s: %s", "root-device", boot_script_error_string (losers)); } #if OSKIT_MACH { /* The oskit's "environ" array contains all the words from the multiboot command line that looked like VAR=VAL. We set each of these as boot-script variables, which can be used for things like ${root}. */ extern char **environ; char **ep; for (ep = environ; *ep != 0; ++ep) { size_t len = strlen (*ep) + 1; char *var = memcpy (alloca (len), *ep, len); char *val = strchr (var, '='); *val++ = '\0'; losers = boot_script_set_variable (var, VAL_STR, (long) val); if (losers) panic ("cannot set boot-script variable %s: %s", var, boot_script_error_string (losers)); } } #else /* GNUmach, not oskit-mach */ { /* Turn each `FOO=BAR' word in the command line into a boot script variable ${FOO} with value BAR. This matches what we get from oskit's environ in the oskit-mach case (above). */ int len = strlen (kernel_cmdline) + 1; char *s = memcpy (alloca (len), kernel_cmdline, len); char *word; while ((word = strsep (&s, " \t")) != 0) { char *eq = strchr (word, '='); if (eq == 0) continue; *eq++ = '\0'; losers = boot_script_set_variable (word, VAL_STR, (long) eq); if (losers) panic ("cannot set boot-script variable %s: %s", word, boot_script_error_string (losers)); } } #endif for (i = 0; i < boot_info.mods_count; ++i) { int err; char *line = (char*)phystokv(bmods[i].string); printf ("module %d: %s\n", i, line); err = boot_script_parse_line (&bmods[i], line); if (err) { printf ("\n\tERROR: %s", boot_script_error_string (err)); ++losers; } } printf ("%d multiboot modules\n", i); if (losers) panic ("%d of %d boot script commands could not be parsed", losers, boot_info.mods_count); losers = boot_script_exec (); if (losers) panic ("ERROR in executing boot script: %s", boot_script_error_string (losers)); } /* XXX we could free the memory used by the boot loader's descriptors and such. */ for (n = 0; n < boot_info.mods_count; n++) vm_page_create(bmods[n].mod_start, bmods[n].mod_end); }