[BACK]Return to init_main.c CVS log [TXT][DIR] Up to [local] / sys / kern

Annotation of sys/kern/init_main.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: init_main.c,v 1.143 2007/07/25 23:11:52 art Exp $     */
                      2: /*     $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Christopher G. Demetriou.  All rights reserved.
                      6:  * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
                      7:  *     The Regents of the University of California.  All rights reserved.
                      8:  * (c) UNIX System Laboratories, Inc.
                      9:  * All or some portions of this file are derived from material licensed
                     10:  * to the University of California by American Telephone and Telegraph
                     11:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
                     12:  * the permission of UNIX System Laboratories, Inc.
                     13:  *
                     14:  * Redistribution and use in source and binary forms, with or without
                     15:  * modification, are permitted provided that the following conditions
                     16:  * are met:
                     17:  * 1. Redistributions of source code must retain the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer.
                     19:  * 2. Redistributions in binary form must reproduce the above copyright
                     20:  *    notice, this list of conditions and the following disclaimer in the
                     21:  *    documentation and/or other materials provided with the distribution.
                     22:  * 3. Neither the name of the University nor the names of its contributors
                     23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  *
                     38:  *     @(#)init_main.c 8.9 (Berkeley) 1/21/94
                     39:  */
                     40:
                     41: #include <sys/param.h>
                     42: #include <sys/filedesc.h>
                     43: #include <sys/file.h>
                     44: #include <sys/errno.h>
                     45: #include <sys/exec.h>
                     46: #include <sys/kernel.h>
                     47: #include <sys/kthread.h>
                     48: #include <sys/mount.h>
                     49: #include <sys/proc.h>
                     50: #include <sys/resourcevar.h>
                     51: #include <sys/signalvar.h>
                     52: #include <sys/systm.h>
                     53: #include <sys/namei.h>
                     54: #include <sys/vnode.h>
                     55: #include <sys/tty.h>
                     56: #include <sys/conf.h>
                     57: #include <sys/buf.h>
                     58: #include <sys/device.h>
                     59: #include <sys/socketvar.h>
                     60: #include <sys/lockf.h>
                     61: #include <sys/protosw.h>
                     62: #include <sys/reboot.h>
                     63: #include <sys/user.h>
                     64: #ifdef SYSVSHM
                     65: #include <sys/shm.h>
                     66: #endif
                     67: #ifdef SYSVSEM
                     68: #include <sys/sem.h>
                     69: #endif
                     70: #ifdef SYSVMSG
                     71: #include <sys/msg.h>
                     72: #endif
                     73: #include <sys/domain.h>
                     74: #include <sys/mbuf.h>
                     75: #include <sys/pipe.h>
                     76: #include <sys/workq.h>
                     77:
                     78: #include <sys/syscall.h>
                     79: #include <sys/syscallargs.h>
                     80:
                     81: #include <dev/rndvar.h>
                     82:
                     83: #include <ufs/ufs/quota.h>
                     84:
                     85: #include <machine/cpu.h>
                     86:
                     87: #include <uvm/uvm.h>
                     88:
                     89: #include <net/if.h>
                     90: #include <net/raw_cb.h>
                     91:
                     92: #if defined(CRYPTO)
                     93: #include <crypto/cryptodev.h>
                     94: #include <crypto/cryptosoft.h>
                     95: #endif
                     96:
                     97: #if defined(NFSSERVER) || defined(NFSCLIENT)
                     98: extern void nfs_init(void);
                     99: #endif
                    100:
                    101: #include "softraid.h"
                    102:
                    103: const char     copyright[] =
                    104: "Copyright (c) 1982, 1986, 1989, 1991, 1993\n"
                    105: "\tThe Regents of the University of California.  All rights reserved.\n"
                    106: "Copyright (c) 1995-2007 OpenBSD. All rights reserved.  http://www.OpenBSD.org\n";
                    107:
                    108: /* Components of the first process -- never freed. */
                    109: struct session session0;
                    110: struct pgrp pgrp0;
                    111: struct proc proc0;
                    112: struct process process0;
                    113: struct pcred cred0;
                    114: struct plimit limit0;
                    115: struct vmspace vmspace0;
                    116: struct sigacts sigacts0;
                    117: struct proc *initproc;
                    118:
                    119: int    cmask = CMASK;
                    120: extern struct user *proc0paddr;
                    121:
                    122: struct vnode *rootvp, *swapdev_vp;
                    123: int    boothowto;
                    124: struct timeval boottime;
                    125: int    ncpus =  1;
                    126: __volatile int start_init_exec;                /* semaphore for start_init() */
                    127:
                    128: #if !defined(NO_PROPOLICE)
                    129: long   __guard[8];
                    130: #endif
                    131:
                    132: /* XXX return int so gcc -Werror won't complain */
                    133: int    main(void *);
                    134: void   check_console(struct proc *);
                    135: void   start_init(void *);
                    136: void   start_cleaner(void *);
                    137: void   start_update(void *);
                    138: void   start_reaper(void *);
                    139: void   start_crypto(void *);
                    140: void   init_exec(void);
                    141: void   kqueue_init(void);
                    142: void   workq_init(void);
                    143:
                    144: extern char sigcode[], esigcode[];
                    145: #ifdef SYSCALL_DEBUG
                    146: extern char *syscallnames[];
                    147: #endif
                    148:
                    149: struct emul emul_native = {
                    150:        "native",
                    151:        NULL,
                    152:        sendsig,
                    153:        SYS_syscall,
                    154:        SYS_MAXSYSCALL,
                    155:        sysent,
                    156: #ifdef SYSCALL_DEBUG
                    157:        syscallnames,
                    158: #else
                    159:        NULL,
                    160: #endif
                    161:        0,
                    162:        copyargs,
                    163:        setregs,
                    164:        NULL,
                    165:        sigcode,
                    166:        esigcode,
                    167:        EMUL_ENABLED | EMUL_NATIVE,
                    168: };
                    169:
                    170: /*
                    171:  * System startup; initialize the world, create process 0, mount root
                    172:  * filesystem, and fork to create init and pagedaemon.  Most of the
                    173:  * hard work is done in the lower-level initialization routines including
                    174:  * startup(), which does memory initialization and autoconfiguration.
                    175:  */
                    176: /* XXX return int, so gcc -Werror won't complain */
                    177: int
                    178: main(void *framep)
                    179: {
                    180:        struct proc *p;
                    181:        struct pdevinit *pdev;
                    182:        struct timeval rtv;
                    183:        quad_t lim;
                    184:        int s, i;
                    185:        extern struct pdevinit pdevinit[];
                    186:        extern void scheduler_start(void);
                    187:        extern void disk_init(void);
                    188:        extern void endtsleep(void *);
                    189:        extern void realitexpire(void *);
                    190:
                    191:        /*
                    192:         * Initialize the current process pointer (curproc) before
                    193:         * any possible traps/probes to simplify trap processing.
                    194:         */
                    195:        curproc = p = &proc0;
                    196:        p->p_cpu = curcpu();
                    197:
                    198:        /*
                    199:         * Initialize timeouts.
                    200:         */
                    201:        timeout_startup();
                    202:
                    203:        /*
                    204:         * Attempt to find console and initialize
                    205:         * in case of early panic or other messages.
                    206:         */
                    207:        config_init();          /* init autoconfiguration data structures */
                    208:        consinit();
                    209:
                    210:        printf("%s\n", copyright);
                    211:
                    212:        KERNEL_LOCK_INIT();
                    213:
                    214:        uvm_init();
                    215:        disk_init();            /* must come before autoconfiguration */
                    216:        tty_init();             /* initialise tty's */
                    217:        cpu_startup();
                    218:
                    219:        /*
                    220:         * Initialize mbuf's.  Do this now because we might attempt to
                    221:         * allocate mbufs or mbuf clusters during autoconfiguration.
                    222:         */
                    223:        mbinit();
                    224:
                    225:        /* Initialize sockets. */
                    226:        soinit();
                    227:
                    228:        /*
                    229:         * Initialize process and pgrp structures.
                    230:         */
                    231:        procinit();
                    232:
                    233:        /* Initialize file locking. */
                    234:        lf_init();
                    235:
                    236:        /*
                    237:         * Initialize filedescriptors.
                    238:         */
                    239:        filedesc_init();
                    240:
                    241:        /*
                    242:         * Initialize pipes.
                    243:         */
                    244:        pipe_init();
                    245:
                    246:        /*
                    247:         * Initialize kqueues.
                    248:         */
                    249:        kqueue_init();
                    250:
                    251:        /*
                    252:         * Create process 0 (the swapper).
                    253:         */
                    254:
                    255:        process0.ps_mainproc = p;
                    256:        TAILQ_INIT(&process0.ps_threads);
                    257:        TAILQ_INSERT_TAIL(&process0.ps_threads, p, p_thr_link);
                    258:        p->p_p = &process0;
                    259:
                    260:        LIST_INSERT_HEAD(&allproc, p, p_list);
                    261:        p->p_pgrp = &pgrp0;
                    262:        LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
                    263:        LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
                    264:        LIST_INIT(&pgrp0.pg_members);
                    265:        LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
                    266:
                    267:        pgrp0.pg_session = &session0;
                    268:        session0.s_count = 1;
                    269:        session0.s_leader = p;
                    270:
                    271:        atomic_setbits_int(&p->p_flag, P_SYSTEM | P_NOCLDWAIT);
                    272:        p->p_stat = SONPROC;
                    273:        p->p_nice = NZERO;
                    274:        p->p_emul = &emul_native;
                    275:        bcopy("swapper", p->p_comm, sizeof ("swapper"));
                    276:
                    277:        /* Init timeouts. */
                    278:        timeout_set(&p->p_sleep_to, endtsleep, p);
                    279:        timeout_set(&p->p_realit_to, realitexpire, p);
                    280:
                    281:        /* Create credentials. */
                    282:        cred0.p_refcnt = 1;
                    283:        p->p_cred = &cred0;
                    284:        p->p_ucred = crget();
                    285:        p->p_ucred->cr_ngroups = 1;     /* group 0 */
                    286:
                    287:        /* Initialize signal state for process 0. */
                    288:        signal_init();
                    289:        p->p_sigacts = &sigacts0;
                    290:        siginit(p);
                    291:
                    292:        /* Create the file descriptor table. */
                    293:        p->p_fd = fdinit(NULL);
                    294:
                    295:        /* Create the limits structures. */
                    296:        p->p_p->ps_limit = &limit0;
                    297:        for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
                    298:                limit0.pl_rlimit[i].rlim_cur =
                    299:                    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
                    300:        limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
                    301:        limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = MIN(NOFILE_MAX,
                    302:            (maxfiles - NOFILE > NOFILE) ?  maxfiles - NOFILE : NOFILE);
                    303:        limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
                    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;
                    308:        limit0.p_refcnt = 1;
                    309:
                    310:        /* Allocate a prototype map so we have something to fork. */
                    311:        uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
                    312:            trunc_page(VM_MAX_ADDRESS), TRUE);
                    313:        p->p_vmspace = &vmspace0;
                    314:
                    315:        p->p_addr = proc0paddr;                         /* XXX */
                    316:
                    317:        /*
                    318:         * We continue to place resource usage info in the
                    319:         * user struct so they're pageable.
                    320:         */
                    321:        p->p_stats = &p->p_addr->u_stats;
                    322:
                    323:        /*
                    324:         * Charge root for one process.
                    325:         */
                    326:        (void)chgproccnt(0, 1);
                    327:
                    328:        /* Initialize run queues */
                    329:        rqinit();
                    330:
                    331:        /* Initialize work queues */
                    332:        workq_init();
                    333:
                    334:        /* Configure the devices */
                    335:        cpu_configure();
                    336:
                    337:        /* Configure virtual memory system, set vm rlimits. */
                    338:        uvm_init_limits(p);
                    339:
                    340:        /* Initialize the file systems. */
                    341: #if defined(NFSSERVER) || defined(NFSCLIENT)
                    342:        nfs_init();                     /* initialize server/shared data */
                    343: #endif
                    344:        vfsinit();
                    345:
                    346:        /* Start real time and statistics clocks. */
                    347:        initclocks();
                    348:
                    349:        /* Lock the kernel on behalf of proc0. */
                    350:        KERNEL_PROC_LOCK(p);
                    351:
                    352: #ifdef SYSVSHM
                    353:        /* Initialize System V style shared memory. */
                    354:        shminit();
                    355: #endif
                    356:
                    357: #ifdef SYSVSEM
                    358:        /* Initialize System V style semaphores. */
                    359:        seminit();
                    360: #endif
                    361:
                    362: #ifdef SYSVMSG
                    363:        /* Initialize System V style message queues. */
                    364:        msginit();
                    365: #endif
                    366:
                    367:        /* Attach pseudo-devices. */
                    368:        randomattach();
                    369:        for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
                    370:                if (pdev->pdev_count > 0)
                    371:                        (*pdev->pdev_attach)(pdev->pdev_count);
                    372:
                    373: #ifdef CRYPTO
                    374:        swcr_init();
                    375: #endif /* CRYPTO */
                    376:
                    377:        /*
                    378:         * Initialize protocols.  Block reception of incoming packets
                    379:         * until everything is ready.
                    380:         */
                    381:        s = splnet();
                    382:        ifinit();
                    383:        domaininit();
                    384:        if_attachdomain();
                    385:        splx(s);
                    386:
                    387: #ifdef GPROF
                    388:        /* Initialize kernel profiling. */
                    389:        kmstartup();
                    390: #endif
                    391:
                    392: #if !defined(NO_PROPOLICE)
                    393:        {
                    394:                volatile long newguard[8];
                    395:                int i;
                    396:
                    397:                arc4random_bytes((long *)newguard, sizeof(newguard));
                    398:
                    399:                for (i = sizeof(__guard)/sizeof(__guard[0]) - 1; i; i--)
                    400:                        __guard[i] = newguard[i];
                    401:        }
                    402: #endif
                    403:
                    404:        /* init exec and emul */
                    405:        init_exec();
                    406:
                    407:        /* Start the scheduler */
                    408:        scheduler_start();
                    409:
                    410:        /*
                    411:         * Create process 1 (init(8)).  We do this now, as Unix has
                    412:         * historically had init be process 1, and changing this would
                    413:         * probably upset a lot of people.
                    414:         *
                    415:         * Note that process 1 won't immediately exec init(8), but will
                    416:         * wait for us to inform it that the root file system has been
                    417:         * mounted.
                    418:         */
                    419:        if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, NULL,
                    420:            &initproc))
                    421:                panic("fork init");
                    422:
                    423:        /*
                    424:         * Create any kernel threads whose creation was deferred because
                    425:         * initproc had not yet been created.
                    426:         */
                    427:        kthread_run_deferred_queue();
                    428:
                    429:        /*
                    430:         * Now that device driver threads have been created, wait for
                    431:         * them to finish any deferred autoconfiguration.  Note we don't
                    432:         * need to lock this semaphore, since we haven't booted any
                    433:         * secondary processors, yet.
                    434:         */
                    435:        while (config_pending)
                    436:                (void) tsleep((void *)&config_pending, PWAIT, "cfpend", 0);
                    437:
                    438:        dostartuphooks();
                    439:
                    440: #if NSOFTRAID > 0
                    441:        config_rootfound("softraid", NULL);
                    442: #endif
                    443:
                    444:        /* Configure root/swap devices */
                    445:        diskconf();
                    446:
                    447:        /* Mount the root file system. */
                    448:        if (vfs_mountroot())
                    449:                panic("cannot mount root");
                    450:        CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;
                    451:
                    452:        /* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
                    453:        if (VFS_ROOT(CIRCLEQ_FIRST(&mountlist), &rootvnode))
                    454:                panic("cannot find root vnode");
                    455:        p->p_fd->fd_cdir = rootvnode;
                    456:        VREF(p->p_fd->fd_cdir);
                    457:        VOP_UNLOCK(rootvnode, 0, p);
                    458:        p->p_fd->fd_rdir = NULL;
                    459:
                    460:        /*
                    461:         * Now that root is mounted, we can fixup initproc's CWD
                    462:         * info.  All other processes are kthreads, which merely
                    463:         * share proc0's CWD info.
                    464:         */
                    465:        initproc->p_fd->fd_cdir = rootvnode;
                    466:        VREF(initproc->p_fd->fd_cdir);
                    467:        initproc->p_fd->fd_rdir = NULL;
                    468:
                    469:        /*
                    470:         * Now can look at time, having had a chance to verify the time
                    471:         * from the file system.  Reset p->p_rtime as it may have been
                    472:         * munched in mi_switch() after the time got set.
                    473:         */
                    474: #ifdef __HAVE_TIMECOUNTER
                    475:        microtime(&boottime);
                    476: #else
                    477:        boottime = mono_time = time;
                    478: #endif
                    479:        LIST_FOREACH(p, &allproc, p_list) {
                    480:                p->p_stats->p_start = boottime;
                    481:                microuptime(&p->p_cpu->ci_schedstate.spc_runtime);
                    482:                p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
                    483:        }
                    484:
                    485:        uvm_swap_init();
                    486:
                    487:        /* Create the pageout daemon kernel thread. */
                    488:        if (kthread_create(uvm_pageout, NULL, NULL, "pagedaemon"))
                    489:                panic("fork pagedaemon");
                    490:
                    491:        /* Create the reaper daemon kernel thread. */
                    492:        if (kthread_create(start_reaper, NULL, NULL, "reaper"))
                    493:                panic("fork reaper");
                    494:
                    495:        /* Create the cleaner daemon kernel thread. */
                    496:        if (kthread_create(start_cleaner, NULL, NULL, "cleaner"))
                    497:                panic("fork cleaner");
                    498:
                    499:        /* Create the update daemon kernel thread. */
                    500:        if (kthread_create(start_update, NULL, NULL, "update"))
                    501:                panic("fork update");
                    502:
                    503:        /* Create the aiodone daemon kernel thread. */
                    504:        if (kthread_create(uvm_aiodone_daemon, NULL, NULL, "aiodoned"))
                    505:                panic("fork aiodoned");
                    506:
                    507: #ifdef CRYPTO
                    508:        /* Create the crypto kernel thread. */
                    509:        if (kthread_create(start_crypto, NULL, NULL, "crypto"))
                    510:                panic("crypto thread");
                    511: #endif /* CRYPTO */
                    512:
                    513:        microtime(&rtv);
                    514:        srandom((u_long)(rtv.tv_sec ^ rtv.tv_usec));
                    515:
                    516:        randompid = 1;
                    517:
                    518: #if defined(MULTIPROCESSOR)
                    519:        /* Boot the secondary processors. */
                    520:        cpu_boot_secondary_processors();
                    521: #endif
                    522:
                    523:        domountroothooks();
                    524:
                    525:        /*
                    526:         * Okay, now we can let init(8) exec!  It's off to userland!
                    527:         */
                    528:        start_init_exec = 1;
                    529:        wakeup((void *)&start_init_exec);
                    530:
                    531:        /* The scheduler is an infinite loop. */
                    532:        uvm_scheduler();
                    533:        /* NOTREACHED */
                    534: }
                    535:
                    536: /*
                    537:  * List of paths to try when searching for "init".
                    538:  */
                    539: static char *initpaths[] = {
                    540:        "/sbin/init",
                    541:        "/sbin/oinit",
                    542:        "/sbin/init.bak",
                    543:        NULL,
                    544: };
                    545:
                    546: void
                    547: check_console(struct proc *p)
                    548: {
                    549:        struct nameidata nd;
                    550:        int error;
                    551:
                    552:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
                    553:        error = namei(&nd);
                    554:        if (error) {
                    555:                if (error == ENOENT)
                    556:                        printf("warning: /dev/console does not exist\n");
                    557:                else
                    558:                        printf("warning: /dev/console error %d\n", error);
                    559:        } else
                    560:                vrele(nd.ni_vp);
                    561: }
                    562:
                    563: /*
                    564:  * Start the initial user process; try exec'ing each pathname in "initpaths".
                    565:  * The program is invoked with one argument containing the boot flags.
                    566:  */
                    567: void
                    568: start_init(void *arg)
                    569: {
                    570:        struct proc *p = arg;
                    571:        vaddr_t addr;
                    572:        struct sys_execve_args /* {
                    573:                syscallarg(const char *) path;
                    574:                syscallarg(char *const *) argp;
                    575:                syscallarg(char *const *) envp;
                    576:        } */ args;
                    577:        int options, error;
                    578:        long i;
                    579:        register_t retval[2];
                    580:        char flags[4], *flagsp;
                    581:        char **pathp, *path, *ucp, **uap, *arg0, *arg1 = NULL;
                    582:
                    583:        /*
                    584:         * Now in process 1.
                    585:         */
                    586:
                    587:        /*
                    588:         * Wait for main() to tell us that it's safe to exec.
                    589:         */
                    590:        while (start_init_exec == 0)
                    591:                (void) tsleep((void *)&start_init_exec, PWAIT, "initexec", 0);
                    592:
                    593:        check_console(p);
                    594:
                    595:        /*
                    596:         * Need just enough stack to hold the faked-up "execve()" arguments.
                    597:         */
                    598: #ifdef MACHINE_STACK_GROWS_UP
                    599:        addr = USRSTACK;
                    600: #else
                    601:        addr = USRSTACK - PAGE_SIZE;
                    602: #endif
                    603:        if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
                    604:            NULL, UVM_UNKNOWN_OFFSET, 0,
                    605:            UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL, UVM_INH_COPY,
                    606:            UVM_ADV_NORMAL, UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)))
                    607:                panic("init: couldn't allocate argument space");
                    608:        p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
                    609:
                    610:        for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
                    611: #ifdef MACHINE_STACK_GROWS_UP
                    612:                ucp = (char *)addr;
                    613: #else
                    614:                ucp = (char *)(addr + PAGE_SIZE);
                    615: #endif
                    616:                /*
                    617:                 * Construct the boot flag argument.
                    618:                 */
                    619:                flagsp = flags;
                    620:                *flagsp++ = '-';
                    621:                options = 0;
                    622:
                    623:                if (boothowto & RB_SINGLE) {
                    624:                        *flagsp++ = 's';
                    625:                        options = 1;
                    626:                }
                    627: #ifdef notyet
                    628:                if (boothowto & RB_FASTBOOT) {
                    629:                        *flagsp++ = 'f';
                    630:                        options = 1;
                    631:                }
                    632: #endif
                    633:
                    634:                /*
                    635:                 * Move out the flags (arg 1), if necessary.
                    636:                 */
                    637:                if (options != 0) {
                    638:                        *flagsp++ = '\0';
                    639:                        i = flagsp - flags;
                    640: #ifdef DEBUG
                    641:                        printf("init: copying out flags `%s' %d\n", flags, i);
                    642: #endif
                    643: #ifdef MACHINE_STACK_GROWS_UP
                    644:                        arg1 = ucp;
                    645:                        (void)copyout((caddr_t)flags, (caddr_t)ucp, i);
                    646:                        ucp += i;
                    647: #else
                    648:                        (void)copyout((caddr_t)flags, (caddr_t)(ucp -= i), i);
                    649:                        arg1 = ucp;
                    650: #endif
                    651:                }
                    652:
                    653:                /*
                    654:                 * Move out the file name (also arg 0).
                    655:                 */
                    656:                i = strlen(path) + 1;
                    657: #ifdef DEBUG
                    658:                printf("init: copying out path `%s' %d\n", path, i);
                    659: #endif
                    660: #ifdef MACHINE_STACK_GROWS_UP
                    661:                arg0 = ucp;
                    662:                (void)copyout((caddr_t)path, (caddr_t)ucp, i);
                    663:                ucp += i;
                    664:                ucp = (caddr_t)ALIGN((u_long)ucp);
                    665:                uap = (char **)ucp + 3;
                    666: #else
                    667:                (void)copyout((caddr_t)path, (caddr_t)(ucp -= i), i);
                    668:                arg0 = ucp;
                    669:                uap = (char **)((u_long)ucp & ~ALIGNBYTES);
                    670: #endif
                    671:
                    672:                /*
                    673:                 * Move out the arg pointers.
                    674:                 */
                    675:                i = 0;
                    676:                copyout(&i, (caddr_t)--uap, sizeof(register_t)); /* terminator */
                    677:                if (options != 0)
                    678:                        copyout(&arg1, (caddr_t)--uap, sizeof(register_t));
                    679:                copyout(&arg0, (caddr_t)--uap, sizeof(register_t));
                    680:
                    681:                /*
                    682:                 * Point at the arguments.
                    683:                 */
                    684:                SCARG(&args, path) = arg0;
                    685:                SCARG(&args, argp) = uap;
                    686:                SCARG(&args, envp) = NULL;
                    687:
                    688:                /*
                    689:                 * Now try to exec the program.  If can't for any reason
                    690:                 * other than it doesn't exist, complain.
                    691:                 */
                    692:                if ((error = sys_execve(p, &args, retval)) == 0) {
                    693:                        KERNEL_PROC_UNLOCK(p);
                    694:                        return;
                    695:                }
                    696:                if (error != ENOENT)
                    697:                        printf("exec %s: error %d\n", path, error);
                    698:        }
                    699:        printf("init: not found\n");
                    700:        panic("no init");
                    701: }
                    702:
                    703: void
                    704: start_update(void *arg)
                    705: {
                    706:        sched_sync(curproc);
                    707:        /* NOTREACHED */
                    708: }
                    709:
                    710: void
                    711: start_cleaner(void *arg)
                    712: {
                    713:        buf_daemon(curproc);
                    714:        /* NOTREACHED */
                    715: }
                    716:
                    717: void
                    718: start_reaper(void *arg)
                    719: {
                    720:        reaper();
                    721:        /* NOTREACHED */
                    722: }
                    723:
                    724: #ifdef CRYPTO
                    725: void
                    726: start_crypto(void *arg)
                    727: {
                    728:        crypto_thread();
                    729:        /* NOTREACHED */
                    730: }
                    731: #endif /* CRYPTO */

CVSweb