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