Annotation of src/sys/kern/init_main.c, Revision 1.277
1.277 ! elad 1: /* $NetBSD: init_main.c,v 1.276 2006/07/26 09:33:57 dogcow 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.277 ! elad 74: __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.276 2006/07/26 09:33:57 dogcow Exp $");
1.115 mrg 75:
1.223 jonathan 76: #include "opt_ipsec.h"
1.267 kardel 77: #include "opt_kcont.h"
1.160 thorpej 78: #include "opt_multiprocessor.h"
1.267 kardel 79: #include "opt_ntp.h"
1.198 jdolecek 80: #include "opt_pipe.h"
1.267 kardel 81: #include "opt_posix.h"
1.172 soren 82: #include "opt_syscall_debug.h"
1.267 kardel 83: #include "opt_sysv.h"
1.271 elad 84: #include "opt_fileassoc.h"
1.61 mycroft 85:
1.106 explorer 86: #include "rnd.h"
1.276 dogcow 87: #include "veriexec.h"
1.106 explorer 88:
1.61 mycroft 89: #include <sys/param.h>
1.164 enami 90: #include <sys/acct.h>
1.61 mycroft 91: #include <sys/filedesc.h>
1.131 thorpej 92: #include <sys/file.h>
1.61 mycroft 93: #include <sys/errno.h>
1.162 thorpej 94: #include <sys/callout.h>
1.61 mycroft 95: #include <sys/kernel.h>
1.234 jonathan 96: #include <sys/kcont.h>
1.269 yamt 97: #include <sys/kmem.h>
1.61 mycroft 98: #include <sys/mount.h>
99: #include <sys/proc.h>
1.136 thorpej 100: #include <sys/kthread.h>
1.61 mycroft 101: #include <sys/resourcevar.h>
102: #include <sys/signalvar.h>
103: #include <sys/systm.h>
104: #include <sys/vnode.h>
1.87 thorpej 105: #include <sys/tty.h>
1.61 mycroft 106: #include <sys/conf.h>
1.95 thorpej 107: #include <sys/disklabel.h>
1.61 mycroft 108: #include <sys/buf.h>
109: #include <sys/device.h>
1.186 jdolecek 110: #include <sys/exec.h>
1.128 thorpej 111: #include <sys/socketvar.h>
1.61 mycroft 112: #include <sys/protosw.h>
113: #include <sys/reboot.h>
114: #include <sys/user.h>
1.176 thorpej 115: #include <sys/sysctl.h>
1.209 jdolecek 116: #include <sys/event.h>
1.227 jonathan 117: #include <sys/mbuf.h>
1.233 junyoung 118: #ifdef FAST_IPSEC
1.223 jonathan 119: #include <netipsec/ipsec.h>
120: #endif
1.82 christos 121: #ifdef SYSVSHM
122: #include <sys/shm.h>
123: #endif
1.233 junyoung 124: #ifdef SYSVSEM
1.82 christos 125: #include <sys/sem.h>
126: #endif
127: #ifdef SYSVMSG
128: #include <sys/msg.h>
129: #endif
1.217 christos 130: #ifdef P1003_1B_SEMAPHORE
131: #include <sys/ksem.h>
132: #endif
1.82 christos 133: #include <sys/domain.h>
1.94 mouse 134: #include <sys/namei.h>
1.106 explorer 135: #if NRND > 0
1.103 explorer 136: #include <sys/rnd.h>
1.106 explorer 137: #endif
1.198 jdolecek 138: #ifndef PIPE_SOCKETPAIR
1.192 jdolecek 139: #include <sys/pipe.h>
140: #endif
1.210 thorpej 141: #ifdef LKM
142: #include <sys/lkm.h>
143: #endif
1.273 elad 144: #if NVERIEXEC > 0
1.245 blymn 145: #include <sys/verified_exec.h>
1.273 elad 146: #endif /* NVERIEXEC > 0 */
1.266 elad 147: #include <sys/kauth.h>
1.252 skrll 148: #include <net80211/ieee80211_netbsd.h>
1.61 mycroft 149:
1.77 christos 150: #include <sys/syscall.h>
1.216 thorpej 151: #include <sys/sa.h>
1.68 cgd 152: #include <sys/syscallargs.h>
153:
1.271 elad 154: #ifdef FILEASSOC
155: #include <sys/fileassoc.h>
156: #endif /* FILEASSOC */
157:
1.61 mycroft 158: #include <ufs/ufs/quota.h>
159:
1.159 fvdl 160: #include <miscfs/genfs/genfs.h>
161: #include <miscfs/syncfs/syncfs.h>
162:
1.61 mycroft 163: #include <machine/cpu.h>
164:
1.114 mrg 165: #include <uvm/uvm.h>
166:
1.202 lukem 167: #include <dev/cons.h>
168:
1.81 christos 169: #include <net/if.h>
170: #include <net/raw_cb.h>
1.61 mycroft 171:
1.277 ! elad 172: #include <secmodel/secmodel.h>
! 173:
1.251 junyoung 174: extern struct proc proc0;
175: extern struct lwp lwp0;
176: extern struct cwdinfo cwdi0;
177:
1.216 thorpej 178: #ifndef curlwp
179: struct lwp *curlwp = &lwp0;
1.133 pk 180: #endif
1.105 mycroft 181: struct proc *initproc;
1.61 mycroft 182:
183: struct vnode *rootvp, *swapdev_vp;
184: int boothowto;
1.156 thorpej 185: int cold = 1; /* still working on startup */
1.272 kardel 186: struct timeval boottime; /* time at system startup - will only follow settime deltas */
1.239 pk 187: time_t rootfstime; /* recorded root fs time, if known */
1.61 mycroft 188:
1.261 perry 189: volatile int start_init_exec; /* semaphore for start_init() */
1.163 thorpej 190:
1.260 christos 191: static void check_console(struct lwp *l);
1.176 thorpej 192: static void start_init(void *);
193: void main(void);
1.76 cgd 194:
1.61 mycroft 195: /*
196: * System startup; initialize the world, create process 0, mount root
197: * filesystem, and fork to create init and pagedaemon. Most of the
198: * hard work is done in the lower-level initialization routines including
199: * startup(), which does memory initialization and autoconfiguration.
200: */
1.81 christos 201: void
1.176 thorpej 202: main(void)
1.61 mycroft 203: {
1.267 kardel 204: #ifdef __HAVE_TIMECOUNTER
205: struct timeval time;
206: #endif
1.216 thorpej 207: struct lwp *l;
1.144 thorpej 208: struct proc *p;
1.111 thorpej 209: struct pdevinit *pdev;
1.204 thorpej 210: int s, error;
1.61 mycroft 211: extern struct pdevinit pdevinit[];
1.176 thorpej 212: extern void schedcpu(void *);
1.175 jdolecek 213: #ifdef NVNODE_IMPLICIT
214: int usevnodes;
215: #endif
1.61 mycroft 216:
217: /*
1.216 thorpej 218: * Initialize the current LWP pointer (curlwp) before
1.61 mycroft 219: * any possible traps/probes to simplify trap processing.
220: */
1.216 thorpej 221: l = &lwp0;
222: curlwp = l;
223: l->l_cpu = curcpu();
224: l->l_proc = &proc0;
225: l->l_lid = 1;
1.233 junyoung 226:
1.61 mycroft 227: /*
228: * Attempt to find console and initialize
229: * in case of early panic or other messages.
230: */
231: consinit();
232:
1.179 thorpej 233: KERNEL_LOCK_INIT();
234:
1.114 mrg 235: uvm_init();
1.127 thorpej 236:
1.269 yamt 237: kmem_init();
238:
1.145 thorpej 239: /* Do machine-dependent initialization. */
240: cpu_startup();
1.162 thorpej 241:
1.166 enami 242: /* Initialize callouts. */
243: callout_startup();
1.145 thorpej 244:
1.228 pk 245: /* Initialize the buffer cache */
246: bufinit();
247:
1.127 thorpej 248: /*
249: * Initialize mbuf's. Do this now because we might attempt to
250: * allocate mbufs or mbuf clusters during autoconfiguration.
251: */
252: mbinit();
1.209 jdolecek 253:
1.128 thorpej 254: /* Initialize sockets. */
255: soinit();
1.127 thorpej 256:
1.235 matt 257: #ifdef KCONT
1.234 jonathan 258: /* Initialize kcont. */
259: kcont_init();
1.235 matt 260: #endif
1.234 jonathan 261:
1.156 thorpej 262: /*
1.212 thorpej 263: * The following things must be done before autoconfiguration.
1.156 thorpej 264: */
1.212 thorpej 265: evcnt_init(); /* initialize event counters */
1.106 explorer 266: #if NRND > 0
1.156 thorpej 267: rnd_init(); /* initialize RNG */
1.106 explorer 268: #endif
1.176 thorpej 269: /* Initialize the sysctl subsystem. */
270: sysctl_init();
271:
1.236 simonb 272: /* Initialize process and pgrp structures. */
1.63 mycroft 273: procinit();
1.210 thorpej 274:
1.251 junyoung 275: /* Initialize signal-related data structures. */
276: signal_init();
1.61 mycroft 277:
1.251 junyoung 278: /* Create process 0 (the swapper). */
279: proc0_init();
1.61 mycroft 280:
281: /*
1.63 mycroft 282: * Charge root for one process.
1.61 mycroft 283: */
284: (void)chgproccnt(0, 1);
285:
286: rqinit();
287:
288: /* Initialize the file systems. */
1.194 matt 289: #ifdef NVNODE_IMPLICIT
290: /*
291: * If maximum number of vnodes in namei vnode cache is not explicitly
292: * defined in kernel config, adjust the number such as we use roughly
1.232 tls 293: * 1.0% of memory for vnode cache (but not less than NVNODE vnodes).
1.194 matt 294: */
1.232 tls 295: usevnodes = (ptoa((unsigned)physmem) / 100) / sizeof(struct vnode);
1.205 sommerfe 296: if (usevnodes > desiredvnodes)
1.194 matt 297: desiredvnodes = usevnodes;
298: #endif
1.61 mycroft 299: vfsinit();
300:
1.267 kardel 301:
302: #ifdef __HAVE_TIMECOUNTER
1.268 kardel 303: inittimecounter();
1.267 kardel 304: ntp_init();
305: #endif /* __HAVE_TIMECOUNTER */
306:
1.156 thorpej 307: /* Configure the system hardware. This will enable interrupts. */
308: configure();
1.61 mycroft 309:
1.185 chs 310: ubc_init(); /* must be after autoconfig */
311:
1.179 thorpej 312: /* Lock the kernel on behalf of proc0. */
1.216 thorpej 313: KERNEL_PROC_LOCK(l);
1.179 thorpej 314:
1.61 mycroft 315: #ifdef SYSVSHM
316: /* Initialize System V style shared memory. */
317: shminit();
318: #endif
319:
320: #ifdef SYSVSEM
321: /* Initialize System V style semaphores. */
322: seminit();
323: #endif
324:
325: #ifdef SYSVMSG
326: /* Initialize System V style message queues. */
327: msginit();
328: #endif
329:
1.217 christos 330: #ifdef P1003_1B_SEMAPHORE
331: /* Initialize posix semaphores */
332: ksem_init();
333: #endif
1.245 blymn 334:
1.266 elad 335: /* Initialize kauth. */
336: kauth_init();
337:
1.277 ! elad 338: /* Initialize default security model. */
! 339: secmodel_start();
! 340:
1.271 elad 341: #ifdef FILEASSOC
342: fileassoc_init();
343: #endif /* FILEASSOC */
344:
1.273 elad 345: #if NVERIEXEC > 0
1.245 blymn 346: /*
347: * Initialise the fingerprint operations vectors before
348: * fingerprints can be loaded.
349: */
350: veriexec_init_fp_ops();
1.273 elad 351: #endif /* NVERIEXEC > 0 */
1.251 junyoung 352:
1.61 mycroft 353: /* Attach pseudo-devices. */
354: for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
355: (*pdev->pdev_attach)(pdev->pdev_count);
1.223 jonathan 356:
357: #ifdef FAST_IPSEC
358: /* Attach network crypto subsystem */
359: ipsec_attach();
360: #endif
1.61 mycroft 361:
362: /*
363: * Initialize protocols. Block reception of incoming packets
364: * until everything is ready.
365: */
1.190 thorpej 366: s = splnet();
1.61 mycroft 367: ifinit();
368: domaininit();
1.200 itojun 369: if_attachdomain();
1.61 mycroft 370: splx(s);
371:
372: #ifdef GPROF
373: /* Initialize kernel profiling. */
374: kmstartup();
375: #endif
1.164 enami 376:
377: /* Initialize system accouting. */
378: acct_init();
1.61 mycroft 379:
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;
444: CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++;
1.61 mycroft 445:
1.111 thorpej 446: /*
447: * Get the vnode for '/'. Set filedesc0.fd_fd.fd_cdir to
448: * reference it.
449: */
1.243 mycroft 450: error = VFS_ROOT(CIRCLEQ_FIRST(&mountlist), &rootvnode);
451: if (error)
452: panic("cannot find root vnode, error=%d", error);
1.148 thorpej 453: cwdi0.cwdi_cdir = rootvnode;
454: VREF(cwdi0.cwdi_cdir);
1.118 fvdl 455: VOP_UNLOCK(rootvnode, 0);
1.148 thorpej 456: cwdi0.cwdi_rdir = NULL;
1.163 thorpej 457:
458: /*
459: * Now that root is mounted, we can fixup initproc's CWD
460: * info. All other processes are kthreads, which merely
461: * share proc0's CWD info.
462: */
463: initproc->p_cwdi->cwdi_cdir = rootvnode;
464: VREF(initproc->p_cwdi->cwdi_cdir);
465: initproc->p_cwdi->cwdi_rdir = NULL;
1.61 mycroft 466:
467: /*
468: * Now can look at time, having had a chance to verify the time
469: * from the file system. Reset p->p_rtime as it may have been
470: * munched in mi_switch() after the time got set.
471: */
1.163 thorpej 472: proclist_lock_read();
1.178 thorpej 473: s = splsched();
1.267 kardel 474: #ifdef __HAVE_TIMECOUNTER
475: getmicrotime(&time);
476: #else
477: mono_time = time;
478: #endif
479: boottime = time;
1.225 jdolecek 480: LIST_FOREACH(p, &allproc, p_list) {
1.240 yamt 481: KASSERT((p->p_flag & P_MARKER) == 0);
1.267 kardel 482: p->p_stats->p_start = time;
1.225 jdolecek 483: LIST_FOREACH(l, &p->p_lwps, l_sibling) {
1.216 thorpej 484: if (l->l_cpu != NULL)
485: l->l_cpu->ci_schedstate.spc_runtime = time;
1.225 jdolecek 486: }
1.163 thorpej 487: p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
488: }
489: splx(s);
490: proclist_unlock_read();
1.61 mycroft 491:
1.163 thorpej 492: /* Create the pageout daemon kernel thread. */
493: uvm_swap_init();
1.177 thorpej 494: if (kthread_create1(uvm_pageout, NULL, NULL, "pagedaemon"))
1.135 thorpej 495: panic("fork pagedaemon");
1.61 mycroft 496:
1.163 thorpej 497: /* Create the filesystem syncer kernel thread. */
1.159 fvdl 498: if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
499: panic("fork syncer");
1.185 chs 500:
501: /* Create the aiodone daemon kernel thread. */
1.213 yamt 502: if (kthread_create1(uvm_aiodone_daemon, NULL, &uvm.aiodoned_proc,
503: "aiodoned"))
1.185 chs 504: panic("fork aiodoned");
1.137 thorpej 505:
1.160 thorpej 506: #if defined(MULTIPROCESSOR)
507: /* Boot the secondary processors. */
508: cpu_boot_secondary_processors();
509: #endif
1.186 jdolecek 510:
511: /* Initialize exec structures */
512: exec_init(1);
1.192 jdolecek 513:
1.163 thorpej 514: /*
515: * Okay, now we can let init(8) exec! It's off to userland!
516: */
517: start_init_exec = 1;
1.247 christos 518: wakeup(&start_init_exec);
1.163 thorpej 519:
1.61 mycroft 520: /* The scheduler is an infinite loop. */
1.114 mrg 521: uvm_scheduler();
1.61 mycroft 522: /* NOTREACHED */
523: }
524:
1.239 pk 525: void
526: setrootfstime(time_t t)
527: {
528: rootfstime = t;
529: }
530:
1.93 mouse 531: static void
1.260 christos 532: check_console(struct lwp *l)
1.93 mouse 533: {
534: struct nameidata nd;
535: int error;
536:
1.260 christos 537: NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", l);
1.93 mouse 538: error = namei(&nd);
1.96 cgd 539: if (error == 0)
540: vrele(nd.ni_vp);
541: else if (error == ENOENT)
542: printf("warning: no /dev/console\n");
1.93 mouse 543: else
1.96 cgd 544: printf("warning: lookup /dev/console: error %d\n", error);
1.93 mouse 545: }
546:
1.61 mycroft 547: /*
548: * List of paths to try when searching for "init".
549: */
1.176 thorpej 550: static const char *initpaths[] = {
1.61 mycroft 551: "/sbin/init",
552: "/sbin/oinit",
553: "/sbin/init.bak",
554: NULL,
555: };
556:
557: /*
558: * Start the initial user process; try exec'ing each pathname in "initpaths".
559: * The program is invoked with one argument containing the boot flags.
560: */
561: static void
1.176 thorpej 562: start_init(void *arg)
1.61 mycroft 563: {
1.216 thorpej 564: struct lwp *l = arg;
565: struct proc *p = l->l_proc;
1.130 eeh 566: vaddr_t addr;
1.78 mycroft 567: struct sys_execve_args /* {
1.108 mycroft 568: syscallarg(const char *) path;
1.92 cgd 569: syscallarg(char * const *) argp;
570: syscallarg(char * const *) envp;
1.68 cgd 571: } */ args;
572: int options, i, error;
573: register_t retval[2];
1.66 mycroft 574: char flags[4], *flagsp;
1.202 lukem 575: const char *path, *slash;
1.176 thorpej 576: char *ucp, **uap, *arg0, *arg1 = NULL;
1.202 lukem 577: char ipath[129];
578: int ipx, len;
1.61 mycroft 579:
1.76 cgd 580: /*
581: * Now in process 1.
582: */
1.146 gwr 583: strncpy(p->p_comm, "init", MAXCOMLEN);
1.163 thorpej 584:
585: /*
586: * Wait for main() to tell us that it's safe to exec.
587: */
588: while (start_init_exec == 0)
1.247 christos 589: (void) tsleep(&start_init_exec, PWAIT, "initexec", 0);
1.93 mouse 590:
591: /*
592: * This is not the right way to do this. We really should
593: * hand-craft a descriptor onto /dev/console to hand to init,
594: * but that's a _lot_ more work, and the benefit from this easy
595: * hack makes up for the "good is the enemy of the best" effect.
596: */
1.260 christos 597: check_console(l);
1.61 mycroft 598:
599: /*
600: * Need just enough stack to hold the faked-up "execve()" arguments.
601: */
1.211 chs 602: addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE);
1.205 sommerfe 603: if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
1.181 thorpej 604: NULL, UVM_UNKNOWN_OFFSET, 0,
1.114 mrg 605: UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
606: UVM_ADV_NORMAL,
1.189 chs 607: UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
1.114 mrg 608: panic("init: couldn't allocate argument space");
1.211 chs 609: p->p_vmspace->vm_maxsaddr = (caddr_t)STACK_MAX(addr, PAGE_SIZE);
1.61 mycroft 610:
1.202 lukem 611: ipx = 0;
612: while (1) {
613: if (boothowto & RB_ASKNAME) {
614: printf("init path");
615: if (initpaths[ipx])
616: printf(" (default %s)", initpaths[ipx]);
617: printf(": ");
618: len = cngetsn(ipath, sizeof(ipath)-1);
619: if (len == 0) {
620: if (initpaths[ipx])
621: path = initpaths[ipx++];
622: else
623: continue;
624: } else {
625: ipath[len] = '\0';
626: path = ipath;
627: }
628: } else {
629: if ((path = initpaths[ipx++]) == NULL)
630: break;
631: }
632:
1.211 chs 633: ucp = (char *)USRSTACK;
1.64 mycroft 634:
1.61 mycroft 635: /*
1.64 mycroft 636: * Construct the boot flag argument.
1.61 mycroft 637: */
1.66 mycroft 638: flagsp = flags;
639: *flagsp++ = '-';
1.61 mycroft 640: options = 0;
1.66 mycroft 641:
1.61 mycroft 642: if (boothowto & RB_SINGLE) {
1.64 mycroft 643: *flagsp++ = 's';
1.61 mycroft 644: options = 1;
645: }
646: #ifdef notyet
647: if (boothowto & RB_FASTBOOT) {
1.64 mycroft 648: *flagsp++ = 'f';
1.61 mycroft 649: options = 1;
650: }
651: #endif
1.64 mycroft 652:
653: /*
654: * Move out the flags (arg 1), if necessary.
655: */
656: if (options != 0) {
657: *flagsp++ = '\0';
658: i = flagsp - flags;
659: #ifdef DEBUG
1.90 christos 660: printf("init: copying out flags `%s' %d\n", flags, i);
1.64 mycroft 661: #endif
1.211 chs 662: arg1 = STACK_ALLOC(ucp, i);
663: ucp = STACK_MAX(arg1, i);
664: (void)copyout((caddr_t)flags, arg1, i);
1.64 mycroft 665: }
1.61 mycroft 666:
667: /*
668: * Move out the file name (also arg 0).
669: */
1.64 mycroft 670: i = strlen(path) + 1;
671: #ifdef DEBUG
1.90 christos 672: printf("init: copying out path `%s' %d\n", path, i);
1.202 lukem 673: #else
1.203 lukem 674: if (boothowto & RB_ASKNAME || path != initpaths[0])
1.202 lukem 675: printf("init: trying %s\n", path);
1.64 mycroft 676: #endif
1.211 chs 677: arg0 = STACK_ALLOC(ucp, i);
678: ucp = STACK_MAX(arg0, i);
1.247 christos 679: (void)copyout(path, arg0, i);
1.61 mycroft 680:
681: /*
682: * Move out the arg pointers.
683: */
1.211 chs 684: ucp = (caddr_t)STACK_ALIGN(ucp, ALIGNBYTES);
685: uap = (char **)STACK_ALLOC(ucp, sizeof(char *) * 3);
686: SCARG(&args, path) = arg0;
687: SCARG(&args, argp) = uap;
688: SCARG(&args, envp) = NULL;
1.142 mycroft 689: slash = strrchr(path, '/');
690: if (slash)
1.211 chs 691: (void)suword((caddr_t)uap++,
1.142 mycroft 692: (long)arg0 + (slash + 1 - path));
693: else
1.211 chs 694: (void)suword((caddr_t)uap++, (long)arg0);
695: if (options != 0)
696: (void)suword((caddr_t)uap++, (long)arg1);
697: (void)suword((caddr_t)uap++, 0); /* terminator */
1.61 mycroft 698:
699: /*
700: * Now try to exec the program. If can't for any reason
701: * other than it doesn't exist, complain.
702: */
1.260 christos 703: error = sys_execve(l, &args, retval);
1.179 thorpej 704: if (error == 0 || error == EJUSTRETURN) {
1.216 thorpej 705: KERNEL_PROC_UNLOCK(l);
1.61 mycroft 706: return;
1.179 thorpej 707: }
1.202 lukem 708: printf("exec %s: error %d\n", path, error);
1.61 mycroft 709: }
1.90 christos 710: printf("init: not found\n");
1.61 mycroft 711: panic("no init");
712: }
CVSweb <webmaster@jp.NetBSD.org>