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

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

CVSweb <webmaster@jp.NetBSD.org>