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/init_main.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1995 Terrence R. Lambert
    3  * All rights reserved.
    4  *
    5  * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. All advertising materials mentioning features or use of this software
   22  *    must display the following acknowledgement:
   23  *      This product includes software developed by the University of
   24  *      California, Berkeley and its contributors.
   25  * 4. Neither the name of the University nor the names of its contributors
   26  *    may be used to endorse or promote products derived from this software
   27  *    without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  *
   41  *      @(#)init_main.c 8.9 (Berkeley) 1/21/94
   42  */
   43 
   44 #include <sys/cdefs.h>
   45 __FBSDID("$FreeBSD$");
   46 
   47 #include "opt_ddb.h"
   48 #include "opt_init_path.h"
   49 #include "opt_mac.h"
   50 
   51 #include <sys/param.h>
   52 #include <sys/kernel.h>
   53 #include <sys/exec.h>
   54 #include <sys/file.h>
   55 #include <sys/filedesc.h>
   56 #include <sys/ktr.h>
   57 #include <sys/lock.h>
   58 #include <sys/mac.h>
   59 #include <sys/mount.h>
   60 #include <sys/mutex.h>
   61 #include <sys/syscallsubr.h>
   62 #include <sys/sysctl.h>
   63 #include <sys/proc.h>
   64 #include <sys/resourcevar.h>
   65 #include <sys/systm.h>
   66 #include <sys/signalvar.h>
   67 #include <sys/vnode.h>
   68 #include <sys/sysent.h>
   69 #include <sys/reboot.h>
   70 #include <sys/sched.h>
   71 #include <sys/sx.h>
   72 #include <sys/sysproto.h>
   73 #include <sys/vmmeter.h>
   74 #include <sys/unistd.h>
   75 #include <sys/malloc.h>
   76 #include <sys/conf.h>
   77 
   78 #include <machine/cpu.h>
   79 
   80 #include <security/audit/audit.h>
   81 
   82 #include <vm/vm.h>
   83 #include <vm/vm_param.h>
   84 #include <vm/pmap.h>
   85 #include <vm/vm_map.h>
   86 #include <sys/copyright.h>
   87 
   88 #include <ddb/ddb.h>
   89 #include <ddb/db_sym.h>
   90 
   91 void mi_startup(void);                          /* Should be elsewhere */
   92 
   93 /* Components of the first process -- never freed. */
   94 static struct session session0;
   95 static struct pgrp pgrp0;
   96 struct  proc proc0;
   97 struct  thread thread0;
   98 struct  ksegrp ksegrp0;
   99 struct  vmspace vmspace0;
  100 struct  proc *initproc;
  101 
  102 int     boothowto = 0;          /* initialized so that it can be patched */
  103 SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
  104 int     bootverbose;
  105 SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
  106 
  107 /*
  108  * This ensures that there is at least one entry so that the sysinit_set
  109  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
  110  * executed.
  111  */
  112 SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
  113 
  114 /*
  115  * The sysinit table itself.  Items are checked off as the are run.
  116  * If we want to register new sysinit types, add them to newsysinit.
  117  */
  118 SET_DECLARE(sysinit_set, struct sysinit);
  119 struct sysinit **sysinit, **sysinit_end;
  120 struct sysinit **newsysinit, **newsysinit_end;
  121 
  122 /*
  123  * Merge a new sysinit set into the current set, reallocating it if
  124  * necessary.  This can only be called after malloc is running.
  125  */
  126 void
  127 sysinit_add(struct sysinit **set, struct sysinit **set_end)
  128 {
  129         struct sysinit **newset;
  130         struct sysinit **sipp;
  131         struct sysinit **xipp;
  132         int count;
  133 
  134         count = set_end - set;
  135         if (newsysinit)
  136                 count += newsysinit_end - newsysinit;
  137         else
  138                 count += sysinit_end - sysinit;
  139         newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
  140         if (newset == NULL)
  141                 panic("cannot malloc for sysinit");
  142         xipp = newset;
  143         if (newsysinit)
  144                 for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
  145                         *xipp++ = *sipp;
  146         else
  147                 for (sipp = sysinit; sipp < sysinit_end; sipp++)
  148                         *xipp++ = *sipp;
  149         for (sipp = set; sipp < set_end; sipp++)
  150                 *xipp++ = *sipp;
  151         if (newsysinit)
  152                 free(newsysinit, M_TEMP);
  153         newsysinit = newset;
  154         newsysinit_end = newset + count;
  155 }
  156 
  157 /*
  158  * System startup; initialize the world, create process 0, mount root
  159  * filesystem, and fork to create init and pagedaemon.  Most of the
  160  * hard work is done in the lower-level initialization routines including
  161  * startup(), which does memory initialization and autoconfiguration.
  162  *
  163  * This allows simple addition of new kernel subsystems that require
  164  * boot time initialization.  It also allows substitution of subsystem
  165  * (for instance, a scheduler, kernel profiler, or VM system) by object
  166  * module.  Finally, it allows for optional "kernel threads".
  167  */
  168 void
  169 mi_startup(void)
  170 {
  171 
  172         register struct sysinit **sipp;         /* system initialization*/
  173         register struct sysinit **xipp;         /* interior loop of sort*/
  174         register struct sysinit *save;          /* bubble*/
  175 
  176 #if defined(VERBOSE_SYSINIT)
  177         int last;
  178         int verbose;
  179 #endif
  180 
  181         if (sysinit == NULL) {
  182                 sysinit = SET_BEGIN(sysinit_set);
  183                 sysinit_end = SET_LIMIT(sysinit_set);
  184         }
  185 
  186 restart:
  187         /*
  188          * Perform a bubble sort of the system initialization objects by
  189          * their subsystem (primary key) and order (secondary key).
  190          */
  191         for (sipp = sysinit; sipp < sysinit_end; sipp++) {
  192                 for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
  193                         if ((*sipp)->subsystem < (*xipp)->subsystem ||
  194                              ((*sipp)->subsystem == (*xipp)->subsystem &&
  195                               (*sipp)->order <= (*xipp)->order))
  196                                 continue;       /* skip*/
  197                         save = *sipp;
  198                         *sipp = *xipp;
  199                         *xipp = save;
  200                 }
  201         }
  202 
  203 #if defined(VERBOSE_SYSINIT)
  204         last = SI_SUB_COPYRIGHT;
  205         verbose = 0;
  206 #if !defined(DDB)
  207         printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n");
  208 #endif
  209 #endif
  210 
  211         /*
  212          * Traverse the (now) ordered list of system initialization tasks.
  213          * Perform each task, and continue on to the next task.
  214          *
  215          * The last item on the list is expected to be the scheduler,
  216          * which will not return.
  217          */
  218         for (sipp = sysinit; sipp < sysinit_end; sipp++) {
  219 
  220                 if ((*sipp)->subsystem == SI_SUB_DUMMY)
  221                         continue;       /* skip dummy task(s)*/
  222 
  223                 if ((*sipp)->subsystem == SI_SUB_DONE)
  224                         continue;
  225 
  226 #if defined(VERBOSE_SYSINIT)
  227                 if ((*sipp)->subsystem > last) {
  228                         verbose = 1;
  229                         last = (*sipp)->subsystem;
  230                         printf("subsystem %x\n", last);
  231                 }
  232                 if (verbose) {
  233 #if defined(DDB)
  234                         const char *name;
  235                         c_db_sym_t sym;
  236                         db_expr_t  offset;
  237 
  238                         sym = db_search_symbol((vm_offset_t)(*sipp)->func,
  239                             DB_STGY_PROC, &offset);
  240                         db_symbol_values(sym, &name, NULL);
  241                         if (name != NULL)
  242                                 printf("   %s(%p)... ", name, (*sipp)->udata);
  243                         else
  244 #endif
  245                                 printf("   %p(%p)... ", (*sipp)->func,
  246                                     (*sipp)->udata);
  247                 }
  248 #endif
  249 
  250                 /* Call function */
  251                 (*((*sipp)->func))((*sipp)->udata);
  252 
  253 #if defined(VERBOSE_SYSINIT)
  254                 if (verbose)
  255                         printf("done.\n");
  256 #endif
  257 
  258                 /* Check off the one we're just done */
  259                 (*sipp)->subsystem = SI_SUB_DONE;
  260 
  261                 /* Check if we've installed more sysinit items via KLD */
  262                 if (newsysinit != NULL) {
  263                         if (sysinit != SET_BEGIN(sysinit_set))
  264                                 free(sysinit, M_TEMP);
  265                         sysinit = newsysinit;
  266                         sysinit_end = newsysinit_end;
  267                         newsysinit = NULL;
  268                         newsysinit_end = NULL;
  269                         goto restart;
  270                 }
  271         }
  272 
  273         panic("Shouldn't get here!");
  274         /* NOTREACHED*/
  275 }
  276 
  277 
  278 /*
  279  ***************************************************************************
  280  ****
  281  **** The following SYSINIT's belong elsewhere, but have not yet
  282  **** been moved.
  283  ****
  284  ***************************************************************************
  285  */
  286 static void
  287 print_caddr_t(void *data __unused)
  288 {
  289         printf("%s", (char *)data);
  290 }
  291 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
  292 SYSINIT(trademark, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, trademark)
  293 SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_THIRD, print_caddr_t, version)
  294 
  295 #ifdef WITNESS
  296 static char wit_warn[] =
  297      "WARNING: WITNESS option enabled, expect reduced performance.\n";
  298 SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
  299    print_caddr_t, wit_warn)
  300 #endif
  301 
  302 #ifdef DIAGNOSTIC
  303 static char diag_warn[] =
  304      "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
  305 SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2,
  306     print_caddr_t, diag_warn)
  307 #endif
  308 
  309 static void
  310 set_boot_verbose(void *data __unused)
  311 {
  312 
  313         if (boothowto & RB_VERBOSE)
  314                 bootverbose++;
  315 }
  316 SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL)
  317 
  318 struct sysentvec null_sysvec = {
  319         0,
  320         NULL,
  321         0,
  322         0,
  323         NULL,
  324         0,
  325         NULL,
  326         NULL,
  327         NULL,
  328         NULL,
  329         NULL,
  330         NULL,
  331         NULL,
  332         "null",
  333         NULL,
  334         NULL,
  335         0,
  336         PAGE_SIZE,
  337         VM_MIN_ADDRESS,
  338         VM_MAXUSER_ADDRESS,
  339         USRSTACK,
  340         PS_STRINGS,
  341         VM_PROT_ALL,
  342         NULL,
  343         NULL,
  344         NULL
  345 };
  346 
  347 /*
  348  ***************************************************************************
  349  ****
  350  **** The two following SYSINIT's are proc0 specific glue code.  I am not
  351  **** convinced that they can not be safely combined, but their order of
  352  **** operation has been maintained as the same as the original init_main.c
  353  **** for right now.
  354  ****
  355  **** These probably belong in init_proc.c or kern_proc.c, since they
  356  **** deal with proc0 (the fork template process).
  357  ****
  358  ***************************************************************************
  359  */
  360 /* ARGSUSED*/
  361 static void
  362 proc0_init(void *dummy __unused)
  363 {
  364         struct proc *p;
  365         unsigned i;
  366         struct thread *td;
  367         struct ksegrp *kg;
  368 
  369         GIANT_REQUIRED;
  370         p = &proc0;
  371         td = &thread0;
  372         kg = &ksegrp0;
  373 
  374         /*
  375          * Initialize magic number.
  376          */
  377         p->p_magic = P_MAGIC;
  378 
  379         /*
  380          * Initialize thread, process and ksegrp structures.
  381          */
  382         procinit();     /* set up proc zone */
  383         threadinit();   /* set up thead, upcall and KSEGRP zones */
  384 
  385         /*
  386          * Initialise scheduler resources.
  387          * Add scheduler specific parts to proc, ksegrp, thread as needed.
  388          */
  389         schedinit();    /* scheduler gets its house in order */
  390         /*
  391          * Initialize sleep queue hash table
  392          */
  393         sleepinit();
  394 
  395         /*
  396          * additional VM structures
  397          */
  398         vm_init2();
  399 
  400         /*
  401          * Create process 0 (the swapper).
  402          */
  403         LIST_INSERT_HEAD(&allproc, p, p_list);
  404         LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
  405         mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
  406         p->p_pgrp = &pgrp0;
  407         LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
  408         LIST_INIT(&pgrp0.pg_members);
  409         LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
  410 
  411         pgrp0.pg_session = &session0;
  412         mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
  413         session0.s_count = 1;
  414         session0.s_leader = p;
  415 
  416         p->p_sysent = &null_sysvec;
  417         p->p_flag = P_SYSTEM;
  418         p->p_sflag = PS_INMEM;
  419         p->p_state = PRS_NORMAL;
  420         knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL);
  421         STAILQ_INIT(&p->p_ktr);
  422         p->p_nice = NZERO;
  423         td->td_state = TDS_RUNNING;
  424         kg->kg_pri_class = PRI_TIMESHARE;
  425         kg->kg_user_pri = PUSER;
  426         td->td_priority = PVM;
  427         td->td_base_pri = PUSER;
  428         td->td_oncpu = 0;
  429         p->p_peers = 0;
  430         p->p_leader = p;
  431 
  432 
  433         bcopy("swapper", p->p_comm, sizeof ("swapper"));
  434 
  435         callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
  436         callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
  437 
  438         /* Create credentials. */
  439         p->p_ucred = crget();
  440         p->p_ucred->cr_ngroups = 1;     /* group 0 */
  441         p->p_ucred->cr_uidinfo = uifind(0);
  442         p->p_ucred->cr_ruidinfo = uifind(0);
  443         p->p_ucred->cr_prison = NULL;   /* Don't jail it. */
  444 #ifdef AUDIT
  445         audit_proc_alloc(p);
  446         audit_proc_kproc0(p);
  447 #endif
  448 #ifdef MAC
  449         mac_create_proc0(p->p_ucred);
  450 #endif
  451         td->td_ucred = crhold(p->p_ucred);
  452 
  453         /* Create sigacts. */
  454         p->p_sigacts = sigacts_alloc();
  455 
  456         /* Initialize signal state for process 0. */
  457         siginit(&proc0);
  458 
  459         /* Create the file descriptor table. */
  460         p->p_fd = fdinit(NULL);
  461         p->p_fdtol = NULL;
  462 
  463         /* Create the limits structures. */
  464         p->p_limit = lim_alloc();
  465         for (i = 0; i < RLIM_NLIMITS; i++)
  466                 p->p_limit->pl_rlimit[i].rlim_cur =
  467                     p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
  468         p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
  469             p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
  470         p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
  471             p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
  472         i = ptoa(cnt.v_free_count);
  473         p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i;
  474         p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
  475         p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
  476         p->p_cpulimit = RLIM_INFINITY;
  477 
  478         p->p_stats = pstats_alloc();
  479 
  480         /* Allocate a prototype map so we have something to fork. */
  481         pmap_pinit0(vmspace_pmap(&vmspace0));
  482         p->p_vmspace = &vmspace0;
  483         vmspace0.vm_refcnt = 1;
  484         vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
  485             p->p_sysent->sv_maxuser);
  486         vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
  487 
  488         /*
  489          * Charge root for one process.
  490          */
  491         (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
  492 }
  493 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
  494 
  495 /* ARGSUSED*/
  496 static void
  497 proc0_post(void *dummy __unused)
  498 {
  499         struct timespec ts;
  500         struct proc *p;
  501 
  502         /*
  503          * Now we can look at the time, having had a chance to verify the
  504          * time from the filesystem.  Pretend that proc0 started now.
  505          */
  506         sx_slock(&allproc_lock);
  507         LIST_FOREACH(p, &allproc, p_list) {
  508                 microuptime(&p->p_stats->p_start);
  509                 p->p_rux.rux_runtime.sec = 0;
  510                 p->p_rux.rux_runtime.frac = 0;
  511         }
  512         sx_sunlock(&allproc_lock);
  513         binuptime(PCPU_PTR(switchtime));
  514         PCPU_SET(switchticks, ticks);
  515 
  516         /*
  517          * Give the ``random'' number generator a thump.
  518          */
  519         nanotime(&ts);
  520         srandom(ts.tv_sec ^ ts.tv_nsec);
  521 }
  522 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
  523 
  524 /*
  525  ***************************************************************************
  526  ****
  527  **** The following SYSINIT's and glue code should be moved to the
  528  **** respective files on a per subsystem basis.
  529  ****
  530  ***************************************************************************
  531  */
  532 
  533 
  534 /*
  535  ***************************************************************************
  536  ****
  537  **** The following code probably belongs in another file, like
  538  **** kern/init_init.c.
  539  ****
  540  ***************************************************************************
  541  */
  542 
  543 /*
  544  * List of paths to try when searching for "init".
  545  */
  546 static char init_path[MAXPATHLEN] =
  547 #ifdef  INIT_PATH
  548     __XSTRING(INIT_PATH);
  549 #else
  550     "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall";
  551 #endif
  552 SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
  553         "Path used to search the init process");
  554 
  555 /*
  556  * Shutdown timeout of init(8).
  557  * Unused within kernel, but used to control init(8), hence do not remove.
  558  */
  559 #ifndef INIT_SHUTDOWN_TIMEOUT
  560 #define INIT_SHUTDOWN_TIMEOUT 120
  561 #endif
  562 static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT;
  563 SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
  564         CTLFLAG_RW, &init_shutdown_timeout, 0, "");
  565 
  566 /*
  567  * Start the initial user process; try exec'ing each pathname in init_path.
  568  * The program is invoked with one argument containing the boot flags.
  569  */
  570 static void
  571 start_init(void *dummy)
  572 {
  573         vm_offset_t addr;
  574         struct execve_args args;
  575         int options, error;
  576         char *var, *path, *next, *s;
  577         char *ucp, **uap, *arg0, *arg1;
  578         struct thread *td;
  579         struct proc *p;
  580 
  581         mtx_lock(&Giant);
  582 
  583         GIANT_REQUIRED;
  584 
  585         td = curthread;
  586         p = td->td_proc;
  587 
  588         vfs_mountroot();
  589 
  590         /*
  591          * Need just enough stack to hold the faked-up "execve()" arguments.
  592          */
  593         addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
  594         if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
  595                         FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
  596                 panic("init: couldn't allocate argument space");
  597         p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
  598         p->p_vmspace->vm_ssize = 1;
  599 
  600         if ((var = getenv("init_path")) != NULL) {
  601                 strlcpy(init_path, var, sizeof(init_path));
  602                 freeenv(var);
  603         }
  604         
  605         for (path = init_path; *path != '\0'; path = next) {
  606                 while (*path == ':')
  607                         path++;
  608                 if (*path == '\0')
  609                         break;
  610                 for (next = path; *next != '\0' && *next != ':'; next++)
  611                         /* nothing */ ;
  612                 if (bootverbose)
  613                         printf("start_init: trying %.*s\n", (int)(next - path),
  614                             path);
  615                         
  616                 /*
  617                  * Move out the boot flag argument.
  618                  */
  619                 options = 0;
  620                 ucp = (char *)p->p_sysent->sv_usrstack;
  621                 (void)subyte(--ucp, 0);         /* trailing zero */
  622                 if (boothowto & RB_SINGLE) {
  623                         (void)subyte(--ucp, 's');
  624                         options = 1;
  625                 }
  626 #ifdef notyet
  627                 if (boothowto & RB_FASTBOOT) {
  628                         (void)subyte(--ucp, 'f');
  629                         options = 1;
  630                 }
  631 #endif
  632 
  633 #ifdef BOOTCDROM
  634                 (void)subyte(--ucp, 'C');
  635                 options = 1;
  636 #endif
  637 
  638                 if (options == 0)
  639                         (void)subyte(--ucp, '-');
  640                 (void)subyte(--ucp, '-');               /* leading hyphen */
  641                 arg1 = ucp;
  642 
  643                 /*
  644                  * Move out the file name (also arg 0).
  645                  */
  646                 (void)subyte(--ucp, 0);
  647                 for (s = next - 1; s >= path; s--)
  648                         (void)subyte(--ucp, *s);
  649                 arg0 = ucp;
  650 
  651                 /*
  652                  * Move out the arg pointers.
  653                  */
  654                 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
  655                 (void)suword((caddr_t)--uap, (long)0);  /* terminator */
  656                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
  657                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
  658 
  659                 /*
  660                  * Point at the arguments.
  661                  */
  662                 args.fname = arg0;
  663                 args.argv = uap;
  664                 args.envv = NULL;
  665 
  666                 /*
  667                  * Now try to exec the program.  If can't for any reason
  668                  * other than it doesn't exist, complain.
  669                  *
  670                  * Otherwise, return via fork_trampoline() all the way
  671                  * to user mode as init!
  672                  */
  673                 if ((error = execve(td, &args)) == 0) {
  674                         mtx_unlock(&Giant);
  675                         return;
  676                 }
  677                 if (error != ENOENT)
  678                         printf("exec %.*s: error %d\n", (int)(next - path), 
  679                             path, error);
  680         }
  681         printf("init: not found in path %s\n", init_path);
  682         panic("no init");
  683 }
  684 
  685 /*
  686  * Like kthread_create(), but runs in it's own address space.
  687  * We do this early to reserve pid 1.
  688  *
  689  * Note special case - do not make it runnable yet.  Other work
  690  * in progress will change this more.
  691  */
  692 static void
  693 create_init(const void *udata __unused)
  694 {
  695         struct ucred *newcred, *oldcred;
  696         int error;
  697 
  698         error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
  699         if (error)
  700                 panic("cannot fork init: %d\n", error);
  701         KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
  702         /* divorce init's credentials from the kernel's */
  703         newcred = crget();
  704         PROC_LOCK(initproc);
  705         initproc->p_flag |= P_SYSTEM;
  706         oldcred = initproc->p_ucred;
  707         crcopy(newcred, oldcred);
  708 #ifdef MAC
  709         mac_create_proc1(newcred);
  710 #endif
  711 #ifdef AUDIT
  712         audit_proc_init(initproc);
  713 #endif
  714         initproc->p_ucred = newcred;
  715         PROC_UNLOCK(initproc);
  716         crfree(oldcred);
  717         cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
  718         mtx_lock_spin(&sched_lock);
  719         initproc->p_sflag |= PS_INMEM;
  720         mtx_unlock_spin(&sched_lock);
  721         cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
  722 }
  723 SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
  724 
  725 /*
  726  * Make it runnable now.
  727  */
  728 static void
  729 kick_init(const void *udata __unused)
  730 {
  731         struct thread *td;
  732 
  733         td = FIRST_THREAD_IN_PROC(initproc);
  734         mtx_lock_spin(&sched_lock);
  735         TD_SET_CAN_RUN(td);
  736         setrunqueue(td, SRQ_BORING);    /* XXXKSE */
  737         mtx_unlock_spin(&sched_lock);
  738 }
  739 SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)

Cache object: 5bcbfbea55bffcae941d31bbd7d0397f


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