[BACK]Return to init_main.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Annotation of src/sys/kern/init_main.c, Revision 1.294.2.5

1.294.2.5! yamt        1: /*     $NetBSD$        */
1.61      mycroft     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.
1.224     agc        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.
1.61      mycroft    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:  *
1.118     fvdl       70:  *     @(#)init_main.c 8.16 (Berkeley) 5/14/95
1.61      mycroft    71:  */
1.196     lukem      72:
                     73: #include <sys/cdefs.h>
1.294.2.5! yamt       74: __KERNEL_RCSID(0, "$NetBSD$");
1.115     mrg        75:
1.223     jonathan   76: #include "opt_ipsec.h"
1.267     kardel     77: #include "opt_kcont.h"
1.160     thorpej    78: #include "opt_multiprocessor.h"
1.267     kardel     79: #include "opt_ntp.h"
1.198     jdolecek   80: #include "opt_pipe.h"
1.267     kardel     81: #include "opt_posix.h"
1.172     soren      82: #include "opt_syscall_debug.h"
1.267     kardel     83: #include "opt_sysv.h"
1.292     ad         84: #include "opt_systrace.h"
                     85: #include "opt_fileassoc.h"
                     86: #include "opt_ktrace.h"
1.281     elad       87: #include "opt_pax.h"
1.61      mycroft    88:
1.106     explorer   89: #include "rnd.h"
1.276     dogcow     90: #include "veriexec.h"
1.106     explorer   91:
1.61      mycroft    92: #include <sys/param.h>
1.164     enami      93: #include <sys/acct.h>
1.61      mycroft    94: #include <sys/filedesc.h>
1.131     thorpej    95: #include <sys/file.h>
1.61      mycroft    96: #include <sys/errno.h>
1.162     thorpej    97: #include <sys/callout.h>
1.294.2.5! yamt       98: #include <sys/cpu.h>
1.61      mycroft    99: #include <sys/kernel.h>
1.234     jonathan  100: #include <sys/kcont.h>
1.269     yamt      101: #include <sys/kmem.h>
1.61      mycroft   102: #include <sys/mount.h>
                    103: #include <sys/proc.h>
1.136     thorpej   104: #include <sys/kthread.h>
1.61      mycroft   105: #include <sys/resourcevar.h>
                    106: #include <sys/signalvar.h>
                    107: #include <sys/systm.h>
                    108: #include <sys/vnode.h>
1.288     hannken   109: #include <sys/fstrans.h>
1.87      thorpej   110: #include <sys/tty.h>
1.61      mycroft   111: #include <sys/conf.h>
1.95      thorpej   112: #include <sys/disklabel.h>
1.61      mycroft   113: #include <sys/buf.h>
                    114: #include <sys/device.h>
1.186     jdolecek  115: #include <sys/exec.h>
1.128     thorpej   116: #include <sys/socketvar.h>
1.61      mycroft   117: #include <sys/protosw.h>
                    118: #include <sys/reboot.h>
                    119: #include <sys/user.h>
1.176     thorpej   120: #include <sys/sysctl.h>
1.209     jdolecek  121: #include <sys/event.h>
1.227     jonathan  122: #include <sys/mbuf.h>
1.294.2.2  rmind     123: #include <sys/sched.h>
1.292     ad        124: #include <sys/sleepq.h>
1.284     ad        125: #include <sys/iostat.h>
1.233     junyoung  126: #ifdef FAST_IPSEC
1.223     jonathan  127: #include <netipsec/ipsec.h>
                    128: #endif
1.82      christos  129: #ifdef SYSVSHM
                    130: #include <sys/shm.h>
                    131: #endif
1.233     junyoung  132: #ifdef SYSVSEM
1.82      christos  133: #include <sys/sem.h>
                    134: #endif
                    135: #ifdef SYSVMSG
                    136: #include <sys/msg.h>
                    137: #endif
1.292     ad        138: #ifdef SYSTRACE
                    139: #include <sys/systrace.h>
                    140: #endif
1.217     christos  141: #ifdef P1003_1B_SEMAPHORE
                    142: #include <sys/ksem.h>
                    143: #endif
1.82      christos  144: #include <sys/domain.h>
1.94      mouse     145: #include <sys/namei.h>
1.106     explorer  146: #if NRND > 0
1.103     explorer  147: #include <sys/rnd.h>
1.106     explorer  148: #endif
1.198     jdolecek  149: #ifndef PIPE_SOCKETPAIR
1.192     jdolecek  150: #include <sys/pipe.h>
                    151: #endif
1.210     thorpej   152: #ifdef LKM
                    153: #include <sys/lkm.h>
                    154: #endif
1.273     elad      155: #if NVERIEXEC > 0
1.245     blymn     156: #include <sys/verified_exec.h>
1.273     elad      157: #endif /* NVERIEXEC > 0 */
1.292     ad        158: #ifdef KTRACE
                    159: #include <sys/ktrace.h>
                    160: #endif
                    161: #include <sys/debug.h>
1.266     elad      162: #include <sys/kauth.h>
1.252     skrll     163: #include <net80211/ieee80211_netbsd.h>
1.61      mycroft   164:
1.77      christos  165: #include <sys/syscall.h>
1.68      cgd       166: #include <sys/syscallargs.h>
                    167:
1.282     elad      168: #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD)
1.281     elad      169: #include <sys/pax.h>
1.282     elad      170: #endif /* PAX_MPROTECT || PAX_SEGVGUARD */
1.61      mycroft   171: #include <ufs/ufs/quota.h>
                    172:
1.159     fvdl      173: #include <miscfs/genfs/genfs.h>
                    174: #include <miscfs/syncfs/syncfs.h>
                    175:
1.61      mycroft   176: #include <machine/cpu.h>
                    177:
1.114     mrg       178: #include <uvm/uvm.h>
                    179:
1.202     lukem     180: #include <dev/cons.h>
                    181:
1.81      christos  182: #include <net/if.h>
                    183: #include <net/raw_cb.h>
1.61      mycroft   184:
1.277     elad      185: #include <secmodel/secmodel.h>
                    186:
1.251     junyoung  187: extern struct proc proc0;
                    188: extern struct lwp lwp0;
                    189: extern struct cwdinfo cwdi0;
                    190:
1.216     thorpej   191: #ifndef curlwp
                    192: struct lwp *curlwp = &lwp0;
1.133     pk        193: #endif
1.105     mycroft   194: struct proc *initproc;
1.61      mycroft   195:
                    196: struct vnode *rootvp, *swapdev_vp;
                    197: int    boothowto;
1.156     thorpej   198: int    cold = 1;                       /* still working on startup */
1.272     kardel    199: struct timeval boottime;               /* time at system startup - will only follow settime deltas */
1.239     pk        200: time_t rootfstime;                     /* recorded root fs time, if known */
1.294     ad        201: int    ncpu =  1;                      /* number of CPUs configured, assume 1 */
1.61      mycroft   202:
1.261     perry     203: volatile int start_init_exec;          /* semaphore for start_init() */
1.163     thorpej   204:
1.260     christos  205: static void check_console(struct lwp *l);
1.176     thorpej   206: static void start_init(void *);
                    207: void main(void);
1.76      cgd       208:
1.280     christos  209: #if defined(__SSP__) || defined(__SSP_ALL__)
                    210: long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
                    211: void __stack_chk_fail(void);
                    212:
                    213: void
                    214: __stack_chk_fail(void)
                    215: {
                    216:        panic("stack overflow detected; terminated");
                    217: }
                    218: #endif
                    219:
1.287     elad      220: void __secmodel_none(void);
1.294.2.4  rmind     221: __weak_alias(secmodel_start,__secmodel_none);
1.287     elad      222: void
                    223: __secmodel_none(void)
                    224: {
                    225:        return;
                    226: }
                    227:
1.61      mycroft   228: /*
                    229:  * System startup; initialize the world, create process 0, mount root
                    230:  * filesystem, and fork to create init and pagedaemon.  Most of the
                    231:  * hard work is done in the lower-level initialization routines including
                    232:  * startup(), which does memory initialization and autoconfiguration.
                    233:  */
1.81      christos  234: void
1.176     thorpej   235: main(void)
1.61      mycroft   236: {
1.267     kardel    237: #ifdef __HAVE_TIMECOUNTER
                    238:        struct timeval time;
                    239: #endif
1.216     thorpej   240:        struct lwp *l;
1.144     thorpej   241:        struct proc *p;
1.111     thorpej   242:        struct pdevinit *pdev;
1.204     thorpej   243:        int s, error;
1.61      mycroft   244:        extern struct pdevinit pdevinit[];
1.175     jdolecek  245: #ifdef NVNODE_IMPLICIT
                    246:        int usevnodes;
                    247: #endif
1.294     ad        248: #ifdef MULTIPROCESSOR
                    249:        CPU_INFO_ITERATOR cii;
                    250:        struct cpu_info *ci;
                    251: #endif
1.61      mycroft   252:
                    253:        /*
1.216     thorpej   254:         * Initialize the current LWP pointer (curlwp) before
1.61      mycroft   255:         * any possible traps/probes to simplify trap processing.
                    256:         */
1.216     thorpej   257:        l = &lwp0;
                    258:        curlwp = l;
                    259:        l->l_cpu = curcpu();
                    260:        l->l_proc = &proc0;
                    261:        l->l_lid = 1;
1.233     junyoung  262:
1.61      mycroft   263:        /*
                    264:         * Attempt to find console and initialize
                    265:         * in case of early panic or other messages.
                    266:         */
                    267:        consinit();
                    268:
1.179     thorpej   269:        KERNEL_LOCK_INIT();
                    270:
1.114     mrg       271:        uvm_init();
1.127     thorpej   272:
1.292     ad        273: #ifdef DEBUG
                    274:        debug_init();
                    275: #endif
                    276:
1.269     yamt      277:        kmem_init();
                    278:
1.145     thorpej   279:        /* Do machine-dependent initialization. */
                    280:        cpu_startup();
1.162     thorpej   281:
1.166     enami     282:        /* Initialize callouts. */
                    283:        callout_startup();
1.145     thorpej   284:
1.291     elad      285:        /*
                    286:         * Initialize the kernel authorization subsystem and start the
                    287:         * default security model, if any. We need to do this early
                    288:         * enough so that subsystems relying on any of the aforementioned
                    289:         * can work properly. Since the security model may dictate the
                    290:         * credential inheritance policy, it is needed at least before
                    291:         * any process is created, specifically proc0.
                    292:         */
1.289     elad      293:        kauth_init();
1.290     elad      294:        secmodel_start();
                    295:
1.228     pk        296:        /* Initialize the buffer cache */
                    297:        bufinit();
                    298:
1.127     thorpej   299:        /*
                    300:         * Initialize mbuf's.  Do this now because we might attempt to
                    301:         * allocate mbufs or mbuf clusters during autoconfiguration.
                    302:         */
                    303:        mbinit();
1.209     jdolecek  304:
1.128     thorpej   305:        /* Initialize sockets. */
                    306:        soinit();
1.127     thorpej   307:
1.235     matt      308: #ifdef KCONT
1.234     jonathan  309:        /* Initialize kcont. */
                    310:         kcont_init();
1.235     matt      311: #endif
1.234     jonathan  312:
1.156     thorpej   313:        /*
1.212     thorpej   314:         * The following things must be done before autoconfiguration.
1.156     thorpej   315:         */
1.212     thorpej   316:        evcnt_init();           /* initialize event counters */
1.106     explorer  317: #if NRND > 0
1.156     thorpej   318:        rnd_init();             /* initialize RNG */
1.106     explorer  319: #endif
1.176     thorpej   320:
1.236     simonb    321:        /* Initialize process and pgrp structures. */
1.63      mycroft   322:        procinit();
1.279     thorpej   323:        lwpinit();
1.210     thorpej   324:
1.251     junyoung  325:        /* Initialize signal-related data structures. */
                    326:        signal_init();
1.61      mycroft   327:
1.251     junyoung  328:        /* Create process 0 (the swapper). */
                    329:        proc0_init();
1.61      mycroft   330:
                    331:        /*
1.63      mycroft   332:         * Charge root for one process.
1.61      mycroft   333:         */
                    334:        (void)chgproccnt(0, 1);
                    335:
1.292     ad        336:        /* Initialize the run queues, turnstiles and sleep queues. */
1.294.2.2  rmind     337:        sched_rqinit();
1.292     ad        338:        turnstile_init();
                    339:        sleeptab_init(&sleeptab);
                    340:
1.294.2.5! yamt      341:        /* MI initialization of the boot cpu */
        !           342:        error = mi_cpu_attach(curcpu());
1.294.2.1  yamt      343:        KASSERT(error == 0);
                    344:
1.292     ad        345:        /* Initialize the sysctl subsystem. */
                    346:        sysctl_init();
1.61      mycroft   347:
1.284     ad        348:        /* Initialize I/O statistics. */
                    349:        iostat_init();
                    350:
1.61      mycroft   351:        /* Initialize the file systems. */
1.194     matt      352: #ifdef NVNODE_IMPLICIT
                    353:        /*
                    354:         * If maximum number of vnodes in namei vnode cache is not explicitly
                    355:         * defined in kernel config, adjust the number such as we use roughly
1.232     tls       356:         * 1.0% of memory for vnode cache (but not less than NVNODE vnodes).
1.194     matt      357:         */
1.232     tls       358:        usevnodes = (ptoa((unsigned)physmem) / 100) / sizeof(struct vnode);
1.205     sommerfe  359:        if (usevnodes > desiredvnodes)
1.194     matt      360:                desiredvnodes = usevnodes;
                    361: #endif
1.61      mycroft   362:        vfsinit();
                    363:
1.288     hannken   364:        /* Initialize fstrans. */
                    365:        fstrans_init();
1.267     kardel    366:
                    367: #ifdef __HAVE_TIMECOUNTER
1.268     kardel    368:        inittimecounter();
1.267     kardel    369:        ntp_init();
                    370: #endif /* __HAVE_TIMECOUNTER */
                    371:
1.156     thorpej   372:        /* Configure the system hardware.  This will enable interrupts. */
                    373:        configure();
1.61      mycroft   374:
1.280     christos  375: #if defined(__SSP__) || defined(__SSP_ALL__)
                    376:        {
                    377: #ifdef DIAGNOSTIC
                    378:                printf("Initializing SSP:");
                    379: #endif
                    380:                /*
                    381:                 * We initialize ssp here carefully:
                    382:                 *      1. after we got some entropy
                    383:                 *      2. without calling a function
                    384:                 */
                    385:                size_t i;
                    386:                long guard[__arraycount(__stack_chk_guard)];
                    387:
                    388:                arc4randbytes(guard, sizeof(guard));
                    389:                for (i = 0; i < __arraycount(guard); i++)
                    390:                        __stack_chk_guard[i] = guard[i];
                    391: #ifdef DIAGNOSTIC
                    392:                for (i = 0; i < __arraycount(guard); i++)
                    393:                        printf("%lx ", guard[i]);
                    394:                printf("\n");
                    395: #endif
                    396:        }
                    397: #endif
1.185     chs       398:        ubc_init();             /* must be after autoconfig */
                    399:
1.179     thorpej   400:        /* Lock the kernel on behalf of proc0. */
1.292     ad        401:        KERNEL_LOCK(1, l);
                    402:
                    403: #ifdef SYSTRACE
                    404:        systrace_init();
                    405: #endif
1.179     thorpej   406:
1.61      mycroft   407: #ifdef SYSVSHM
                    408:        /* Initialize System V style shared memory. */
                    409:        shminit();
                    410: #endif
                    411:
                    412: #ifdef SYSVSEM
                    413:        /* Initialize System V style semaphores. */
                    414:        seminit();
                    415: #endif
                    416:
                    417: #ifdef SYSVMSG
                    418:        /* Initialize System V style message queues. */
                    419:        msginit();
                    420: #endif
                    421:
1.217     christos  422: #ifdef P1003_1B_SEMAPHORE
                    423:        /* Initialize posix semaphores */
                    424:        ksem_init();
                    425: #endif
1.245     blymn     426:
1.273     elad      427: #if NVERIEXEC > 0
1.283     elad      428:        /*
                    429:         * Initialise the Veriexec subsystem.
                    430:         */
                    431:        veriexec_init();
1.273     elad      432: #endif /* NVERIEXEC > 0 */
1.251     junyoung  433:
1.282     elad      434: #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD)
1.281     elad      435:        pax_init();
1.282     elad      436: #endif /* PAX_MPROTECT || PAX_SEGVGUARD */
1.281     elad      437:
1.61      mycroft   438:        /* Attach pseudo-devices. */
                    439:        for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
                    440:                (*pdev->pdev_attach)(pdev->pdev_count);
1.223     jonathan  441:
                    442: #ifdef FAST_IPSEC
                    443:        /* Attach network crypto subsystem */
                    444:        ipsec_attach();
                    445: #endif
1.61      mycroft   446:
                    447:        /*
                    448:         * Initialize protocols.  Block reception of incoming packets
                    449:         * until everything is ready.
                    450:         */
1.190     thorpej   451:        s = splnet();
1.61      mycroft   452:        ifinit();
                    453:        domaininit();
1.200     itojun    454:        if_attachdomain();
1.61      mycroft   455:        splx(s);
                    456:
                    457: #ifdef GPROF
                    458:        /* Initialize kernel profiling. */
                    459:        kmstartup();
                    460: #endif
1.164     enami     461:
                    462:        /* Initialize system accouting. */
                    463:        acct_init();
1.61      mycroft   464:
1.294.2.2  rmind     465:        /* Setup the scheduler */
                    466:        sched_setup();
1.98      gwr       467:
1.292     ad        468: #ifdef KTRACE
                    469:        /* Initialize ktrace. */
                    470:        ktrinit();
                    471: #endif
                    472:
1.163     thorpej   473:        /*
                    474:         * Create process 1 (init(8)).  We do this now, as Unix has
                    475:         * historically had init be process 1, and changing this would
                    476:         * probably upset a lot of people.
                    477:         *
                    478:         * Note that process 1 won't immediately exec init(8), but will
                    479:         * wait for us to inform it that the root file system has been
                    480:         * mounted.
                    481:         */
1.216     thorpej   482:        if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, &initproc))
1.163     thorpej   483:                panic("fork init");
                    484:
                    485:        /*
                    486:         * Create any kernel threads who's creation was deferred because
                    487:         * initproc had not yet been created.
                    488:         */
                    489:        kthread_run_deferred_queue();
                    490:
                    491:        /*
                    492:         * Now that device driver threads have been created, wait for
                    493:         * them to finish any deferred autoconfiguration.  Note we don't
                    494:         * need to lock this semaphore, since we haven't booted any
                    495:         * secondary processors, yet.
                    496:         */
                    497:        while (config_pending)
