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

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

CVSweb <webmaster@jp.NetBSD.org>