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

Cache object: 3b9453ce8e82716744515861e85d216a


[ 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.