1.247     christos  498:                (void) tsleep(&config_pending, PWAIT, "cfpend", 0);
1.208     thorpej   499:
                    500:        /*
                    501:         * Finalize configuration now that all real devices have been
                    502:         * found.  This needs to be done before the root device is
                    503:         * selected, since finalization may create the root device.
                    504:         */
                    505:        config_finalize();
1.163     thorpej   506:
                    507:        /*
                    508:         * Now that autoconfiguration has completed, we can determine
                    509:         * the root and dump devices.
                    510:         */
1.98      gwr       511:        cpu_rootconf();
1.101     thorpej   512:        cpu_dumpconf();
1.61      mycroft   513:
                    514:        /* Mount the root file system. */
1.95      thorpej   515:        do {
                    516:                domountroothook();
                    517:                if ((error = vfs_mountroot())) {
1.97      thorpej   518:                        printf("cannot mount root, error = %d\n", error);
1.95      thorpej   519:                        boothowto |= RB_ASKNAME;
                    520:                        setroot(root_device,
1.152     thorpej   521:                            (rootdev != NODEV) ? DISKPART(rootdev) : 0);
1.95      thorpej   522:                }
                    523:        } while (error != 0);
                    524:        mountroothook_destroy();
                    525:
1.239     pk        526:        /*
                    527:         * Initialise the time-of-day clock, passing the time recorded
                    528:         * in the root filesystem (if any) for use by systems that
                    529:         * don't have a non-volatile time-of-day device.
                    530:         */
                    531:        inittodr(rootfstime);
                    532:
