The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/bootstrap.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1993-1989 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        bootstrap.c,v $
   29  * Revision 2.32  93/11/17  17:07:06  dbg
   30  *      Removed lint.  Converted to stdarg.
   31  *      [93/09/30            dbg]
   32  * 
   33  * Revision 2.31  93/03/26  17:54:41  mrt
   34  *      Changed boot_map to be palatable to vm_object_page_map().
   35  *      ANSIfied (except for varargs functions).
   36  *      [93/03/23            af]
   37  * 
   38  * Revision 2.30  93/03/09  12:26:38  danner
   39  *      String protos.
   40  *      [93/03/07            af]
   41  * 
   42  * Revision 2.29  93/02/05  07:51:14  danner
   43  *      Alpha like mips, has machdep init flags.
   44  *      [93/02/04  01:56:09  af]
   45  * 
   46  *      64bit cleanup.  Added a magic number to the boot label.
   47  *      Changed ovbcopy_ints to be quicker where it can.
   48  *      [92/11/30            af]
   49  * 
   50  * Revision 2.28  92/08/03  17:36:37  jfriedl
   51  *      removed silly prototypes
   52  *      [92/08/02            jfriedl]
   53  * 
   54  * Revision 2.27  92/05/21  17:12:55  jfriedl
   55  *      Removed unused variable 'port' from bootstrap_create().
   56  *      Cleanup to quiet gcc warnings.
   57  *      [92/05/16            jfriedl]
   58  * 
   59  * Revision 2.26  92/05/04  11:26:09  danner
   60  *      Set load_bootstrap_symbols from bootstrap_symbols option file. 
   61  *      [92/05/03            danner]
   62  * 
   63  * Revision 2.25  92/04/01  19:33:06  rpd
   64  *      Fixed ovbcopy_ints to handle zero size.
   65  *      [92/03/13            rpd]
   66  * 
   67  * Revision 2.24  92/02/26  13:12:51  elf
   68  *      Added protect in copy_bootstrap against zero size bss. 
   69  *      [92/02/26            danner]
   70  * 
   71  * Revision 2.23  92/02/19  16:46:30  elf
   72  *      Change -a switch into -q switch.
   73  *      Do not load the default-pager's symtable by default,
   74  *      it gets in the way of debugging UX.
   75  *      [92/02/10  17:50:23  af]
   76  * 
   77  * Revision 2.22  92/02/18  18:00:12  elf
   78  *      Added global load_fault_in_text to force the faulting in of the
   79  *      bootstrap task text. Useful for debugging.
   80  *      [92/02/14            danner]
   81  * 
   82  * Revision 2.21  92/01/03  20:13:43  dbg
   83  *      Move bootstrap code out to user space.
   84  *      Mac2 and iPSC-dependent code must be moved there also.
   85  *      [91/12/18            dbg]
   86  * 
   87  * Revision 2.20  91/12/10  16:32:40  jsb
   88  *      Fixes from Intel
   89  *      [91/12/10  15:51:50  jsb]
   90  * 
   91  * Revision 2.19  91/11/12  11:51:53  rvb
   92  *      Added task_insert_send_right.
   93  *      Changed BOOTSTRAP_MAP_SIZE to 4 meg.
   94  *      [91/11/12            rpd]
   95  * 
   96  * Revision 2.18  91/09/12  16:37:49  bohman
   97  *      Made bootstrap task call mac2 machine dependent code before running
   98  *      'startup', which is loaded from the UX file system.  This needs to
   99  *      be handled more generally in the future.
  100  *      [91/09/11  17:07:59  bohman]
  101  * 
  102  * Revision 2.17  91/08/28  11:14:22  jsb
  103  *      Changed msgh_kind to msgh_seqno.
  104  *      [91/08/10            rpd]
  105  * 
  106  * Revision 2.16  91/08/03  18:18:45  jsb
  107  *      Moved bootstrap query earlier. Removed all NORMA specific code.
  108  *      [91/07/25  18:25:35  jsb]
  109  * 
  110  * Revision 2.15  91/07/31  17:44:14  dbg
  111  *      Pass host port to boot_load_program and read_emulator_symbols.
  112  *      [91/07/30  17:02:40  dbg]
  113  * 
  114  * Revision 2.14  91/07/01  08:24:54  jsb
  115  *      Removed notion of master/slave. Instead, refuse to start up
  116  *      a bootstrap task whenever startup_name is null.
  117  *      [91/06/29  16:48:14  jsb]
  118  * 
  119  * Revision 2.13  91/06/19  11:55:57  rvb
  120  *      Ask for startup program to override default.
  121  *      [91/06/18  21:39:17  rvb]
  122  * 
  123  * Revision 2.12  91/06/17  15:46:51  jsb
  124  *      Renamed NORMA conditionals.
  125  *      [91/06/17  10:49:04  jsb]
  126  * 
  127  * Revision 2.11  91/06/06  17:06:53  jsb
  128  *      Allow slaves to act as masters (for now).
  129  *      [91/05/13  17:36:17  jsb]
  130  * 
  131  * Revision 2.10  91/05/18  14:31:32  rpd
  132  *      Added argument to kernel_thread.
  133  *      [91/04/03            rpd]
  134  * 
  135  * Revision 2.9  91/05/14  16:40:06  mrt
  136  *      Correcting copyright
  137  * 
  138  * Revision 2.8  91/02/05  17:25:42  mrt
  139  *      Changed to new Mach copyright
  140  *      [91/02/01  16:11:22  mrt]
  141  * 
  142  * Revision 2.7  90/12/14  11:01:58  jsb
  143  *      Changes to NORMA_BOOT support. Use real device port, not a proxy;
  144  *      new device forwarding code handles forwarding of requests.
  145  *      Have slave not bother starting bootstrap task if there is nothing
  146  *      for it to run.
  147  *      [90/12/13  21:37:57  jsb]
  148  * 
  149  * Revision 2.6  90/09/28  16:55:30  jsb
  150  *      Added NORMA_BOOT support.
  151  *      [90/09/28  14:04:43  jsb]
  152  * 
  153  * Revision 2.5  90/06/02  14:53:39  rpd
  154  *      Load emulator symbols.
  155  *      [90/05/11  16:58:37  rpd]
  156  * 
  157  *      Made bootstrap_task available externally.
  158  *      [90/04/05            rpd]
  159  *      Converted to new IPC.
  160  *      [90/03/26  22:03:39  rpd]
  161  * 
  162  * Revision 2.4  90/01/11  11:43:02  dbg
  163  *      Initialize bootstrap print routines.  Remove port number
  164  *      printout.
  165  *      [89/12/20            dbg]
  166  * 
  167  * Revision 2.3  89/11/29  14:09:01  af
  168  *      Enlarged the bootstrap task's map to accomodate some unnamed
  169  *      greedy RISC box.  Sigh.
  170  *      [89/11/07            af]
  171  *      Made root_name and startup_name non-preallocated, so that
  172  *      they can be changed at boot time on those machines like
  173  *      mips and Sun where the boot loader passes command line
  174  *      arguments to the kernel.
  175  *      [89/10/28            af]
  176  * 
  177  * Revision 2.2  89/09/08  11:25:02  dbg
  178  *      Pass root partition name to default_pager_setup.
  179  *      [89/08/31            dbg]
  180  * 
  181  *      Assume that device service has already been created.
  182  *      Create bootstrap task here and give it the host and
  183  *      device ports.
  184  *      [89/08/01            dbg]
  185  * 
  186  *      Call default_pager_setup.
  187  *      [89/07/11            dbg]
  188  * 
  189  * 12-Apr-89  David Golub (dbg) at Carnegie-Mellon University
  190  *      Removed console_port.
  191  *
  192  */
  193 /*
  194  * Bootstrap the various built-in servers.
  195  */
  196 #include <mach_kdb.h>
  197 #include <bootstrap_symbols.h>
  198 
  199 #include <mach/port.h>
  200 #include <mach/message.h>
  201 #include <mach/vm_param.h>
  202 #include <ipc/ipc_port.h>
  203 #include <kern/host.h>
  204 #include <kern/kern_io.h>
  205 #include <kern/memory.h>
  206 #include <kern/strings.h>
  207 #include <kern/task.h>
  208 #include <kern/thread.h>
  209 #include <vm/vm_kern.h>
  210 #include <vm/vm_user.h>
  211 #include <vm/vm_fault.h>
  212 #include <device/device_port.h>
  213 
  214 #include <sys/stdarg.h>
  215 
  216 #include <mach/boot_info.h>
  217 
  218 #if     MACH_KDB
  219 #include <machine/db_machdep.h>
  220 #include <ddb/db_sym.h>
  221 #endif
  222 
  223 /*
  224  *      Bootstrap image is moved out of BSS at startup.
  225  */
  226 
  227 vm_offset_t     boot_start = 0;         /* pointer to bootstrap image */
  228 vm_size_t       boot_size = 0;          /* size of bootstrap image */
  229 vm_offset_t     load_info_start = 0;    /* pointer to bootstrap load info */
  230 vm_size_t       load_info_size = 0;     /* size of bootstrap load info */
  231 vm_offset_t     kern_sym_start = 0;     /* pointer to kernel symbols */
  232 vm_size_t       kern_sym_size = 0;      /* size of kernel symbols */
  233 
  234 #if     DEBUG
  235 void load_info_print(void)
  236 {
  237         struct loader_info *lp = (struct loader_info *)load_info_start;
  238 
  239         printf("Load info: text (%#x, %#x, %#x)\n",
  240                 lp->text_start, lp->text_size, lp->text_offset);
  241         printf("           data (%#x, %#x, %#x)\n",
  242                 lp->data_start, lp->data_size, lp->data_offset);
  243         printf("           bss  (%#x)\n", lp->bss_size);
  244         printf("           syms (%#x, %#x)\n",
  245                 lp->sym_offset, lp->sym_size);
  246         printf("           entry(%#x, %#x)\n",
  247                 lp->entry_1, lp->entry_2);
  248 }
  249 #endif
  250 
  251 /*
  252  *      Moves kernel symbol table, bootstrap image, and bootstrap
  253  *      load information out of BSS at startup.  Returns the
  254  *      first unused address.
  255  *
  256  *      PAGE_SIZE must be set.
  257  *
  258  *      On some machines, this code must run before the page
  259  *      tables are set up, and therefore must be re-created
  260  *      in assembly language.
  261  */
  262 
  263 void
  264 ovbcopy_ints(
  265         vm_offset_t src,
  266         vm_offset_t dst,
  267         vm_size_t   size)
  268 {
  269         register vm_size_t *srcp;
  270         register vm_size_t *dstp;
  271         register unsigned int count;
  272 
  273         srcp = (vm_size_t *)(src + size);
  274         dstp = (vm_size_t *)(dst + size);
  275         count = size / sizeof(vm_size_t);
  276 
  277         while (count-- != 0)
  278             *--dstp = *--srcp;
  279 }
  280 
  281 extern char     edata[];        /* start of BSS */
  282 extern char     end[];          /* end of BSS */
  283 
  284 vm_offset_t
  285 move_bootstrap(void)
  286 {
  287         register struct boot_info *bi = (struct boot_info *)edata;
  288 
  289         /*
  290          * Tolerate some "imprecision" in a certain linker
  291          */
  292         if (bi->magic_number != MACH_BOOT_INFO_MAGIC) {
  293                 register vm_size_t      *addr, *erange;
  294 
  295                 addr   = (vm_size_t *)edata;
  296                 erange = (vm_size_t *)(edata + PAGE_SIZE);
  297                 while (addr < erange) {
  298                         bi = (struct boot_info *) ++addr;
  299                         if (bi->magic_number == MACH_BOOT_INFO_MAGIC)
  300                                 break;
  301                 }
  302                 if (bi->magic_number != MACH_BOOT_INFO_MAGIC)
  303                         return 0;       /* good luck.. */
  304         }
  305 
  306         kern_sym_start = (vm_offset_t) end;
  307         kern_sym_size  = bi->sym_size;
  308         /*
  309          * Align start of bootstrap on page boundary,
  310          * to allow mapping into user space.
  311          */
  312         boot_start = round_page(kern_sym_start + kern_sym_size);
  313         boot_size  = bi->boot_size;
  314         load_info_start = boot_start + boot_size;
  315         load_info_size  = bi->load_info_size;
  316 
  317         ovbcopy_ints((vm_offset_t)bi + sizeof(struct boot_info) + kern_sym_size,
  318                      boot_start,
  319                      boot_size + load_info_size);
  320 
  321         ovbcopy_ints((vm_offset_t)bi + sizeof(struct boot_info),
  322                      kern_sym_start,
  323                      kern_sym_size);
  324 
  325         return boot_start + boot_size + load_info_size;
  326 }
  327 
  328 /*
  329 
  330  */
  331 mach_port_t     boot_device_port;       /* local name */
  332 mach_port_t     boot_host_port;         /* local name */
  333 
  334 no_return       user_bootstrap(void);   /* forward */
  335 
  336 extern char     *root_name;
  337 
  338 mach_port_t
  339 task_insert_send_right(
  340         task_t task,
  341         ipc_port_t port)
  342 {
  343         mach_port_t name;
  344 
  345         for (name = 1;; name++) {
  346                 kern_return_t kr;
  347 
  348                 kr = mach_port_insert_right(task->itk_space, name,
  349                             (ipc_object_t)port, MACH_MSG_TYPE_PORT_SEND);
  350                 if (kr == KERN_SUCCESS)
  351                         break;
  352                 assert(kr == KERN_NAME_EXISTS);
  353         }
  354 
  355         return name;
  356 }
  357 
  358 void bootstrap_create(void)
  359 {
  360         task_t          bootstrap_task;
  361         thread_t        bootstrap_thread;
  362 
  363         if (boot_size == 0) {
  364                 printf("Not starting bootstrap task.\n");
  365                 return;
  366         }
  367 
  368         /*
  369          * Create the bootstrap task.
  370          */
  371 
  372         (void) task_create(TASK_NULL, FALSE, &bootstrap_task);
  373         (void) thread_create(bootstrap_task, &bootstrap_thread);
  374 
  375         /*
  376          * Insert send rights to the master host and device ports.
  377          */
  378 
  379         boot_host_port =
  380                 task_insert_send_right(bootstrap_task,
  381                         ipc_port_make_send(realhost.host_priv_self));
  382 
  383         boot_device_port =
  384                 task_insert_send_right(bootstrap_task,
  385                         ipc_port_make_send(master_device_port));
  386 
  387         /*
  388          * Start the bootstrap thread.
  389          */
  390         thread_start(bootstrap_thread, user_bootstrap);
  391         (void) thread_resume(bootstrap_thread);
  392 }
  393 
  394 /*
  395  * The following code runs as the kernel mode portion of the
  396  * first user thread.
  397  */
  398 
  399 /*
  400  * Convert an unsigned integer to its decimal representation.
  401  */
  402 void
  403 itoa(
  404         char            *str,
  405         vm_size_t       num)
  406 {
  407         char    buf[sizeof(vm_size_t)*2+3];
  408         register char *np;
  409 
  410         np = buf + sizeof(buf);
  411         *--np = 0;
  412 
  413         do {
  414             *--np = '' + num % 10;
  415             num /= 10;
  416         } while (num != 0);
  417 
  418         strcpy(str, np);
  419 }
  420 
  421 /*
  422  * Parse the boot flags into an argument string.
  423  * Format as a standard flag argument: '-qsdn...'
  424  */
  425 #include <sys/reboot.h>
  426 
  427 static void
  428 get_boot_flags(
  429         char    str[])  /* OUT */
  430 {
  431         register char *cp;
  432         register int    bflag;
  433 
  434 #if     defined(mips) || defined(alpha)
  435 
  436         extern char *machine_get_boot_flags();
  437         cp = machine_get_boot_flags(str);
  438 #else
  439         cp = str;
  440         *cp++ = '-';
  441 #endif
  442 
  443         bflag = boothowto;
  444 
  445         if (bflag & RB_ASKNAME)
  446             *cp++ = 'q';
  447         if (bflag & RB_SINGLE)
  448             *cp++ = 's';
  449 #if     MACH_KDB
  450         if (bflag & RB_KDB)
  451             *cp++ = 'd';
  452 #endif  /* MACH_KDB */
  453         if (bflag & RB_INITNAME)
  454             *cp++ = 'n';
  455 
  456         if (cp == &str[1])      /* no flags */
  457             *cp++ = 'x';
  458         *cp = '\0';
  459 }
  460 
  461 /*
  462  * Copy boot_data (executable) to the user portion of this task.
  463  */
  464 boolean_t       load_protect_text = TRUE;
  465 #if MACH_KDB
  466                 /* if set, fault in the text segment */
  467 boolean_t       load_fault_in_text = TRUE;
  468 #endif
  469 
  470 vm_offset_t
  471 boot_map(
  472         void *          data,   /* private data */
  473         vm_offset_t     offset) /* offset to map */
  474 {
  475         vm_offset_t     start_offset = (vm_offset_t) data;
  476 
  477         return pmap_extract(kernel_pmap, start_offset + offset);
  478 }
  479 
  480 
  481 #if BOOTSTRAP_SYMBOLS
  482 boolean_t load_bootstrap_symbols = TRUE;
  483 #else
  484 boolean_t load_bootstrap_symbols = FALSE;
  485 #endif
  486 
  487 
  488 
  489 void
  490 copy_bootstrap(
  491         natural_t       *entry) /* out */
  492 {
  493         struct loader_info      *lp;
  494         vm_offset_t             text_page_start,
  495                                 text_page_end,
  496                                 data_page_start,
  497                                 bss_start,
  498                                 bss_page_start,
  499                                 bss_page_end;
  500 
  501         register vm_map_t       user_map = current_task()->map;
  502         vm_object_t             boot_object;
  503         vm_size_t               bss_size;
  504 
  505         /*
  506          * Point to bootstrap load information.
  507          */
  508         lp = (struct loader_info *)load_info_start;
  509 
  510         /*
  511          * We assume that makeboot has aligned the various
  512          * pieces of the bootstrap image on page boundaries.
  513          */
  514         assert(lp->text_start == trunc_page(lp->text_start));
  515         assert(lp->data_start == trunc_page(lp->data_start));
  516         assert(lp->text_offset == trunc_page(lp->text_offset));
  517         assert(lp->data_offset == trunc_page(lp->data_offset)
  518             || lp->data_offset == lp->text_offset + lp->text_size);
  519 
  520         /*
  521          * Find how much virtual space we have to allocate.
  522          */
  523         text_page_start = trunc_page(lp->text_start);
  524         text_page_end   = round_page(lp->text_start + lp->text_size);
  525         data_page_start = trunc_page(lp->data_start);
  526         bss_start       = lp->data_start + lp->data_size;
  527         bss_page_start  = trunc_page(bss_start);
  528         bss_page_end    = round_page(bss_start + lp->bss_size);
  529         bss_size        = bss_page_end - bss_page_start;
  530 
  531 
  532         /*
  533          * Create an object that maps the pages in the
  534          * bootstrap image.  Map only until the end of the last
  535          * whole page.
  536          */
  537         boot_size = lp->data_offset + bss_page_start - lp->data_start;
  538         boot_object = vm_object_allocate(boot_size);
  539         vm_object_page_map(boot_object,
  540                            (vm_offset_t) 0,     /* from boot_start */
  541                            boot_size,
  542                            boot_map,
  543                            (char *)boot_start);
  544 
  545         /*
  546          * Map the text and data from the boot image into
  547          * the user task.  Map the data area only through
  548          * the last whole page of data - the next page of
  549          * data is split between data and bss, and must be
  550          * partially cleared.
  551          */
  552 
  553         if (text_page_end >= data_page_start) {
  554             /*
  555              * One contiguous area for text and data.
  556              */
  557             (void) vm_map_enter(user_map,
  558                         &text_page_start,
  559                         (vm_size_t) (bss_page_start - text_page_start),
  560                         (vm_offset_t) 0, FALSE,
  561                         boot_object,
  562                         lp->text_offset,
  563                         FALSE,
  564                         VM_PROT_READ | VM_PROT_WRITE,
  565                         VM_PROT_ALL,
  566                         VM_INHERIT_DEFAULT);
  567 
  568         }
  569         else {
  570             /*
  571              * Separated text and data areas.
  572              */
  573             (void) vm_map_enter(user_map,
  574                         &text_page_start,
  575                         (vm_size_t)(text_page_end - text_page_start),
  576                         (vm_offset_t) 0, FALSE,
  577                         boot_object,
  578                         lp->text_offset,
  579                         FALSE,
  580                         VM_PROT_READ | VM_PROT_WRITE,
  581                         VM_PROT_ALL,
  582                         VM_INHERIT_DEFAULT);
  583 
  584             (void) vm_map_enter(user_map,
  585                         &data_page_start,
  586                         (vm_size_t)(bss_page_start - data_page_start),
  587                         (vm_offset_t) 0, FALSE,
  588                         boot_object,
  589                         lp->data_offset,
  590                         FALSE,
  591                         VM_PROT_READ | VM_PROT_WRITE,
  592                         VM_PROT_ALL,
  593                         VM_INHERIT_DEFAULT);
  594         }
  595 
  596 
  597         /*
  598          * Allocate the remainder of the data segment and all
  599          * of the BSS. Protect against zero size bss.
  600          */
  601         if (bss_size)
  602           {
  603             (void) vm_allocate(user_map, &bss_page_start, 
  604                                (vm_size_t)(bss_size), FALSE);
  605 
  606             /*
  607              * If the data segment does not end on a VM page boundary,
  608              * we copy the end of the data segment onto a new page
  609              * so that the bss segment will be zero, and so that
  610              * we do not overwrite the bootstrap symbol table.
  611              */
  612             if (bss_start > bss_page_start) {
  613               (void) copyout((char *) boot_start +
  614                              lp->data_offset +
  615                              lp->data_size -
  616                              (bss_start - bss_page_start),
  617                              (char *)bss_page_start,
  618                              bss_start - bss_page_start);
  619             }
  620           } 
  621 
  622         /*
  623          * Protect the text.
  624          */
  625         if (load_protect_text)
  626             (void) vm_protect(user_map,
  627                         text_page_start,
  628                         (vm_size_t)(trunc_page(lp->text_start+lp->text_size)
  629                                 - text_page_start),
  630                         FALSE,
  631                         VM_PROT_READ|VM_PROT_EXECUTE);
  632 
  633 #if     MACH_KDB
  634         /*
  635          * Enter the bootstrap symbol table.
  636          */
  637 
  638         if (load_bootstrap_symbols)
  639         (void) X_db_sym_init(
  640                 (char*) boot_start+lp->sym_offset,
  641                 (char*) boot_start+lp->sym_offset+lp->sym_size,
  642                 "bootstrap",
  643                 (char *) user_map);
  644 
  645         if (load_fault_in_text)
  646           {
  647             vm_offset_t lenp = round_page(lp->text_start+lp->text_size) -
  648                              trunc_page(lp->text_start);
  649             vm_offset_t i = 0;
  650 
  651             while (i < lenp)
  652               {
  653                 (void) vm_fault(user_map, text_page_start + i,
  654                         load_protect_text ?  
  655                          VM_PROT_READ|VM_PROT_EXECUTE :
  656                          VM_PROT_READ|VM_PROT_EXECUTE | VM_PROT_WRITE,
  657                          FALSE, FALSE, 0);
  658                 i = round_page (i+1);
  659               }
  660           }
  661 
  662 
  663 #endif  /* MACH_KDB */
  664         /*
  665          * Return the entry points.
  666          */
  667         entry[0] = lp->entry_1;
  668         entry[1] = lp->entry_2;
  669 }
  670 
  671 /*
  672  * Allocate the stack, and build the argument list.
  673  */
  674 
  675 void
  676 build_args_and_stack(natural_t *entry, ...)
  677 {
  678         vm_offset_t     stack_base;
  679         vm_size_t       stack_size;
  680         va_list         argv_ptr;
  681         register
  682         char *          arg_ptr;
  683         int             arg_len;
  684         int             arg_count;
  685         register
  686         char *          arg_pos;
  687         int             arg_item_len;
  688         char *          string_pos;
  689         char *          zero = (char *)0;
  690 
  691 #define STACK_SIZE      (64*1024)
  692 
  693         /*
  694          * Calculate the size of the argument list.
  695          */
  696         va_start(argv_ptr, entry);
  697         arg_len = 0;
  698         arg_count = 0;
  699         for (;;) {
  700             arg_ptr = va_arg(argv_ptr, char *);
  701             if (arg_ptr == 0)
  702                 break;
  703             arg_count++;
  704             arg_len += strlen(arg_ptr) + 1;
  705         }
  706         va_end(argv_ptr);
  707 
  708         /*
  709          * Add space for:
  710          *      arg count
  711          *      pointers to arguments
  712          *      trailing 0 pointer
  713          *      dummy 0 pointer to environment variables
  714          *      and align to integer boundary
  715          */
  716         arg_len += sizeof(integer_t)
  717                  + (2 + arg_count) * sizeof(char *);
  718         arg_len = (arg_len + sizeof(integer_t) - 1) & ~(sizeof(integer_t)-1);
  719 
  720         /*
  721          * Allocate the stack.
  722          */
  723         stack_size = round_page(STACK_SIZE);
  724         stack_base = user_stack_low(stack_size);
  725         (void) vm_allocate(current_task()->map,
  726                         &stack_base,
  727                         stack_size,
  728                         FALSE);
  729 
  730         arg_pos = (char *)
  731                 set_user_regs(stack_base, stack_size, entry, arg_len);
  732 
  733         /*
  734          * Start the strings after the arg-count and pointers
  735          */
  736         string_pos = arg_pos
  737                 + sizeof(integer_t)
  738                 + arg_count * sizeof(char *)
  739                 + 2 * sizeof(char *);
  740 
  741         /*
  742          * first the argument count
  743          */
  744         (void) copyout((char *)&arg_count,
  745                         arg_pos,
  746                         sizeof(integer_t));
  747         arg_pos += sizeof(integer_t);
  748 
  749         /*
  750          * Then the strings and string pointers for each argument
  751          */
  752         va_start(argv_ptr, entry);
  753         while (--arg_count >= 0) {
  754             arg_ptr = va_arg(argv_ptr, char *);
  755             arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
  756 
  757             /* set string pointer */
  758             (void) copyout((char *)&string_pos,
  759                         arg_pos,
  760                         sizeof (char *));
  761             arg_pos += sizeof(char *);
  762 
  763             /* copy string */
  764             (void) copyout(arg_ptr, string_pos, arg_item_len);
  765             string_pos += arg_item_len;
  766         }
  767         va_end(argv_ptr);
  768 
  769         /*
  770          * last, the trailing 0 argument and a null environment pointer.
  771          */
  772         (void) copyout((char *)&zero, arg_pos, sizeof(char *));
  773         arg_pos += sizeof(char *);
  774         (void) copyout((char *)&zero, arg_pos, sizeof(char *));
  775 }
  776 
  777 no_return user_bootstrap(void)
  778 {
  779         natural_t       entry[2];
  780 
  781         char    host_string[12];
  782         char    device_string[12];
  783         char    flag_string[12];
  784 
  785         /*
  786          * Copy the bootstrap code from boot_data to the user task.
  787          */
  788         copy_bootstrap(entry);
  789 
  790         /*
  791          * Convert the host and device ports to strings,
  792          * to put in the argument list.
  793          */
  794         itoa(host_string, boot_host_port);
  795         itoa(device_string, boot_device_port);
  796 
  797         /*
  798          * Get the boot flags, also
  799          */
  800         get_boot_flags(flag_string);
  801 
  802         /*
  803          * Build the argument list and insert in the user task.
  804          * Argument list is
  805          * "bootstrap -<boothowto> <host_port> <device_port> <root_name>"
  806          */
  807         build_args_and_stack(entry,
  808                         "bootstrap",
  809                         flag_string,
  810                         host_string,
  811                         device_string,
  812                         root_name,
  813                         (char *)0);
  814 
  815         /*
  816          * Exit to user thread.
  817          */
  818         thread_bootstrap_return();
  819         /*NOTREACHED*/
  820 }
  821 

Cache object: f431b5968ae7574b447e48c74b668993


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.