123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886 |
- /*
- * Mach Operating System
- * Copyright (c) 1992-1989 Carnegie Mellon University.
- * Copyright (c) 1995-1993 The University of Utah and
- * the Computer Systems Laboratory (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
- * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
- * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
- * THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
- /*
- * Bootstrap the various built-in servers.
- */
- #include <alloca.h>
- #include <string.h>
- #include <mach/port.h>
- #include <mach/message.h>
- #include <machine/locore.h>
- #include <machine/vm_param.h>
- #include <machine/pcb.h>
- #include <ipc/ipc_port.h>
- #include <ipc/mach_port.h>
- #include <kern/debug.h>
- #include <kern/host.h>
- #include <kern/printf.h>
- #include <kern/kalloc.h>
- #include <kern/task.h>
- #include <kern/thread.h>
- #include <kern/lock.h>
- #include <vm/vm_kern.h>
- #include <vm/vm_user.h>
- #include <vm/pmap.h>
- #include <device/device_port.h>
- #if MACH_KDB
- #include <machine/db_machdep.h>
- #include <ddb/db_sym.h>
- #endif
- #if OSKIT_MACH
- #include <stddef.h>
- #include <oskit/machine/base_multiboot.h>
- #include <oskit/exec/exec.h>
- #include <oskit/c/stdio.h>
- #define safe_gets(s, n) fgets((s),(n),stdin)
- #else
- #include <mach/machine/multiboot.h>
- #include <mach/exec/exec.h>
- #ifdef MACH_XEN
- #include <mach/xen.h>
- extern struct start_info boot_info; /* XXX put this in a header! */
- #else /* MACH_XEN */
- extern struct multiboot_info boot_info; /* XXX put this in a header! */
- #endif /* MACH_XEN */
- #endif
- #include "boot_script.h"
- static mach_port_t boot_device_port; /* local name */
- static mach_port_t boot_host_port; /* local name */
- extern char *kernel_cmdline;
- static void user_bootstrap(void); /* forward */
- static void user_bootstrap_compat(void); /* forward */
- static void bootstrap_exec_compat(void *exec_data); /* forward */
- static void get_compat_strings(char *flags_str, char *root_str); /* forward */
- static mach_port_t
- task_insert_send_right(
- task_t task,
- ipc_port_t port)
- {
- mach_port_t name;
- for (name = 1;; name++) {
- kern_return_t kr;
- kr = mach_port_insert_right(task->itk_space, name,
- port, MACH_MSG_TYPE_PORT_SEND);
- if (kr == KERN_SUCCESS)
- break;
- assert(kr == KERN_NAME_EXISTS);
- }
- return name;
- }
- static void
- free_bootstrap_pages(phys_addr_t start, phys_addr_t end)
- {
- struct vm_page *page;
- while (start < end)
- {
- page = vm_page_lookup_pa(start);
- assert(page != NULL);
- vm_page_manage(page);
- start += PAGE_SIZE;
- }
- }
- void bootstrap_create(void)
- {
- int compat;
- unsigned 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
- {
- unsigned i;
- int 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-task", VAL_PORT,
- (long) kernel_task->itk_self);
- if (losers)
- panic ("cannot set boot-script variable kernel-task: %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++)
- free_bootstrap_pages(bmods[n].mod_start, bmods[n].mod_end);
- }
- static void
- bootstrap_exec_compat(void *e)
- {
- task_t bootstrap_task;
- thread_t bootstrap_thread;
- /*
- * Create the bootstrap task.
- */
- (void) task_create(TASK_NULL, FALSE, &bootstrap_task);
- (void) thread_create(bootstrap_task, &bootstrap_thread);
- /*
- * Insert send rights to the master host and device ports.
- */
- boot_host_port =
- task_insert_send_right(bootstrap_task,
- ipc_port_make_send(realhost.host_priv_self));
- boot_device_port =
- task_insert_send_right(bootstrap_task,
- ipc_port_make_send(master_device_port));
- /*
- * Start the bootstrap thread.
- */
- bootstrap_thread->saved.other = e;
- thread_start(bootstrap_thread, user_bootstrap_compat);
- (void) thread_resume(bootstrap_thread);
- }
- /*
- * The following code runs as the kernel mode portion of the
- * first user thread.
- */
- /*
- * Convert an unsigned integer to its decimal representation.
- */
- static void
- itoa(
- char *str,
- vm_size_t num)
- {
- char buf[sizeof(vm_size_t)*2+3];
- char *np;
- np = buf + sizeof(buf);
- *--np = 0;
- do {
- *--np = '0' + num % 10;
- num /= 10;
- } while (num != 0);
- strcpy(str, np);
- }
- /*
- * Collect the boot flags into a single argument string,
- * for compatibility with existing bootstrap and startup code.
- * Format as a standard flag argument: '-qsdn...'
- */
- static void get_compat_strings(char *flags_str, char *root_str)
- {
- char *ip, *cp;
- strcpy (root_str, "UNKNOWN");
- cp = flags_str;
- *cp++ = '-';
- for (ip = kernel_cmdline; *ip; )
- {
- if (*ip == ' ')
- {
- ip++;
- }
- else if (*ip == '-')
- {
- ip++;
- while (*ip > ' ')
- *cp++ = *ip++;
- }
- else if (strncmp(ip, "root=", 5) == 0)
- {
- char *rp = root_str;
- ip += 5;
- if (strncmp(ip, "/dev/", 5) == 0)
- ip += 5;
- while (*ip > ' ')
- *rp++ = *ip++;
- *rp = '\0';
- }
- else
- {
- while (*ip > ' ')
- ip++;
- }
- }
- if (cp == &flags_str[1]) /* no flags */
- *cp++ = 'x';
- *cp = '\0';
- }
- #if 0
- /*
- * Copy boot_data (executable) to the user portion of this task.
- */
- static boolean_t load_protect_text = TRUE;
- #if MACH_KDB
- /* if set, fault in the text segment */
- static boolean_t load_fault_in_text = TRUE;
- #endif
- static vm_offset_t
- boot_map(
- void * data, /* private data */
- vm_offset_t offset) /* offset to map */
- {
- vm_offset_t start_offset = (vm_offset_t) data;
- return pmap_extract(kernel_pmap, start_offset + offset);
- }
- #if BOOTSTRAP_SYMBOLS
- static boolean_t load_bootstrap_symbols = TRUE;
- #else
- static boolean_t load_bootstrap_symbols = FALSE;
- #endif
- #endif
- static int
- boot_read(void *handle, vm_offset_t file_ofs, void *buf, vm_size_t size,
- vm_size_t *out_actual)
- {
- struct multiboot_module *mod = handle;
- if (mod->mod_start + file_ofs + size > mod->mod_end)
- return -1;
- memcpy(buf, (const char*) phystokv (mod->mod_start) + file_ofs, size);
- *out_actual = size;
- return 0;
- }
- static int
- read_exec(void *handle, vm_offset_t file_ofs, vm_size_t file_size,
- vm_offset_t mem_addr, vm_size_t mem_size,
- exec_sectype_t sec_type)
- {
- struct multiboot_module *mod = handle;
- vm_map_t user_map = current_task()->map;
- vm_offset_t start_page, end_page;
- vm_prot_t mem_prot = sec_type & EXEC_SECTYPE_PROT_MASK;
- int err;
- if (mod->mod_start + file_ofs + file_size > mod->mod_end)
- return -1;
- if (!(sec_type & EXEC_SECTYPE_ALLOC))
- return 0;
- assert(mem_size > 0);
- assert(mem_size >= file_size);
- start_page = trunc_page(mem_addr);
- end_page = round_page(mem_addr + mem_size);
- #if 0
- printf("reading bootstrap section %08x-%08x-%08x prot %d pages %08x-%08x\n",
- mem_addr, mem_addr+file_size, mem_addr+mem_size, mem_prot, start_page, end_page);
- #endif
- err = vm_allocate(user_map, &start_page, end_page - start_page, FALSE);
- assert(err == 0);
- assert(start_page == trunc_page(mem_addr));
- if (file_size > 0)
- {
- err = copyout((char *)phystokv (mod->mod_start) + file_ofs,
- (void *)mem_addr, file_size);
- assert(err == 0);
- }
- if (mem_prot != VM_PROT_ALL)
- {
- err = vm_protect(user_map, start_page, end_page - start_page, FALSE, mem_prot);
- assert(err == 0);
- }
- return 0;
- }
- static void copy_bootstrap(void *e, exec_info_t *boot_exec_info)
- {
- /* vm_map_t user_map = current_task()->map; */
- int err;
- if ((err = exec_load(boot_read, read_exec, e, boot_exec_info)))
- panic("Cannot load user-bootstrap image: error code %d", err);
- #if MACH_KDB
- /*
- * Enter the bootstrap symbol table.
- */
- #if 0 /*XXX*/
- if (load_bootstrap_symbols)
- (void) X_db_sym_init(
- (char*) boot_start+lp->sym_offset,
- (char*) boot_start+lp->sym_offset+lp->sym_size,
- "bootstrap",
- (char *) user_map);
- #endif
- #if 0 /*XXX*/
- if (load_fault_in_text)
- {
- vm_offset_t lenp = round_page(lp->text_start+lp->text_size) -
- trunc_page(lp->text_start);
- vm_offset_t i = 0;
- while (i < lenp)
- {
- vm_fault(user_map, text_page_start +i,
- load_protect_text ?
- VM_PROT_READ|VM_PROT_EXECUTE :
- VM_PROT_READ|VM_PROT_EXECUTE | VM_PROT_WRITE,
- 0,0,0);
- i = round_page (i+1);
- }
- }
- #endif
- #endif /* MACH_KDB */
- }
- /*
- * Allocate the stack, and build the argument list.
- */
- static void
- build_args_and_stack(struct exec_info *boot_exec_info,
- char **argv, char **envp)
- {
- vm_offset_t stack_base;
- vm_size_t stack_size;
- char * arg_ptr;
- int arg_count, envc;
- int arg_len;
- char * arg_pos;
- int arg_item_len;
- char * string_pos;
- char * zero = (char *)0;
- int i;
- #define STACK_SIZE (64*1024)
- /*
- * Calculate the size of the argument list.
- */
- arg_len = 0;
- arg_count = 0;
- while (argv[arg_count] != 0) {
- arg_ptr = argv[arg_count++];
- arg_len += strlen(arg_ptr) + 1;
- }
- envc = 0;
- if (envp != 0)
- while (envp[envc] != 0)
- arg_len += strlen (envp[envc++]) + 1;
- /*
- * Add space for:
- * arg count
- * pointers to arguments
- * trailing 0 pointer
- * pointers to environment variables
- * trailing 0 pointer
- * and align to integer boundary
- */
- arg_len += (sizeof(integer_t)
- + (arg_count + 1 + envc + 1) * sizeof(char *));
- arg_len = (arg_len + sizeof(integer_t) - 1) & ~(sizeof(integer_t)-1);
- /*
- * Allocate the stack.
- */
- stack_size = round_page(STACK_SIZE);
- stack_base = user_stack_low(stack_size);
- (void) vm_allocate(current_task()->map,
- &stack_base,
- stack_size,
- FALSE);
- arg_pos = (char *)
- set_user_regs(stack_base, stack_size, boot_exec_info, arg_len);
- /*
- * Start the strings after the arg-count and pointers
- */
- string_pos = (arg_pos
- + sizeof(integer_t)
- + (arg_count + 1 + envc + 1) * sizeof(char *));
- /*
- * first the argument count
- */
- (void) copyout(&arg_count,
- arg_pos,
- sizeof(integer_t));
- arg_pos += sizeof(integer_t);
- /*
- * Then the strings and string pointers for each argument
- */
- for (i = 0; i < arg_count; ++i) {
- arg_ptr = argv[i];
- arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
- /* set string pointer */
- (void) copyout(&string_pos,
- arg_pos,
- sizeof (char *));
- arg_pos += sizeof(char *);
- /* copy string */
- (void) copyout(arg_ptr, string_pos, arg_item_len);
- string_pos += arg_item_len;
- }
- /*
- * Null terminator for argv.
- */
- (void) copyout(&zero, arg_pos, sizeof(char *));
- arg_pos += sizeof(char *);
- /*
- * Then the strings and string pointers for each environment variable
- */
- for (i = 0; i < envc; ++i) {
- arg_ptr = envp[i];
- arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
- /* set string pointer */
- (void) copyout(&string_pos,
- arg_pos,
- sizeof (char *));
- arg_pos += sizeof(char *);
- /* copy string */
- (void) copyout(arg_ptr, string_pos, arg_item_len);
- string_pos += arg_item_len;
- }
- /*
- * Null terminator for envp.
- */
- (void) copyout(&zero, arg_pos, sizeof(char *));
- }
- 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*/
- }
- struct user_bootstrap_info
- {
- struct multiboot_module *mod;
- char **argv;
- int done;
- decl_simple_lock_data(,lock)
- };
- int
- boot_script_exec_cmd (void *hook, task_t task, char *path, int argc,
- char **argv, char *strings, int stringlen)
- {
- struct multiboot_module *mod = hook;
- int err;
- if (task != MACH_PORT_NULL)
- {
- thread_t thread;
- struct user_bootstrap_info info = { mod, argv, 0, };
- simple_lock_init (&info.lock);
- err = thread_create ((task_t)task, &thread);
- assert(err == 0);
- simple_lock (&info.lock);
- thread->saved.other = &info;
- thread_start (thread, user_bootstrap);
- err = thread_resume (thread);
- assert(err == 0);
- /* We need to synchronize with the new thread and block this
- main thread until it has finished referring to our local state. */
- while (! info.done)
- {
- thread_sleep ((event_t) &info, simple_lock_addr(info.lock), FALSE);
- simple_lock (&info.lock);
- }
- simple_unlock (&info.lock);
- thread_deallocate (thread);
- printf ("\n");
- }
- return 0;
- }
- static void user_bootstrap(void)
- {
- struct user_bootstrap_info *info = current_thread()->saved.other;
- exec_info_t boot_exec_info;
- int err;
- char **av;
- /* Load this task up from the executable file in the module. */
- err = exec_load(boot_read, read_exec, info->mod, &boot_exec_info);
- if (err)
- panic ("Cannot load user executable module (error code %d): %s",
- err, info->argv[0]);
- printf ("task loaded:");
- /* Set up the stack with arguments. */
- build_args_and_stack(&boot_exec_info, info->argv, 0);
- for (av = info->argv; *av != 0; ++av)
- printf (" %s", *av);
- task_suspend (current_task());
- /* Tell the bootstrap thread running boot_script_exec_cmd
- that we are done looking at INFO. */
- simple_lock (&info->lock);
- assert (!info->done);
- info->done = 1;
- simple_unlock (&info->lock);
- thread_wakeup ((event_t) info);
- /*
- * Exit to user thread.
- */
- thread_bootstrap_return();
- /*NOTREACHED*/
- }
- void *
- boot_script_malloc (unsigned int size)
- {
- return (void *) kalloc (size);
- }
- void
- boot_script_free (void *ptr, unsigned int size)
- {
- kfree ((vm_offset_t)ptr, size);
- }
- int
- boot_script_task_create (struct cmd *cmd)
- {
- kern_return_t rc = task_create_kernel(TASK_NULL, FALSE, &cmd->task);
- if (rc)
- {
- printf("boot_script_task_create failed with %x\n", rc);
- return BOOT_SCRIPT_MACH_ERROR;
- }
- task_set_name(cmd->task, cmd->path);
- return 0;
- }
- int
- boot_script_task_resume (struct cmd *cmd)
- {
- kern_return_t rc = task_resume (cmd->task);
- if (rc)
- {
- printf("boot_script_task_resume failed with %x\n", rc);
- return BOOT_SCRIPT_MACH_ERROR;
- }
- printf ("\nstart %s: ", cmd->path);
- return 0;
- }
- int
- boot_script_prompt_task_resume (struct cmd *cmd)
- {
- #if ! MACH_KDB
- char xx[5];
- #endif
- printf ("Pausing for %s...\n", cmd->path);
- #if ! MACH_KDB
- printf ("Hit <return> to resume bootstrap.");
- safe_gets (xx, sizeof xx);
- #else
- SoftDebugger("Hit `c<return>' to resume bootstrap.");
- #endif
- return boot_script_task_resume (cmd);
- }
- void
- boot_script_free_task (task_t task, int aborting)
- {
- if (aborting)
- task_terminate (task);
- task_deallocate (task);
- }
- int
- boot_script_insert_right (struct cmd *cmd, mach_port_t port, mach_port_t *name)
- {
- *name = task_insert_send_right (cmd->task,
- ipc_port_make_send((ipc_port_t) port));
- return 0;
- }
- int
- boot_script_insert_task_port (struct cmd *cmd, task_t task, mach_port_t *name)
- {
- *name = task_insert_send_right (cmd->task, task->itk_sself);
- return 0;
- }
|