Annotation of sys/kern/init_main.c, Revision 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