1.206     matt      533:        CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;
                    534:        CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++;
1.61      mycroft   535:
1.111     thorpej   536:        /*
                    537:         * Get the vnode for '/'.  Set filedesc0.fd_fd.fd_cdir to
                    538:         * reference it.
                    539:         */
1.243     mycroft   540:        error = VFS_ROOT(CIRCLEQ_FIRST(&mountlist), &rootvnode);
                    541:        if (error)
                    542:                panic("cannot find root vnode, error=%d", error);
1.148     thorpej   543:        cwdi0.cwdi_cdir = rootvnode;
                    544:        VREF(cwdi0.cwdi_cdir);
1.118     fvdl      545:        VOP_UNLOCK(rootvnode, 0);
1.148     thorpej   546:        cwdi0.cwdi_rdir = NULL;
1.163     thorpej   547:
                    548:        /*
                    549:         * Now that root is mounted, we can fixup initproc's CWD
                    550:         * info.  All other processes are kthreads, which merely
                    551:         * share proc0's CWD info.
                    552:         */
                    553:        initproc->p_cwdi->cwdi_cdir = rootvnode;
                    554:        VREF(initproc->p_cwdi->cwdi_cdir);
                    555:        initproc->p_cwdi->cwdi_rdir = NULL;
1.61      mycroft   556:
                    557:        /*
                    558:         * Now can look at time, having had a chance to verify the time
1.292     ad        559:         * from the file system.  Reset l->l_rtime as it may have been
1.61      mycroft   560:         * munched in mi_switch() after the time got set.
                    561:         */
