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.371.2.5 2010/12/21 22:21:42 riz Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   26  * POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
   31  *      The Regents of the University of California.  All rights reserved.
   32  * (c) UNIX System Laboratories, Inc.
   33  * All or some portions of this file are derived from material licensed
   34  * to the University of California by American Telephone and Telegraph
   35  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   36  * the permission of UNIX System Laboratories, Inc.
   37  *
   38  * Redistribution and use in source and binary forms, with or without
   39  * modification, are permitted provided that the following conditions
   40  * are met:
   41  * 1. Redistributions of source code must retain the above copyright
   42  *    notice, this list of conditions and the following disclaimer.
   43  * 2. Redistributions in binary form must reproduce the above copyright
   44  *    notice, this list of conditions and the following disclaimer in the
   45  *    documentation and/or other materials provided with the distribution.
   46  * 3. Neither the name of the University nor the names of its contributors
   47  *    may be used to endorse or promote products derived from this software
   48  *    without specific prior written permission.
   49  *
   50  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   51  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   52  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   53  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   54  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   57  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   58  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   59  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   60  * SUCH DAMAGE.
   61  *
   62  *      @(#)init_main.c 8.16 (Berkeley) 5/14/95
   63  */
   64 
   65 /*
   66  * Copyright (c) 1995 Christopher G. Demetriou.  All rights reserved.
   67  *
   68  * Redistribution and use in source and binary forms, with or without
   69  * modification, are permitted provided that the following conditions
   70  * are met:
   71  * 1. Redistributions of source code must retain the above copyright
   72  *    notice, this list of conditions and the following disclaimer.
   73  * 2. Redistributions in binary form must reproduce the above copyright
   74  *    notice, this list of conditions and the following disclaimer in the
   75  *    documentation and/or other materials provided with the distribution.
   76  * 3. All advertising materials mentioning features or use of this software
   77  *    must display the following acknowledgement:
   78  *      This product includes software developed by the University of
   79  *      California, Berkeley and its contributors.
   80  * 4. Neither the name of the University nor the names of its contributors
   81  *    may be used to endorse or promote products derived from this software
   82  *    without specific prior written permission.
   83  *
   84  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   85  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   86  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   87  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   88  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   89  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   90  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   91  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   92  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   93  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   94  * SUCH DAMAGE.
   95  *
   96  *      @(#)init_main.c 8.16 (Berkeley) 5/14/95
   97  */
   98 
   99 #include <sys/cdefs.h>
  100 __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.371.2.5 2010/12/21 22:21:42 riz Exp $");
  101 
  102 #include "opt_ddb.h"
  103 #include "opt_ipsec.h"
  104 #include "opt_ntp.h"
  105 #include "opt_pipe.h"
  106 #include "opt_posix.h"
  107 #include "opt_syscall_debug.h"
  108 #include "opt_sysv.h"
  109 #include "opt_fileassoc.h"
  110 #include "opt_ktrace.h"
  111 #include "opt_pax.h"
  112 #include "opt_wapbl.h"
  113 
  114 #include "rnd.h"
  115 #include "ksyms.h"
  116 #include "sysmon_envsys.h"
  117 #include "sysmon_power.h"
  118 #include "sysmon_taskq.h"
  119 #include "sysmon_wdog.h"
  120 #include "veriexec.h"
  121 
  122 #include <sys/param.h>
  123 #include <sys/acct.h>
  124 #include <sys/filedesc.h>
  125 #include <sys/file.h>
  126 #include <sys/errno.h>
  127 #include <sys/callout.h>
  128 #include <sys/cpu.h>
  129 #include <sys/kernel.h>
  130 #include <sys/mount.h>
  131 #include <sys/proc.h>
  132 #include <sys/kthread.h>
  133 #include <sys/resourcevar.h>
  134 #include <sys/signalvar.h>
  135 #include <sys/systm.h>
  136 #include <sys/vnode.h>
  137 #include <sys/fstrans.h>
  138 #include <sys/tty.h>
  139 #include <sys/conf.h>
  140 #include <sys/disklabel.h>
  141 #include <sys/buf.h>
  142 #include <sys/device.h>
  143 #include <sys/exec.h>
  144 #include <sys/socketvar.h>
  145 #include <sys/protosw.h>
  146 #include <sys/percpu.h>
  147 #include <sys/pset.h>
  148 #include <sys/sysctl.h>
  149 #include <sys/reboot.h>
  150 #include <sys/user.h>
  151 #include <sys/sysctl.h>
  152 #include <sys/event.h>
  153 #include <sys/mbuf.h>
  154 #include <sys/sched.h>
  155 #include <sys/sleepq.h>
  156 #include <sys/iostat.h>
  157 #include <sys/vmem.h>
  158 #include <sys/uuid.h>
  159 #include <sys/extent.h>
  160 #include <sys/disk.h>
  161 #include <sys/mqueue.h>
  162 #include <sys/msgbuf.h>
  163 #include <sys/module.h>
  164 #include <sys/event.h>
  165 #include <sys/lockf.h>
  166 #include <sys/once.h>
  167 #include <sys/ksyms.h>
  168 #include <sys/uidinfo.h>
  169 #ifdef FAST_IPSEC
  170 #include <netipsec/ipsec.h>
  171 #endif
  172 #ifdef SYSVSHM
  173 #include <sys/shm.h>
  174 #endif
  175 #ifdef SYSVSEM
  176 #include <sys/sem.h>
  177 #endif
  178 #ifdef SYSVMSG
  179 #include <sys/msg.h>
  180 #endif
  181 #ifdef P1003_1B_SEMAPHORE
  182 #include <sys/ksem.h>
  183 #endif
  184 #include <sys/domain.h>
  185 #include <sys/namei.h>
  186 #if NRND > 0
  187 #include <sys/rnd.h>
  188 #endif
  189 #include <sys/pipe.h>
  190 #ifdef LKM
  191 #include <sys/lkm.h>
  192 #endif
  193 #if NVERIEXEC > 0
  194 #include <sys/verified_exec.h>
  195 #endif /* NVERIEXEC > 0 */
  196 #ifdef KTRACE
  197 #include <sys/ktrace.h>
  198 #endif
  199 #include <sys/kauth.h>
  200 #ifdef WAPBL
  201 #include <sys/wapbl.h>
  202 #endif
  203 #include <net80211/ieee80211_netbsd.h>
  204 
  205 #include <sys/syscall.h>
  206 #include <sys/syscallargs.h>
  207 
  208 #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR)
  209 #include <sys/pax.h>
  210 #endif /* PAX_MPROTECT || PAX_SEGVGUARD || PAX_ASLR */
  211 
  212 #include <ufs/ufs/quota.h>
  213 
  214 #include <miscfs/genfs/genfs.h>
  215 #include <miscfs/syncfs/syncfs.h>
  216 
  217 #include <sys/cpu.h>
  218 
  219 #include <uvm/uvm.h>
  220 
  221 #if NSYSMON_TASKQ > 0
  222 #include <dev/sysmon/sysmon_taskq.h>
  223 #endif
  224 
  225 #include <dev/cons.h>
  226 
  227 #if NSYSMON_ENVSYS > 0 || NSYSMON_POWER > 0 || NSYSMON_WDOG > 0
  228 #include <dev/sysmon/sysmonvar.h>
  229 #endif
  230 
  231 #include <net/if.h>
  232 #include <net/raw_cb.h>
  233 
  234 #include <secmodel/secmodel.h>
  235 
  236 extern struct proc proc0;
  237 extern struct lwp lwp0;
  238 extern struct cwdinfo cwdi0;
  239 extern time_t rootfstime;
  240 
  241 #ifndef curlwp
  242 struct  lwp *curlwp = &lwp0;
  243 #endif
  244 struct  proc *initproc;
  245 
  246 struct  vnode *rootvp, *swapdev_vp;
  247 int     boothowto;
  248 int     cold = 1;                       /* still working on startup */
  249 struct timeval boottime;                /* time at system startup - will only follow settime deltas */
  250 
  251 int     start_init_exec;                /* semaphore for start_init() */
  252 
  253 static void check_console(struct lwp *l);
  254 static void start_init(void *);
  255 void main(void);
  256 
  257 void __secmodel_none(void);
  258 __weak_alias(secmodel_start,__secmodel_none);
  259 void
  260 __secmodel_none(void)
  261 {
  262         return;
  263 }
  264 
  265 /*
  266  * System startup; initialize the world, create process 0, mount root
  267  * filesystem, and fork to create init and pagedaemon.  Most of the
  268  * hard work is done in the lower-level initialization routines including
  269  * startup(), which does memory initialization and autoconfiguration.
  270  */
  271 void
  272 main(void)
  273 {
  274         struct timeval time;
  275         struct lwp *l;
  276         struct proc *p;
  277         int s, error;
  278 #ifdef NVNODE_IMPLICIT
  279         int usevnodes;
  280 #endif
  281         CPU_INFO_ITERATOR cii;
  282         struct cpu_info *ci;
  283 
  284         l = &lwp0;
  285 #ifndef LWP0_CPU_INFO
  286         l->l_cpu = curcpu();
  287 #endif
  288 
  289         /*
  290          * Attempt to find console and initialize
  291          * in case of early panic or other messages.
  292          */
  293         consinit();
  294 
  295         kernel_lock_init();
  296         once_init();
  297         mutex_init(&cpu_lock, MUTEX_DEFAULT, IPL_NONE);
  298 
  299         uvm_init();
  300 
  301         percpu_init();
  302 
  303         /* Initialize lock caches. */
  304         mutex_obj_init();
  305 
  306 #if NKSYMS > 0
  307         ksyms_init_finalize();
  308 #endif
  309 
  310         /* Initialize the extent manager. */
  311         extent_init();
  312 
  313         /* Do machine-dependent initialization. */
  314         cpu_startup();
  315 
  316         /* Initialize callouts, part 1. */
  317         callout_startup();
  318 
  319         /*
  320          * Initialize the kernel authorization subsystem and start the
  321          * default security model, if any. We need to do this early
  322          * enough so that subsystems relying on any of the aforementioned
  323          * can work properly. Since the security model may dictate the
  324          * credential inheritance policy, it is needed at least before
  325          * any process is created, specifically proc0.
  326          */
  327         kauth_init();
  328         secmodel_start();
  329 
  330         /* Initialize the buffer cache */
  331         bufinit();
  332 
  333         /* Initialize sockets. */
  334         soinit();
  335 
  336         /*
  337          * The following things must be done before autoconfiguration.
  338          */
  339         evcnt_init();           /* initialize event counters */
  340 #if NRND > 0
  341         rnd_init();             /* initialize random number generator */
  342 #endif
  343 
  344         /* Initialize process and pgrp structures. */
  345         procinit();
  346         lwpinit();
  347 
  348         /* Initialize signal-related data structures. */
  349         signal_init();
  350 
  351         /* Initialize resource management. */
  352         resource_init();
  353 
  354         /* Create process 0 (the swapper). */
  355         proc0_init();
  356 
  357         /* Initialize the UID hash table. */
  358         uid_init();
  359 
  360         /* Charge root for one process. */
  361         (void)chgproccnt(0, 1);
  362 
  363         /* Initialize timekeeping. */
  364         time_init();
  365 
  366         /* Initialize the run queues, turnstiles and sleep queues. */
  367         sched_rqinit();
  368         turnstile_init();
  369         sleeptab_init(&sleeptab);
  370 
  371         /* Initialize processor-sets */
  372         psets_init();
  373 
  374         /* MI initialization of the boot cpu */
  375         error = mi_cpu_attach(curcpu());
  376         KASSERT(error == 0);
  377 
  378         /* Initialize timekeeping, part 2. */
  379         time_init2();
  380 
  381         /*
  382          * Initialize mbuf's.  Do this now because we might attempt to
  383          * allocate mbufs or mbuf clusters during autoconfiguration.
  384          */
  385         mbinit();
  386 
  387         /* Initialize the sysctl subsystem. */
  388         sysctl_init();
  389 
  390         /* Initialize I/O statistics. */
  391         iostat_init();
  392 
  393         /* Initialize the log device. */
  394         loginit();
  395 
  396         /* Start module system. */
  397         module_init();
  398 
  399         /* Initialize the file systems. */
  400 #ifdef NVNODE_IMPLICIT
  401         /*
  402          * If maximum number of vnodes in namei vnode cache is not explicitly
  403          * defined in kernel config, adjust the number such as we use roughly
  404          * 10% of memory for vnodes and associated data structures in the
  405          * assumed worst case.  Do not provide fewer than NVNODE vnodes.
  406          */
  407         usevnodes =
  408             calc_cache_size(kernel_map, 10, VNODE_VA_MAXPCT) / VNODE_COST;
  409         if (usevnodes > desiredvnodes)
  410                 desiredvnodes = usevnodes;
  411 #endif
  412         vfsinit();
  413         lf_init();
  414 
  415         /* Initialize fstrans. */
  416         fstrans_init();
  417 
  418         /* Initialize the file descriptor system. */
  419         fd_sys_init();
  420 
  421         /* Initialize kqueue. */
  422         kqueue_init();
  423 
  424         /* Initialize asynchronous I/O. */
  425         aio_sysinit();
  426 
  427         /* Initialize message queues. */
  428         mqueue_sysinit();
  429 
  430         /* Initialize the system monitor subsystems. */
  431 #if NSYSMON_TASKQ > 0
  432         sysmon_task_queue_preinit();
  433 #endif
  434 
  435 #if NSYSMON_ENVSYS > 0
  436         sysmon_envsys_init();
  437 #endif
  438 
  439 #if NSYSMON_POWER > 0
  440         sysmon_power_init();
  441 #endif
  442 
  443 #if NSYSMON_WDOG > 0
  444         sysmon_wdog_init();
  445 #endif
  446 
  447         inittimecounter();
  448         ntp_init();
  449 
  450         /* Initialize the device switch tables. */
  451         devsw_init();
  452 
  453         /* Initialize tty subsystem. */
  454         tty_init();
  455         ttyldisc_init();
  456 
  457         /* Initialize the buffer cache, part 2. */
  458         bufinit2();
  459 
  460         /* Initialize the disk wedge subsystem. */
  461         dkwedge_init();
  462 
  463         /* Initialize interfaces. */
  464         ifinit1();
  465 
  466         /* Configure the system hardware.  This will enable interrupts. */
  467         configure();
  468 
  469         ssp_init();
  470 
  471         configure2();
  472 
  473         ubc_init();             /* must be after autoconfig */
  474 
  475 #ifdef SYSVSHM
  476         /* Initialize System V style shared memory. */
  477         shminit();
  478 #endif
  479 
  480         vmem_rehash_start();    /* must be before exec_init */
  481 
  482         /* Initialize exec structures */
  483         exec_init(1);           /* seminit calls exithook_establish() */
  484 
  485 #ifdef SYSVSEM
  486         /* Initialize System V style semaphores. */
  487         seminit();
  488 #endif
  489 
  490 #ifdef SYSVMSG
  491         /* Initialize System V style message queues. */
  492         msginit();
  493 #endif
  494 
  495 #ifdef P1003_1B_SEMAPHORE
  496         /* Initialize posix semaphores */
  497         ksem_init();
  498 #endif
  499 
  500 #if NVERIEXEC > 0
  501         /*
  502          * Initialise the Veriexec subsystem.
  503          */
  504         veriexec_init();
  505 #endif /* NVERIEXEC > 0 */
  506 
  507 #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR)
  508         pax_init();
  509 #endif /* PAX_MPROTECT || PAX_SEGVGUARD || PAX_ASLR */
  510 
  511 #ifdef  FAST_IPSEC
  512         /* Attach network crypto subsystem */
  513         ipsec_attach();
  514 #endif
  515 
  516         /*
  517          * Initialize protocols.  Block reception of incoming packets
  518          * until everything is ready.
  519          */
  520         s = splnet();
  521         ifinit();
  522         domaininit();
  523         if_attachdomain();
  524         splx(s);
  525 
  526 #ifdef GPROF
  527         /* Initialize kernel profiling. */
  528         kmstartup();
  529 #endif
  530 
  531         /* Initialize system accounting. */
  532         acct_init();
  533 
  534 #ifndef PIPE_SOCKETPAIR
  535         /* Initialize pipes. */
  536         pipe_init();
  537 #endif
  538 
  539 #ifdef KTRACE
  540         /* Initialize ktrace. */
  541         ktrinit();
  542 #endif
  543 
  544         /* Initialize the UUID system calls. */
  545         uuid_init();
  546 
  547 #ifdef WAPBL
  548         /* Initialize write-ahead physical block logging. */
  549         wapbl_init();
  550 #endif
  551 
  552         /*
  553          * Create process 1 (init(8)).  We do this now, as Unix has
  554          * historically had init be process 1, and changing this would
  555          * probably upset a lot of people.
  556          *
  557          * Note that process 1 won't immediately exec init(8), but will
  558          * wait for us to inform it that the root file system has been
  559          * mounted.
  560          */
  561         if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, &initproc))
  562                 panic("fork init");
  563 
  564         /*
  565          * Load any remaining builtin modules, and hand back temporary
  566          * storage to the VM system.
  567          */
  568         module_init_class(MODULE_CLASS_ANY);
  569 
  570         /*
  571          * Finalize configuration now that all real devices have been
  572          * found.  This needs to be done before the root device is
  573          * selected, since finalization may create the root device.
  574          */
  575         config_finalize();
  576 
  577         /*
  578          * Now that autoconfiguration has completed, we can determine
  579          * the root and dump devices.
  580          */
  581         cpu_rootconf();
  582         cpu_dumpconf();
  583 
  584         /* Mount the root file system. */
  585         do {
  586                 domountroothook();
  587                 if ((error = vfs_mountroot())) {
  588                         printf("cannot mount root, error = %d\n", error);
  589                         boothowto |= RB_ASKNAME;
  590                         setroot(root_device,
  591                             (rootdev != NODEV) ? DISKPART(rootdev) : 0);
  592                 }
  593         } while (error != 0);
  594         mountroothook_destroy();
  595 
  596         /*
  597          * Initialise the time-of-day clock, passing the time recorded
  598          * in the root filesystem (if any) for use by systems that
  599          * don't have a non-volatile time-of-day device.
  600          */
  601         inittodr(rootfstime);
  602 
  603         CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;
  604         CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++;
  605 
  606         /*
  607          * Get the vnode for '/'.  Set filedesc0.fd_fd.fd_cdir to
  608          * reference it.
  609          */
  610         error = VFS_ROOT(CIRCLEQ_FIRST(&mountlist), &rootvnode);
  611         if (error)
  612                 panic("cannot find root vnode, error=%d", error);
  613         cwdi0.cwdi_cdir = rootvnode;
  614         VREF(cwdi0.cwdi_cdir);
  615         VOP_UNLOCK(rootvnode, 0);
  616         cwdi0.cwdi_rdir = NULL;
  617 
  618         /*
  619          * Now that root is mounted, we can fixup initproc's CWD
  620          * info.  All other processes are kthreads, which merely
  621          * share proc0's CWD info.
  622          */
  623         initproc->p_cwdi->cwdi_cdir = rootvnode;
  624         VREF(initproc->p_cwdi->cwdi_cdir);
  625         initproc->p_cwdi->cwdi_rdir = NULL;
  626 
  627         /*
  628          * Now can look at time, having had a chance to verify the time
  629          * from the file system.  Reset l->l_rtime as it may have been
  630          * munched in mi_switch() after the time got set.
  631          */
  632         getmicrotime(&time);
  633         boottime = time;
  634         mutex_enter(proc_lock);
  635         LIST_FOREACH(p, &allproc, p_list) {
  636                 KASSERT((p->p_flag & PK_MARKER) == 0);
  637                 mutex_enter(p->p_lock);
  638                 p->p_stats->p_start = time;
  639                 LIST_FOREACH(l, &p->p_lwps, l_sibling) {
  640                         lwp_lock(l);
  641                         memset(&l->l_rtime, 0, sizeof(l->l_rtime));
  642                         lwp_unlock(l);
  643                 }
  644                 mutex_exit(p->p_lock);
  645         }
  646         mutex_exit(proc_lock);
  647         binuptime(&curlwp->l_stime);
  648 
  649         for (CPU_INFO_FOREACH(cii, ci)) {
  650                 ci->ci_schedstate.spc_lastmod = time_second;
  651         }
  652 
  653         /* Create the pageout daemon kernel thread. */
  654         uvm_swap_init();
  655         if (kthread_create(PRI_PGDAEMON, KTHREAD_MPSAFE, NULL, uvm_pageout,
  656             NULL, NULL, "pgdaemon"))
  657                 panic("fork pagedaemon");
  658 
  659         /* Create the filesystem syncer kernel thread. */
  660         if (kthread_create(PRI_IOFLUSH, KTHREAD_MPSAFE, NULL, sched_sync,
  661             NULL, NULL, "ioflush"))
  662                 panic("fork syncer");
  663 
  664         /* Create the aiodone daemon kernel thread. */
  665         if (workqueue_create(&uvm.aiodone_queue, "aiodoned",
  666             uvm_aiodone_worker, NULL, PRI_VM, IPL_NONE, WQ_MPSAFE))
  667                 panic("fork aiodoned");
  668 
  669         /*
  670          * Okay, now we can let init(8) exec!  It's off to userland!
  671          */
  672         mutex_enter(proc_lock);
  673         start_init_exec = 1;
  674         cv_broadcast(&lbolt);
  675         mutex_exit(proc_lock);
  676 
  677         /* The scheduler is an infinite loop. */
  678         uvm_scheduler();
  679         /* NOTREACHED */
  680 }
  681 
  682 static void
  683 check_console(struct lwp *l)
  684 {
  685         struct nameidata nd;
  686         int error;
  687 
  688         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console");
  689         error = namei(&nd);
  690         if (error == 0)
  691                 vrele(nd.ni_vp);
  692         else if (error == ENOENT)
  693                 printf("warning: no /dev/console\n");
  694         else
  695                 printf("warning: lookup /dev/console: error %d\n", error);
  696 }
  697 
  698 /*
  699  * List of paths to try when searching for "init".
  700  */
  701 static const char * const initpaths[] = {
  702         "/sbin/init",
  703         "/sbin/oinit",
  704         "/sbin/init.bak",
  705         NULL,
  706 };
  707 
  708 /*
  709  * Start the initial user process; try exec'ing each pathname in "initpaths".
  710  * The program is invoked with one argument containing the boot flags.
  711  */
  712 static void
  713 start_init(void *arg)
  714 {
  715         struct lwp *l = arg;
  716         struct proc *p = l->l_proc;
  717         vaddr_t addr;
  718         struct sys_execve_args /* {
  719                 syscallarg(const char *) path;
  720                 syscallarg(char * const *) argp;
  721                 syscallarg(char * const *) envp;
  722         } */ args;
  723         int options, i, error;
  724         register_t retval[2];
  725         char flags[4], *flagsp;
  726         const char *path, *slash;
  727         char *ucp, **uap, *arg0, *arg1 = NULL;
  728         char ipath[129];
  729         int ipx, len;
  730 
  731         /*
  732          * Now in process 1.
  733          */
  734         strncpy(p->p_comm, "init", MAXCOMLEN);
  735 
  736         /*
  737          * Wait for main() to tell us that it's safe to exec.
  738          */
  739         mutex_enter(proc_lock);
  740         while (start_init_exec == 0)
  741                 cv_wait(&lbolt, proc_lock);
  742         mutex_exit(proc_lock);
  743 
  744         /*
  745          * This is not the right way to do this.  We really should
  746          * hand-craft a descriptor onto /dev/console to hand to init,
  747          * but that's a _lot_ more work, and the benefit from this easy
  748          * hack makes up for the "good is the enemy of the best" effect.
  749          */
  750         check_console(l);
  751 
  752         /*
  753          * Need just enough stack to hold the faked-up "execve()" arguments.
  754          */
  755         addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE);
  756         if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
  757                     NULL, UVM_UNKNOWN_OFFSET, 0,
  758                     UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
  759                     UVM_ADV_NORMAL,
  760                     UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
  761                 panic("init: couldn't allocate argument space");
  762         p->p_vmspace->vm_maxsaddr = (void *)STACK_MAX(addr, PAGE_SIZE);
  763 
  764         ipx = 0;
  765         while (1) {
  766                 if (boothowto & RB_ASKNAME) {
  767                         printf("init path");
  768                         if (initpaths[ipx])
  769                                 printf(" (default %s)", initpaths[ipx]);
  770                         printf(": ");
  771                         len = cngetsn(ipath, sizeof(ipath)-1);
  772                         if (len == 4 && strcmp(ipath, "halt") == 0) {
  773                                 cpu_reboot(RB_HALT, NULL);
  774                         } else if (len == 6 && strcmp(ipath, "reboot") == 0) {
  775                                 cpu_reboot(0, NULL);
  776 #if defined(DDB)
  777                         } else if (len == 3 && strcmp(ipath, "ddb") == 0) {
  778                                 console_debugger();
  779                                 continue;
  780 #endif
  781                         } else if (len > 0 && ipath[0] == '/') {
  782                                 ipath[len] = '\0';
  783                                 path = ipath;
  784                         } else if (len == 0 && initpaths[ipx] != NULL) {
  785                                 path = initpaths[ipx++];
  786                         } else {
  787                                 printf("use absolute path, ");
  788 #if defined(DDB)
  789                                 printf("\"ddb\", ");
  790 #endif
  791                                 printf("\"halt\", or \"reboot\"\n");
  792                                 continue;
  793                         }
  794                 } else {
  795                         if ((path = initpaths[ipx++]) == NULL) {
  796                                 ipx = 0;
  797                                 boothowto |= RB_ASKNAME;
  798                                 continue;
  799                         }
  800                 }
  801 
  802                 ucp = (char *)USRSTACK;
  803 
  804                 /*
  805                  * Construct the boot flag argument.
  806                  */
  807                 flagsp = flags;
  808                 *flagsp++ = '-';
  809                 options = 0;
  810 
  811                 if (boothowto & RB_SINGLE) {
  812                         *flagsp++ = 's';
  813                         options = 1;
  814                 }
  815 #ifdef notyet
  816                 if (boothowto & RB_FASTBOOT) {
  817                         *flagsp++ = 'f';
  818                         options = 1;
  819                 }
  820 #endif
  821 
  822                 /*
  823                  * Move out the flags (arg 1), if necessary.
  824                  */
  825                 if (options != 0) {
  826                         *flagsp++ = '\0';
  827                         i = flagsp - flags;
  828 #ifdef DEBUG
  829                         aprint_normal("init: copying out flags `%s' %d\n", flags, i);
  830 #endif
  831                         arg1 = STACK_ALLOC(ucp, i);
  832                         ucp = STACK_MAX(arg1, i);
  833                         (void)copyout((void *)flags, arg1, i);
  834                 }
  835 
  836                 /*
  837                  * Move out the file name (also arg 0).
  838                  */
  839                 i = strlen(path) + 1;
  840 #ifdef DEBUG
  841                 aprint_normal("init: copying out path `%s' %d\n", path, i);
  842 #else
  843                 if (boothowto & RB_ASKNAME || path != initpaths[0])
  844                         printf("init: trying %s\n", path);
  845 #endif
  846                 arg0 = STACK_ALLOC(ucp, i);
  847                 ucp = STACK_MAX(arg0, i);
  848                 (void)copyout(path, arg0, i);
  849 
  850                 /*
  851                  * Move out the arg pointers.
  852                  */
  853                 ucp = (void *)STACK_ALIGN(ucp, ALIGNBYTES);
  854                 uap = (char **)STACK_ALLOC(ucp, sizeof(char *) * 3);
  855                 SCARG(&args, path) = arg0;
  856                 SCARG(&args, argp) = uap;
  857                 SCARG(&args, envp) = NULL;
  858                 slash = strrchr(path, '/');
  859                 if (slash)
  860                         (void)suword((void *)uap++,
  861                             (long)arg0 + (slash + 1 - path));
  862                 else
  863                         (void)suword((void *)uap++, (long)arg0);
  864                 if (options != 0)
  865                         (void)suword((void *)uap++, (long)arg1);
  866                 (void)suword((void *)uap++, 0); /* terminator */
  867 
  868                 /*
  869                  * Now try to exec the program.  If can't for any reason
  870                  * other than it doesn't exist, complain.
  871                  */
  872                 error = sys_execve(l, &args, retval);
  873                 if (error == 0 || error == EJUSTRETURN) {
  874                         KERNEL_UNLOCK_LAST(l);
  875                         return;
  876                 }
  877                 printf("exec %s: error %d\n", path, error);
  878         }
  879         printf("init: not found\n");
  880         panic("no init");
  881 }
  882 
  883 /*
  884  * calculate cache size from physmem and vm_map size.
  885  */
  886 vaddr_t
  887 calc_cache_size(struct vm_map *map, int pct, int va_pct)
  888 {
  889         paddr_t t;
  890 
  891         /* XXX should consider competing cache if any */
  892         /* XXX should consider submaps */
  893         t = (uintmax_t)physmem * pct / 100 * PAGE_SIZE;
  894         if (map != NULL) {
  895                 vsize_t vsize;
  896 
  897                 vsize = vm_map_max(map) - vm_map_min(map);
  898                 vsize = (uintmax_t)vsize * va_pct / 100;
  899                 if (t > vsize) {
  900                         t = vsize;
  901                 }
  902         }
  903         return t;
  904 }

Cache object: 851bda0b92b79d316368d438d3eec6c9


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