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