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-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 /*      $NetBSD: init_main.c,v 1.244.6.6 2006/01/20 20:48:41 riz Exp $  */
    2 
    3 /*
    4  * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  * (c) UNIX System Laboratories, Inc.
    7  * All or some portions of this file are derived from material licensed
    8  * to the University of California by American Telephone and Telegraph
    9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   10  * the permission of UNIX System Laboratories, Inc.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  *      @(#)init_main.c 8.16 (Berkeley) 5/14/95
   37  */
   38 
   39 /*
   40  * Copyright (c) 1995 Christopher G. Demetriou.  All rights reserved.
   41  *
   42  * Redistribution and use in source and binary forms, with or without
   43  * modification, are permitted provided that the following conditions
   44  * are met:
   45  * 1. Redistributions of source code must retain the above copyright
   46  *    notice, this list of conditions and the following disclaimer.
   47  * 2. Redistributions in binary form must reproduce the above copyright
   48  *    notice, this list of conditions and the following disclaimer in the
   49  *    documentation and/or other materials provided with the distribution.
   50  * 3. All advertising materials mentioning features or use of this software
   51  *    must display the following acknowledgement:
   52  *      This product includes software developed by the University of
   53  *      California, Berkeley and its contributors.
   54  * 4. Neither the name of the University nor the names of its contributors
   55  *    may be used to endorse or promote products derived from this software
   56  *    without specific prior written permission.
   57  *
   58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   68  * SUCH DAMAGE.
   69  *
   70  *      @(#)init_main.c 8.16 (Berkeley) 5/14/95
   71  */
   72 
   73 #include <sys/cdefs.h>
   74 __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.244.6.6 2006/01/20 20:48:41 riz Exp $");
   75 
   76 #include "fs_nfs.h"
   77 #include "opt_nfsserver.h"
   78 #include "opt_ipsec.h"
   79 #include "opt_sysv.h"
   80 #include "opt_maxuprc.h"
   81 #include "opt_multiprocessor.h"
   82 #include "opt_pipe.h"
   83 #include "opt_syscall_debug.h"
   84 #include "opt_systrace.h"
   85 #include "opt_posix.h"
   86 #include "opt_kcont.h"
   87 #include "opt_verified_exec.h"
   88 
   89 #include "opencrypto.h"
   90 #include "rnd.h"
   91 
   92 #include <sys/param.h>
   93 #include <sys/acct.h>
   94 #include <sys/filedesc.h>
   95 #include <sys/file.h>
   96 #include <sys/errno.h>
   97 #include <sys/callout.h>
   98 #include <sys/kernel.h>
   99 #include <sys/kcont.h>
  100 #include <sys/mount.h>
  101 #include <sys/proc.h>
  102 #include <sys/kthread.h>
  103 #include <sys/resourcevar.h>
  104 #include <sys/signalvar.h>
  105 #include <sys/systm.h>
  106 #include <sys/vnode.h>
  107 #include <sys/tty.h>
  108 #include <sys/conf.h>
  109 #include <sys/disklabel.h>
  110 #include <sys/buf.h>
  111 #include <sys/device.h>
  112 #include <sys/exec.h>
  113 #include <sys/socketvar.h>
  114 #include <sys/protosw.h>
  115 #include <sys/reboot.h>
  116 #include <sys/user.h>
  117 #include <sys/sysctl.h>
  118 #include <sys/event.h>
  119 #include <sys/mbuf.h>
  120 #ifdef FAST_IPSEC
  121 #include <netipsec/ipsec.h>
  122 #endif
  123 #ifdef SYSVSHM
  124 #include <sys/shm.h>
  125 #endif
  126 #ifdef SYSVSEM
  127 #include <sys/sem.h>
  128 #endif
  129 #ifdef SYSVMSG
  130 #include <sys/msg.h>
  131 #endif
  132 #ifdef P1003_1B_SEMAPHORE
  133 #include <sys/ksem.h>
  134 #endif
  135 #ifdef SYSTRACE
  136 #include <sys/systrace.h>
  137 #endif
  138 #include <sys/domain.h>
  139 #include <sys/namei.h>
  140 #if NOPENCRYPTO > 0
  141 #include <opencrypto/cryptodev.h>       /* XXX really the framework */
  142 #endif
  143 #if NRND > 0
  144 #include <sys/rnd.h>
  145 #endif
  146 #ifndef PIPE_SOCKETPAIR
  147 #include <sys/pipe.h>
  148 #endif
  149 #ifdef LKM
  150 #include <sys/lkm.h>
  151 #endif
  152 #ifdef VERIFIED_EXEC
  153 #include <sys/verified_exec.h>
  154 #endif
  155 
  156 #include <sys/syscall.h>
  157 #include <sys/sa.h>
  158 #include <sys/syscallargs.h>
  159 
  160 #include <ufs/ufs/quota.h>
  161 
  162 #include <miscfs/genfs/genfs.h>
  163 #include <miscfs/syncfs/syncfs.h>
  164 
  165 #include <machine/cpu.h>
  166 
  167 #include <uvm/uvm.h>
  168 
  169 #include <dev/cons.h>
  170 
  171 #include <net/if.h>
  172 #include <net/raw_cb.h>
  173 
  174 /* Components of the first process -- never freed. */
  175 struct  session session0;
  176 struct  pgrp pgrp0;
  177 struct  proc proc0;
  178 struct  lwp lwp0;
  179 struct  pcred cred0;
  180 struct  filedesc0 filedesc0;
  181 struct  cwdinfo cwdi0;
  182 struct  plimit limit0;
  183 struct  pstats pstat0;
  184 struct  vmspace vmspace0;
  185 struct  sigacts sigacts0;
  186 #ifndef curlwp
  187 struct  lwp *curlwp = &lwp0;
  188 #endif
  189 struct  proc *initproc;
  190 
  191 int     nofile = NOFILE;
  192 int     maxuprc = MAXUPRC;
  193 int     cmask = CMASK;
  194 extern  struct user *proc0paddr;
  195 
  196 struct  vnode *rootvp, *swapdev_vp;
  197 int     boothowto;
  198 int     cold = 1;                       /* still working on startup */
  199 struct  timeval boottime;
  200 time_t  rootfstime;                     /* recorded root fs time, if known */
  201 
  202 __volatile int start_init_exec;         /* semaphore for start_init() */
  203 
  204 static void check_console(struct proc *p);
  205 static void start_init(void *);
  206 void main(void);
  207 
  208 extern const struct emul emul_netbsd;   /* defined in kern_exec.c */
  209 
  210 /*
  211  * System startup; initialize the world, create process 0, mount root
  212  * filesystem, and fork to create init and pagedaemon.  Most of the
  213  * hard work is done in the lower-level initialization routines including
  214  * startup(), which does memory initialization and autoconfiguration.
  215  */
  216 void
  217 main(void)
  218 {
  219         struct lwp *l;
  220         struct proc *p;
  221         struct pdevinit *pdev;
  222         int s, error;
  223         u_int i;
  224         rlim_t lim;
  225         extern struct pdevinit pdevinit[];
  226         extern void schedcpu(void *);
  227 #if defined(NFSSERVER) || defined(NFS)
  228         extern void nfs_init(void);
  229 #endif
  230 #ifdef NVNODE_IMPLICIT
  231         int usevnodes;
  232 #endif
  233 
  234         /*
  235          * Initialize the current LWP pointer (curlwp) before
  236          * any possible traps/probes to simplify trap processing.
  237          */
  238         l = &lwp0;
  239         curlwp = l;
  240         l->l_cpu = curcpu();
  241         l->l_proc = &proc0;
  242         l->l_lid = 1;
  243 
  244         /*
  245          * Attempt to find console and initialize
  246          * in case of early panic or other messages.
  247          */
  248         consinit();
  249         printf("%s", copyright);
  250 
  251         KERNEL_LOCK_INIT();
  252 
  253         uvm_init();
  254 
  255         /* Do machine-dependent initialization. */
  256         cpu_startup();
  257 
  258         /* Initialize callouts. */
  259         callout_startup();
  260 
  261         /* Initialize the buffer cache */
  262         bufinit();
  263 
  264         /*
  265          * Initialize mbuf's.  Do this now because we might attempt to
  266          * allocate mbufs or mbuf clusters during autoconfiguration.
  267          */
  268         mbinit();
  269 
  270         /* Initialize sockets. */
  271         soinit();
  272 
  273 #ifdef KCONT
  274         /* Initialize kcont. */
  275         kcont_init();
  276 #endif
  277 
  278         /*
  279          * The following things must be done before autoconfiguration.
  280          */
  281         evcnt_init();           /* initialize event counters */
  282         tty_init();             /* initialize tty list */
  283 #if NRND > 0
  284         rnd_init();             /* initialize RNG */
  285 #endif
  286 #if NOPENCRYPTO > 0
  287         /* Initialize crypto subsystem before configuring crypto hardware. */
  288         (void)crypto_init();
  289 #endif
  290         /* Initialize the sysctl subsystem. */
  291         sysctl_init();
  292 
  293         /* Initialize process and pgrp structures. */
  294         procinit();
  295 
  296 #ifdef LKM
  297         /* Initialize the LKM system. */
  298         lkm_init();
  299 #endif
  300 
  301         /*
  302          * Create process 0 (the swapper).
  303          */
  304         p = &proc0;
  305         proc0_insert(p, l, &pgrp0, &session0);
  306 
  307         /*
  308          * Set P_NOCLDWAIT so that kernel threads are reparented to
  309          * init(8) when they exit.  init(8) can easily wait them out
  310          * for us.
  311          */
  312         p->p_flag = P_SYSTEM | P_NOCLDWAIT;
  313         p->p_stat = SACTIVE;
  314         p->p_nice = NZERO;
  315         p->p_emul = &emul_netbsd;
  316 #ifdef __HAVE_SYSCALL_INTERN
  317         (*p->p_emul->e_syscall_intern)(p);
  318 #endif
  319         strncpy(p->p_comm, "swapper", MAXCOMLEN);
  320 
  321         l->l_flag = L_INMEM;
  322         l->l_stat = LSONPROC;
  323         p->p_nrlwps = 1;
  324 
  325         callout_init(&l->l_tsleep_ch);
  326 
  327         /* Create credentials. */
  328         cred0.p_refcnt = 1;
  329         p->p_cred = &cred0;
  330         p->p_ucred = crget();
  331         p->p_ucred->cr_ngroups = 1;     /* group 0 */
  332 
  333         /* Create the file descriptor table. */
  334         p->p_fd = &filedesc0.fd_fd;
  335         fdinit1(&filedesc0);
  336 
  337         /* Create the CWD info. */
  338         p->p_cwdi = &cwdi0;
  339         cwdi0.cwdi_cmask = cmask;
  340         cwdi0.cwdi_refcnt = 1;
  341         simple_lock_init(&cwdi0.cwdi_slock);
  342 
  343         /* Create the limits structures. */
  344         p->p_limit = &limit0;
  345         simple_lock_init(&limit0.p_slock);
  346         for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
  347                 limit0.pl_rlimit[i].rlim_cur =
  348                     limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
  349 
  350         limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
  351         limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
  352             maxfiles < nofile ? maxfiles : nofile;
  353 
  354         limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
  355         limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
  356             maxproc < maxuprc ? maxproc : maxuprc;
  357 
  358         lim = ptoa(uvmexp.free);
  359         limit0.pl_rlimit[RLIMIT_RSS].rlim_max = lim;
  360         limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = lim;
  361         limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
  362         limit0.pl_corename = defcorename;
  363         limit0.p_refcnt = 1;
  364 
  365         /*
  366          * Initialize proc0's vmspace, which uses the kernel pmap.
  367          * All kernel processes (which never have user space mappings)
  368          * share proc0's vmspace, and thus, the kernel pmap.
  369          */
  370         uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
  371             trunc_page(VM_MAX_ADDRESS));
  372         p->p_vmspace = &vmspace0;
  373 
  374         l->l_addr = proc0paddr;                         /* XXX */
  375 
  376         p->p_stats = &pstat0;
  377 
  378         /*
  379          * Charge root for one process.
  380          */
  381         (void)chgproccnt(0, 1);
  382 
  383         rqinit();
  384 
  385         /* Configure virtual memory system, set vm rlimits. */
  386         uvm_init_limits(p);
  387 
  388         /* Initialize the file systems. */
  389 #if defined(NFSSERVER) || defined(NFS)
  390         nfs_init();                     /* initialize server/shared data */
  391 #endif
  392 #ifdef NVNODE_IMPLICIT
  393         /*
  394          * If maximum number of vnodes in namei vnode cache is not explicitly
  395          * defined in kernel config, adjust the number such as we use roughly
  396          * 1.0% of memory for vnode cache (but not less than NVNODE vnodes).
  397          */
  398         usevnodes = (ptoa((unsigned)physmem) / 100) / sizeof(struct vnode);
  399         if (usevnodes > desiredvnodes)
  400                 desiredvnodes = usevnodes;
  401 #endif
  402         vfsinit();
  403 
  404         /* Configure the system hardware.  This will enable interrupts. */
  405         configure();
  406 
  407         ubc_init();             /* must be after autoconfig */
  408 
  409         /* Lock the kernel on behalf of proc0. */
  410         KERNEL_PROC_LOCK(l);
  411 
  412 #ifdef SYSVSHM
  413         /* Initialize System V style shared memory. */
  414         shminit();
  415 #endif
  416 
  417 #ifdef SYSVSEM
  418         /* Initialize System V style semaphores. */
  419         seminit();
  420 #endif
  421 
  422 #ifdef SYSVMSG
  423         /* Initialize System V style message queues. */
  424         msginit();
  425 #endif
  426 
  427 #ifdef P1003_1B_SEMAPHORE
  428         /* Initialize posix semaphores */
  429         ksem_init();
  430 #endif
  431 
  432 #ifdef VERIFIED_EXEC
  433           /*
  434            * Initialise the fingerprint operations vectors before
  435            * fingerprints can be loaded.
  436            */
  437         veriexec_init_fp_ops();
  438 #endif
  439         
  440         /* Attach pseudo-devices. */
  441         for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
  442                 (*pdev->pdev_attach)(pdev->pdev_count);
  443 
  444 #ifdef  FAST_IPSEC
  445         /* Attach network crypto subsystem */
  446         ipsec_attach();
  447 #endif
  448 
  449         /*
  450          * Initialize protocols.  Block reception of incoming packets
  451          * until everything is ready.
  452          */
  453         s = splnet();
  454         ifinit();
  455         domaininit();
  456         if_attachdomain();
  457         splx(s);
  458 
  459 #ifdef GPROF
  460         /* Initialize kernel profiling. */
  461         kmstartup();
  462 #endif
  463 
  464         /* Initialize system accouting. */
  465         acct_init();
  466 
  467 #ifdef SYSTRACE
  468         systrace_init();
  469 #endif
  470         /*
  471          * Initialize signal-related data structures, and signal state
  472          * for proc0.
  473          */
  474         signal_init();
  475         p->p_sigacts = &sigacts0;
  476         siginit(p);
  477 
  478         /* Kick off timeout driven events by calling first time. */
  479         schedcpu(NULL);
  480 
  481         /*
  482          * Create process 1 (init(8)).  We do this now, as Unix has
  483          * historically had init be process 1, and changing this would
  484          * probably upset a lot of people.
  485          *
  486          * Note that process 1 won't immediately exec init(8), but will
  487          * wait for us to inform it that the root file system has been
  488          * mounted.
  489          */
  490         if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, &initproc))
  491                 panic("fork init");
  492 
  493         /*
  494          * Create any kernel threads who's creation was deferred because
  495          * initproc had not yet been created.
  496          */
  497         kthread_run_deferred_queue();
  498 
  499         /*
  500          * Now that device driver threads have been created, wait for
  501          * them to finish any deferred autoconfiguration.  Note we don't
  502          * need to lock this semaphore, since we haven't booted any
  503          * secondary processors, yet.
  504          */
  505         while (config_pending)
  506                 (void) tsleep((void *)&config_pending, PWAIT, "cfpend", 0);
  507 
  508         /*
  509          * Finalize configuration now that all real devices have been
  510          * found.  This needs to be done before the root device is
  511          * selected, since finalization may create the root device.
  512          */
  513         config_finalize();
  514 
  515         /*
  516          * Now that autoconfiguration has completed, we can determine
  517          * the root and dump devices.
  518          */
  519         cpu_rootconf();
  520         cpu_dumpconf();
  521 
  522         /* Mount the root file system. */
  523         do {
  524                 domountroothook();
  525                 if ((error = vfs_mountroot())) {
  526                         printf("cannot mount root, error = %d\n", error);
  527                         boothowto |= RB_ASKNAME;
  528                         setroot(root_device,
  529                             (rootdev != NODEV) ? DISKPART(rootdev) : 0);
  530                 }
  531         } while (error != 0);
  532         mountroothook_destroy();
  533 
  534         /*
  535          * Initialise the time-of-day clock, passing the time recorded
  536          * in the root filesystem (if any) for use by systems that
  537          * don't have a non-volatile time-of-day device.
  538          */
  539         inittodr(rootfstime);
  540 
  541         CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;
  542         CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++;
  543 
  544         /*
  545          * Get the vnode for '/'.  Set filedesc0.fd_fd.fd_cdir to
  546          * reference it.
  547          */
  548         error = VFS_ROOT(CIRCLEQ_FIRST(&mountlist), &rootvnode);
  549         if (error)
  550                 panic("cannot find root vnode, error=%d", error);
  551         cwdi0.cwdi_cdir = rootvnode;
  552         VREF(cwdi0.cwdi_cdir);
  553         VOP_UNLOCK(rootvnode, 0);
  554         cwdi0.cwdi_rdir = NULL;
  555 
  556         /*
  557          * Now that root is mounted, we can fixup initproc's CWD
  558          * info.  All other processes are kthreads, which merely
  559          * share proc0's CWD info.
  560          */
  561         initproc->p_cwdi->cwdi_cdir = rootvnode;
  562         VREF(initproc->p_cwdi->cwdi_cdir);
  563         initproc->p_cwdi->cwdi_rdir = NULL;
  564 
  565         /*
  566          * Now can look at time, having had a chance to verify the time
  567          * from the file system.  Reset p->p_rtime as it may have been
  568          * munched in mi_switch() after the time got set.
  569          */
  570         proclist_lock_read();
  571         s = splsched();
  572         LIST_FOREACH(p, &allproc, p_list) {
  573                 KASSERT((p->p_flag & P_MARKER) == 0);
  574                 p->p_stats->p_start = mono_time = boottime = time;
  575                 LIST_FOREACH(l, &p->p_lwps, l_sibling) {
  576                         if (l->l_cpu != NULL)
  577                                 l->l_cpu->ci_schedstate.spc_runtime = time;
  578                 }
  579                 p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
  580         }
  581         splx(s);
  582         proclist_unlock_read();
  583 
  584         /* Create the pageout daemon kernel thread. */
  585         uvm_swap_init();
  586         if (kthread_create1(uvm_pageout, NULL, NULL, "pagedaemon"))
  587                 panic("fork pagedaemon");
  588 
  589         /* Create the filesystem syncer kernel thread. */
  590         if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
  591                 panic("fork syncer");
  592 
  593         /* Create the aiodone daemon kernel thread. */
  594         if (kthread_create1(uvm_aiodone_daemon, NULL, &uvm.aiodoned_proc,
  595             "aiodoned"))
  596                 panic("fork aiodoned");
  597 
  598 #if defined(MULTIPROCESSOR)
  599         /* Boot the secondary processors. */
  600         cpu_boot_secondary_processors();
  601 #endif
  602 
  603         /* Initialize exec structures */
  604         exec_init(1);
  605 
  606         /*
  607          * Okay, now we can let init(8) exec!  It's off to userland!
  608          */
  609         start_init_exec = 1;
  610         wakeup((void *)&start_init_exec);
  611 
  612         /* The scheduler is an infinite loop. */
  613         uvm_scheduler();
  614         /* NOTREACHED */
  615 }
  616 
  617 void
  618 setrootfstime(time_t t)
  619 {
  620         rootfstime = t;
  621 }
  622 
  623 static void
  624 check_console(struct proc *p)
  625 {
  626         struct nameidata nd;
  627         int error;
  628 
  629         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
  630         error = namei(&nd);
  631         if (error == 0)
  632                 vrele(nd.ni_vp);
  633         else if (error == ENOENT)
  634                 printf("warning: no /dev/console\n");
  635         else
  636                 printf("warning: lookup /dev/console: error %d\n", error);
  637 }
  638 
  639 /*
  640  * List of paths to try when searching for "init".
  641  */
  642 static const char *initpaths[] = {
  643         "/sbin/init",
  644         "/sbin/oinit",
  645         "/sbin/init.bak",
  646         NULL,
  647 };
  648 
  649 /*
  650  * Start the initial user process; try exec'ing each pathname in "initpaths".
  651  * The program is invoked with one argument containing the boot flags.
  652  */
  653 static void
  654 start_init(void *arg)
  655 {
  656         struct lwp *l = arg;
  657         struct proc *p = l->l_proc;
  658         vaddr_t addr;
  659         struct sys_execve_args /* {
  660                 syscallarg(const char *) path;
  661                 syscallarg(char * const *) argp;
  662                 syscallarg(char * const *) envp;
  663         } */ args;
  664         int options, i, error;
  665         register_t retval[2];
  666         char flags[4], *flagsp;
  667         const char *path, *slash;
  668         char *ucp, **uap, *arg0, *arg1 = NULL;
  669         char ipath[129];
  670         int ipx, len;
  671 
  672         /*
  673          * Now in process 1.
  674          */
  675         strncpy(p->p_comm, "init", MAXCOMLEN);
  676 
  677         /*
  678          * Wait for main() to tell us that it's safe to exec.
  679          */
  680         while (start_init_exec == 0)
  681                 (void) tsleep((void *)&start_init_exec, PWAIT, "initexec", 0);
  682 
  683         /*
  684          * This is not the right way to do this.  We really should
  685          * hand-craft a descriptor onto /dev/console to hand to init,
  686          * but that's a _lot_ more work, and the benefit from this easy
  687          * hack makes up for the "good is the enemy of the best" effect.
  688          */
  689         check_console(p);
  690 
  691         /*
  692          * Need just enough stack to hold the faked-up "execve()" arguments.
  693          */
  694         addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE);
  695         if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
  696                     NULL, UVM_UNKNOWN_OFFSET, 0,
  697                     UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
  698                     UVM_ADV_NORMAL,
  699                     UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
  700                 panic("init: couldn't allocate argument space");
  701         p->p_vmspace->vm_maxsaddr = (caddr_t)STACK_MAX(addr, PAGE_SIZE);
  702 
  703         ipx = 0;
  704         while (1) {
  705                 if (boothowto & RB_ASKNAME) {
  706                         printf("init path");
  707                         if (initpaths[ipx])
  708                                 printf(" (default %s)", initpaths[ipx]);
  709                         printf(": ");
  710                         len = cngetsn(ipath, sizeof(ipath)-1);
  711                         if (len == 0) {
  712                                 if (initpaths[ipx])
  713                                         path = initpaths[ipx++];
  714                                 else
  715                                         continue;
  716                         } else {
  717                                 ipath[len] = '\0';
  718                                 path = ipath;
  719                         }
  720                 } else {
  721                         if ((path = initpaths[ipx++]) == NULL)
  722                                 break;
  723                 }
  724 
  725                 ucp = (char *)USRSTACK;
  726 
  727                 /*
  728                  * Construct the boot flag argument.
  729                  */
  730                 flagsp = flags;
  731                 *flagsp++ = '-';
  732                 options = 0;
  733 
  734                 if (boothowto & RB_SINGLE) {
  735                         *flagsp++ = 's';
  736                         options = 1;
  737                 }
  738 #ifdef notyet
  739                 if (boothowto & RB_FASTBOOT) {
  740                         *flagsp++ = 'f';
  741                         options = 1;
  742                 }
  743 #endif
  744 
  745                 /*
  746                  * Move out the flags (arg 1), if necessary.
  747                  */
  748                 if (options != 0) {
  749                         *flagsp++ = '\0';
  750                         i = flagsp - flags;
  751 #ifdef DEBUG
  752                         printf("init: copying out flags `%s' %d\n", flags, i);
  753 #endif
  754                         arg1 = STACK_ALLOC(ucp, i);
  755                         ucp = STACK_MAX(arg1, i);
  756                         (void)copyout((caddr_t)flags, arg1, i);
  757                 }
  758 
  759                 /*
  760                  * Move out the file name (also arg 0).
  761                  */
  762                 i = strlen(path) + 1;
  763 #ifdef DEBUG
  764                 printf("init: copying out path `%s' %d\n", path, i);
  765 #else
  766                 if (boothowto & RB_ASKNAME || path != initpaths[0])
  767                         printf("init: trying %s\n", path);
  768 #endif
  769                 arg0 = STACK_ALLOC(ucp, i);
  770                 ucp = STACK_MAX(arg0, i);
  771                 (void)copyout((caddr_t)path, arg0, i);
  772 
  773                 /*
  774                  * Move out the arg pointers.
  775                  */
  776                 ucp = (caddr_t)STACK_ALIGN(ucp, ALIGNBYTES);
  777                 uap = (char **)STACK_ALLOC(ucp, sizeof(char *) * 3);
  778                 SCARG(&args, path) = arg0;
  779                 SCARG(&args, argp) = uap;
  780                 SCARG(&args, envp) = NULL;
  781                 slash = strrchr(path, '/');
  782                 if (slash)
  783                         (void)suword((caddr_t)uap++,
  784                             (long)arg0 + (slash + 1 - path));
  785                 else
  786                         (void)suword((caddr_t)uap++, (long)arg0);
  787                 if (options != 0)
  788                         (void)suword((caddr_t)uap++, (long)arg1);
  789                 (void)suword((caddr_t)uap++, 0);        /* terminator */
  790 
  791                 /*
  792                  * Now try to exec the program.  If can't for any reason
  793                  * other than it doesn't exist, complain.
  794                  */
  795                 error = sys_execve(LIST_FIRST(&p->p_lwps), &args, retval);
  796                 if (error == 0 || error == EJUSTRETURN) {
  797                         KERNEL_PROC_UNLOCK(l);
  798                         return;
  799                 }
  800                 printf("exec %s: error %d\n", path, error);
  801         }
  802         printf("init: not found\n");
  803         panic("no init");
  804 }

Cache object: 47c5c66429f668c483a45bd9c43decc9


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