1.267     kardel    562: #ifdef __HAVE_TIMECOUNTER
                    563:        getmicrotime(&time);
                    564: #else
                    565:        mono_time = time;
                    566: #endif
                    567:        boottime = time;
1.294.2.4  rmind     568:        mutex_enter(&proclist_lock);
1.225     jdolecek  569:        LIST_FOREACH(p, &allproc, p_list) {
1.294.2.3  yamt      570:                KASSERT((p->p_flag & PK_MARKER) == 0);
1.292     ad        571:                mutex_enter(&p->p_smutex);
1.267     kardel    572:                p->p_stats->p_start = time;
1.225     jdolecek  573:                LIST_FOREACH(l, &p->p_lwps, l_sibling) {
1.292     ad        574:                        lwp_lock(l);
                    575:                        l->l_cpu->ci_schedstate.spc_runtime = time;
                    576:                        l->l_rtime.tv_sec = l->l_rtime.tv_usec = 0;
                    577:                        lwp_unlock(l);
1.225     jdolecek  578:                }
1.292     ad        579:                mutex_exit(&p->p_smutex);
1.163     thorpej   580:        }
1.294.2.4  rmind     581:        mutex_exit(&proclist_lock);
1.61      mycroft   582:
1.163     thorpej   583:        /* Create the pageout daemon kernel thread. */
                    584:        uvm_swap_init();
1.177     thorpej   585:        if (kthread_create1(uvm_pageout, NULL, NULL, "pagedaemon"))
1.135     thorpej   586:                panic("fork pagedaemon");
1.61      mycroft   587:
1.163     thorpej   588:        /* Create the filesystem syncer kernel thread. */
1.159     fvdl      589:        if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
                    590:                panic("fork syncer");
1.185     chs       591:
                    592:        /* Create the aiodone daemon kernel thread. */
1.286     yamt      593:        if (workqueue_create(&uvm.aiodone_queue, "aiodoned",
                    594:            uvm_aiodone_worker, NULL, PVM, IPL_BIO, 0))
1.185     chs       595:                panic("fork aiodoned");
1.137     thorpej   596:
1.160     thorpej   597: #if defined(MULTIPROCESSOR)
                    598:        /* Boot the secondary processors. */
                    599:        cpu_boot_secondary_processors();
1.294     ad        600:
                    601:        /* Count the number of running CPUs. */
                    602:        for (CPU_INFO_FOREACH(cii, ci)) {
                    603:                ncpu++;
                    604:        }
                    605:        ncpu--;
1.160     thorpej   606: #endif
1.186     jdolecek  607:
                    608:        /* Initialize exec structures */
                    609:        exec_init(1);
1.192     jdolecek  610:
1.163     thorpej   611:        /*
                    612:         * Okay, now we can let init(8) exec!  It's off to userland!
                    613:         */
                    614:        start_init_exec = 1;
1.247     christos  615:        wakeup(&start_init_exec);
1.163     thorpej   616:
1.61      mycroft   617:        /* The scheduler is an infinite loop. */
1.114     mrg       618:        uvm_scheduler();
1.61      mycroft   619:        /* NOTREACHED */
                    620: }
                    621:
1.239     pk        622: void
                    623: setrootfstime(time_t t)
                    624: {
                    625:        rootfstime = t;
                    626: }
                    627:
1.93      mouse     628: static void
1.260     christos  629: check_console(struct lwp *l)
1.93      mouse     630: {
                    631:        struct nameidata nd;
                    632:        int error;
                    633:
1.260     christos  634:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", l);
1.93      mouse     635:        error = namei(&nd);
1.96      cgd       636:        if (error == 0)
                    637:                vrele(nd.ni_vp);
                    638:        else if (error == ENOENT)
                    639:                printf("warning: no /dev/console\n");
1.93      mouse     640:        else
1.96      cgd       641:                printf("warning: lookup /dev/console: error %d\n", error);
1.93      mouse     642: }
                    643:
1.61      mycroft   644: /*
                    645:  * List of paths to try when searching for "init".
                    646:  */
1.176     thorpej   647: static const char *initpaths[] = {
1.61      mycroft   648:        "/sbin/init",
                    649:        "/sbin/oinit",
                    650:        "/sbin/init.bak",
                    651:        NULL,
                    652: };
                    653:
                    654: /*
                    655:  * Start the initial user process; try exec'ing each pathname in "initpaths".
                    656:  * The program is invoked with one argument containing the boot flags.
                    657:  */
                    658: static void
1.176     thorpej   659: start_init(void *arg)
1.61      mycroft   660: {
1.216     thorpej   661:        struct lwp *l = arg;
                    662:        struct proc *p = l->l_proc;
1.130     eeh       663:        vaddr_t addr;
1.78      mycroft   664:        struct sys_execve_args /* {
1.108     mycroft   665:                syscallarg(const char *) path;
1.92      cgd       666:                syscallarg(char * const *) argp;
                    667:                syscallarg(char * const *) envp;
1.68      cgd       668:        } */ args;
                    669:        int options, i, error;
                    670:        register_t retval[2];
1.66      mycroft   671:        char flags[4], *flagsp;
1.202     lukem     672:        const char *path, *slash;
1.176     thorpej   673:        char *ucp, **uap, *arg0, *arg1 = NULL;
1.202     lukem     674:        char ipath[129];
                    675:        int ipx, len;
1.61      mycroft   676:
1.76      cgd       677:        /*
                    678:         * Now in process 1.
                    679:         */
1.146     gwr       680:        strncpy(p->p_comm, "init", MAXCOMLEN);
1.163     thorpej   681:
                    682:        /*
                    683:         * Wait for main() to tell us that it's safe to exec.
                    684:         */
                    685:        while (start_init_exec == 0)
1.247     christos  686:                (void) tsleep(&start_init_exec, PWAIT, "initexec", 0);
1.93      mouse     687:
                    688:        /*
                    689:         * This is not the right way to do this.  We really should
                    690:         * hand-craft a descriptor onto /dev/console to hand to init,
                    691:         * but that's a _lot_ more work, and the benefit from this easy
                    692:         * hack makes up for the "good is the enemy of the best" effect.
                    693:         */
1.260     christos  694:        check_console(l);
1.61      mycroft   695:
                    696:        /*
                    697:         * Need just enough stack to hold the faked-up "execve()" arguments.
                    698:         */
1.211     chs       699:        addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE);
1.205     sommerfe  700:        if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
1.181     thorpej   701:                     NULL, UVM_UNKNOWN_OFFSET, 0,
1.114     mrg       702:                     UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
                    703:                    UVM_ADV_NORMAL,
1.189     chs       704:                     UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
1.114     mrg       705:                panic("init: couldn't allocate argument space");
1.294.2.4  rmind     706:        p->p_vmspace->vm_maxsaddr = (void *)STACK_MAX(addr, PAGE_SIZE);
1.61      mycroft   707:
1.202     lukem     708:        ipx = 0;
                    709:        while (1) {
                    710:                if (boothowto & RB_ASKNAME) {
                    711:                        printf("init path");
                    712:                        if (initpaths[ipx])
                    713:                                printf(" (default %s)", initpaths[ipx]);
                    714:                        printf(": ");
                    715:                        len = cngetsn(ipath, sizeof(ipath)-1);
                    716:                        if (len == 0) {
                    717:                                if (initpaths[ipx])
                    718:                                        path = initpaths[ipx++];
                    719:                                else
                    720:                                        continue;
                    721:                        } else {
                    722:                                ipath[len] = '\0';
                    723:                                path = ipath;
                    724:                        }
                    725:                } else {
                    726:                        if ((path = initpaths[ipx++]) == NULL)
                    727:                                break;
                    728:                }
                    729:
1.211     chs       730:                ucp = (char *)USRSTACK;
1.64      mycroft   731:
1.61      mycroft   732:                /*
1.64      mycroft   733:                 * Construct the boot flag argument.
1.61      mycroft   734:                 */
1.66      mycroft   735:                flagsp = flags;
                    736:                *flagsp++ = '-';
1.61      mycroft   737:                options = 0;
1.66      mycroft   738:
1.61      mycroft   739:                if (boothowto & RB_SINGLE) {
1.64      mycroft   740:                        *flagsp++ = 's';
1.61      mycroft   741:                        options = 1;
                    742:                }
                    743: #ifdef notyet
                    744:                if (boothowto & RB_FASTBOOT) {
1.64      mycroft   745:                        *flagsp++ = 'f';
1.61      mycroft   746:                        options = 1;
                    747:                }
                    748: #endif
1.64      mycroft   749:
                    750:                /*
                    751:                 * Move out the flags (arg 1), if necessary.
                    752:                 */
                    753:                if (options != 0) {
                    754:                        *flagsp++ = '\0';
                    755:                        i = flagsp - flags;
                    756: #ifdef DEBUG
1.90      christos  757:                        printf("init: copying out flags `%s' %d\n", flags, i);
1.64      mycroft   758: #endif
1.211     chs       759:                        arg1 = STACK_ALLOC(ucp, i);
                    760:                        ucp = STACK_MAX(arg1, i);
1.294.2.4  rmind     761:                        (void)copyout((void *)flags, arg1, i);
1.64      mycroft   762:                }
1.61      mycroft   763:
                    764:                /*
                    765:                 * Move out the file name (also arg 0).
                    766:                 */
1.64      mycroft   767:                i = strlen(path) + 1;
                    768: #ifdef DEBUG
1.90      christos  769:                printf("init: copying out path `%s' %d\n", path, i);
1.202     lukem     770: #else
1.203     lukem     771:                if (boothowto & RB_ASKNAME || path != initpaths[0])
1.202     lukem     772:                        printf("init: trying %s\n", path);
1.64      mycroft   773: #endif
1.211     chs       774:                arg0 = STACK_ALLOC(ucp, i);
                    775:                ucp = STACK_MAX(arg0, i);
1.247     christos  776:                (void)copyout(path, arg0, i);
1.61      mycroft   777:
                    778:                /*
                    779:                 * Move out the arg pointers.
                    780:                 */
1.294.2.4  rmind     781:                ucp = (void *)STACK_ALIGN(ucp, ALIGNBYTES);
1.211     chs       782:                uap = (char **)STACK_ALLOC(ucp, sizeof(char *) * 3);
                    783:                SCARG(&args, path) = arg0;
                    784:                SCARG(&args, argp) = uap;
                    785:                SCARG(&args, envp) = NULL;
1.142     mycroft   786:                slash = strrchr(path, '/');
                    787:                if (slash)
1.294.2.4  rmind     788:                        (void)suword((void *)uap++,
1.142     mycroft   789:                            (long)arg0 + (slash + 1 - path));
                    790:                else
1.294.2.4  rmind     791:                        (void)suword((void *)uap++, (long)arg0);
1.211     chs       792:                if (options != 0)
1.294.2.4  rmind     793:                        (void)suword((void *)uap++, (long)arg1);
                    794:                (void)suword((void *)uap++, 0); /* terminator */
1.61      mycroft   795:
                    796:                /*
                    797:                 * Now try to exec the program.  If can't for any reason
                    798:                 * other than it doesn't exist, complain.
                    799:                 */
1.260     christos  800:                error = sys_execve(l, &args, retval);
1.179     thorpej   801:                if (error == 0 || error == EJUSTRETURN) {
1.292     ad        802:                        KERNEL_UNLOCK_LAST(l);
1.61      mycroft   803:                        return;
1.179     thorpej   804:                }
1.202     lukem     805:                printf("exec %s: error %d\n", path, error);
1.61      mycroft   806:        }
1.90      christos  807:        printf("init: not found\n");
1.61      mycroft   808:        panic("no init");
                    809: }

CVSweb <webmaster@jp.NetBSD.org>