xref: /openbsd-src/sys/kern/init_main.c (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
1 /*	$OpenBSD: init_main.c,v 1.105 2003/06/02 23:28:05 millert 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/protosw.h>
61 #include <sys/reboot.h>
62 #include <sys/user.h>
63 #ifdef SYSVSHM
64 #include <sys/shm.h>
65 #endif
66 #ifdef SYSVSEM
67 #include <sys/sem.h>
68 #endif
69 #ifdef SYSVMSG
70 #include <sys/msg.h>
71 #endif
72 #include <sys/domain.h>
73 #include <sys/mbuf.h>
74 #include <sys/pipe.h>
75 
76 #include <sys/syscall.h>
77 #include <sys/syscallargs.h>
78 
79 #include <dev/rndvar.h>
80 
81 #include <ufs/ufs/quota.h>
82 
83 #include <machine/cpu.h>
84 
85 #include <uvm/uvm.h>
86 
87 #include <net/if.h>
88 #include <net/raw_cb.h>
89 
90 #if defined(CRYPTO)
91 #include <crypto/cryptodev.h>
92 #include <crypto/cryptosoft.h>
93 #endif
94 
95 #if defined(NFSSERVER) || defined(NFSCLIENT)
96 extern void nfs_init(void);
97 #endif
98 
99 const char	copyright[] =
100 "Copyright (c) 1982, 1986, 1989, 1991, 1993\n"
101 "\tThe Regents of the University of California.  All rights reserved.\n"
102 "Copyright (c) 1995-2003 OpenBSD. All rights reserved.  http://www.OpenBSD.org\n";
103 
104 /* Components of the first process -- never freed. */
105 struct	session session0;
106 struct	pgrp pgrp0;
107 struct	proc proc0;
108 struct	pcred cred0;
109 struct	plimit limit0;
110 struct	vmspace vmspace0;
111 struct	sigacts sigacts0;
112 #ifndef curproc
113 struct	proc *curproc;
114 #endif
115 struct	proc *initproc;
116 
117 int	cmask = CMASK;
118 extern	struct user *proc0paddr;
119 
120 void	(*md_diskconf)(void) = NULL;
121 struct	vnode *rootvp, *swapdev_vp;
122 int	boothowto;
123 struct	timeval boottime;
124 struct	timeval runtime;
125 
126 #if !defined(NO_PROPOLICE)
127 long	__guard[8];
128 #endif
129 
130 /* XXX return int so gcc -Werror won't complain */
131 int	main(void *);
132 void	check_console(struct proc *);
133 void	start_init(void *);
134 void	start_cleaner(void *);
135 void	start_update(void *);
136 void	start_reaper(void *);
137 void    start_crypto(void *);
138 
139 extern char sigcode[], esigcode[];
140 #ifdef SYSCALL_DEBUG
141 extern char *syscallnames[];
142 #endif
143 
144 struct emul emul_native = {
145 	"native",
146 	NULL,
147 	sendsig,
148 	SYS_syscall,
149 	SYS_MAXSYSCALL,
150 	sysent,
151 #ifdef SYSCALL_DEBUG
152 	syscallnames,
153 #else
154 	NULL,
155 #endif
156 	0,
157 	copyargs,
158 	setregs,
159 	NULL,
160 	sigcode,
161 	esigcode,
162 };
163 
164 /*
165  * System startup; initialize the world, create process 0, mount root
166  * filesystem, and fork to create init and pagedaemon.  Most of the
167  * hard work is done in the lower-level initialization routines including
168  * startup(), which does memory initialization and autoconfiguration.
169  */
170 /* XXX return int, so gcc -Werror won't complain */
171 int
172 main(framep)
173 	void *framep;				/* XXX should go away */
174 {
175 	struct proc *p;
176 	struct pdevinit *pdev;
177 	struct timeval rtv;
178 	quad_t lim;
179 	int s, i;
180 	register_t rval[2];
181 #if !defined(NO_PROPOLICE)
182 	int *guard = (int *)&__guard[0];
183 #endif
184 	extern struct pdevinit pdevinit[];
185 	extern void scheduler_start(void);
186 	extern void disk_init(void);
187 	extern void endtsleep(void *);
188 	extern void realitexpire(void *);
189 
190 	/*
191 	 * Initialize the current process pointer (curproc) before
192 	 * any possible traps/probes to simplify trap processing.
193 	 */
194 	curproc = p = &proc0;
195 
196 	/*
197 	 * Attempt to find console and initialize
198 	 * in case of early panic or other messages.
199 	 */
200 	config_init();		/* init autoconfiguration data structures */
201 	consinit();
202 	printf(copyright);
203 	printf("\n");
204 
205 	uvm_init();
206 	disk_init();		/* must come before autoconfiguration */
207 	tty_init();		/* initialise tty's */
208 	cpu_startup();
209 
210 	/*
211 	 * Initialize mbuf's.  Do this now because we might attempt to
212 	 * allocate mbufs or mbuf clusters during autoconfiguration.
213 	 */
214 	mbinit();
215 
216 	/* Initalize sockets. */
217 	soinit();
218 
219 	/*
220 	 * Initialize timeouts.
221 	 */
222 	timeout_startup();
223 
224 	/* Initialize sysctls (must be done before any processes run) */
225 	sysctl_init();
226 
227 	/*
228 	 * Initialize process and pgrp structures.
229 	 */
230 	procinit();
231 
232 	/*
233 	 * Initialize filedescriptors.
234 	 */
235 	filedesc_init();
236 
237 	/*
238 	 * Initialize pipes.
239 	 */
240 	pipe_init();
241 
242 	/*
243 	 * Create process 0 (the swapper).
244 	 */
245 	LIST_INSERT_HEAD(&allproc, p, p_list);
246 	p->p_pgrp = &pgrp0;
247 	LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
248 	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
249 	LIST_INIT(&pgrp0.pg_members);
250 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
251 
252 	pgrp0.pg_session = &session0;
253 	session0.s_count = 1;
254 	session0.s_leader = p;
255 
256 	p->p_flag = P_INMEM | P_SYSTEM | P_NOCLDWAIT;
257 	p->p_stat = SRUN;
258 	p->p_nice = NZERO;
259 	p->p_emul = &emul_native;
260 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
261 
262 	/* Init timeouts. */
263 	timeout_set(&p->p_sleep_to, endtsleep, p);
264 	timeout_set(&p->p_realit_to, realitexpire, p);
265 
266 	/* Create credentials. */
267 	cred0.p_refcnt = 1;
268 	p->p_cred = &cred0;
269 	p->p_ucred = crget();
270 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
271 
272 	/* Initialize signal state for process 0. */
273 	signal_init();
274 	p->p_sigacts = &sigacts0;
275 	siginit(p);
276 
277 	/* Create the file descriptor table. */
278 	p->p_fd = fdinit(NULL);
279 
280 	/* Create the limits structures. */
281 	p->p_limit = &limit0;
282 	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
283 		limit0.pl_rlimit[i].rlim_cur =
284 		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
285 	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
286 	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = MIN(NOFILE_MAX,
287 	    (maxfiles - NOFILE > NOFILE) ?  maxfiles - NOFILE : NOFILE);
288 	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
289 	lim = ptoa(uvmexp.free);
290 	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = lim;
291 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = lim;
292 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
293 	limit0.p_refcnt = 1;
294 
295 	/* Allocate a prototype map so we have something to fork. */
296 	uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
297 	    trunc_page(VM_MAX_ADDRESS), TRUE);
298 	p->p_vmspace = &vmspace0;
299 
300 	p->p_addr = proc0paddr;				/* XXX */
301 
302 	/*
303 	 * We continue to place resource usage info in the
304 	 * user struct so they're pageable.
305 	 */
306 	p->p_stats = &p->p_addr->u_stats;
307 
308 	/*
309 	 * Charge root for one process.
310 	 */
311 	(void)chgproccnt(0, 1);
312 
313 	/* Initialize run queues */
314 	rqinit();
315 
316 	/* Configure the devices */
317 	cpu_configure();
318 
319 	/* Configure virtual memory system, set vm rlimits. */
320 	uvm_init_limits(p);
321 
322 	/* Initialize the file systems. */
323 #if defined(NFSSERVER) || defined(NFSCLIENT)
324 	nfs_init();			/* initialize server/shared data */
325 #endif
326 	vfsinit();
327 
328 	/* Start real time and statistics clocks. */
329 	initclocks();
330 
331 #ifdef SYSVSHM
332 	/* Initialize System V style shared memory. */
333 	shminit();
334 #endif
335 
336 #ifdef SYSVSEM
337 	/* Initialize System V style semaphores. */
338 	seminit();
339 #endif
340 
341 #ifdef SYSVMSG
342 	/* Initialize System V style message queues. */
343 	msginit();
344 #endif
345 
346 	/* Attach pseudo-devices. */
347 	randomattach();
348 	for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
349 		if (pdev->pdev_count > 0)
350 			(*pdev->pdev_attach)(pdev->pdev_count);
351 
352 #ifdef CRYPTO
353 	swcr_init();
354 #endif /* CRYPTO */
355 
356 	/*
357 	 * Initialize protocols.  Block reception of incoming packets
358 	 * until everything is ready.
359 	 */
360 	s = splimp();
361 	ifinit();
362 	domaininit();
363 	if_attachdomain();
364 	splx(s);
365 
366 #ifdef GPROF
367 	/* Initialize kernel profiling. */
368 	kmstartup();
369 #endif
370 
371 #if !defined(NO_PROPOLICE)
372 	for (i = 0; i < sizeof(__guard) / 4; i++)
373 		guard[i] = arc4random();
374 #endif
375 
376 	/* Start the scheduler */
377 	scheduler_start();
378 
379 	dostartuphooks();
380 
381 	/* Configure root/swap devices */
382 	if (md_diskconf)
383 		(*md_diskconf)();
384 
385 	/* Mount the root file system. */
386 	if (vfs_mountroot())
387 		panic("cannot mount root");
388 	CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;
389 
390 	/* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
391 	if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
392 		panic("cannot find root vnode");
393 	p->p_fd->fd_cdir = rootvnode;
394 	VREF(p->p_fd->fd_cdir);
395 	VOP_UNLOCK(rootvnode, 0, p);
396 	p->p_fd->fd_rdir = NULL;
397 
398 	uvm_swap_init();
399 
400 	/*
401 	 * Now can look at time, having had a chance to verify the time
402 	 * from the file system.  Reset p->p_rtime as it may have been
403 	 * munched in mi_switch() after the time got set.
404 	 */
405 	p->p_stats->p_start = runtime = mono_time = boottime = time;
406 	p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
407 
408 	/* Create process 1 (init(8)). */
409 	if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, rval))
410 		panic("fork init");
411 
412 	/* Create process 2, the pageout daemon kernel thread. */
413 	if (kthread_create(uvm_pageout, NULL, NULL, "pagedaemon"))
414 		panic("fork pagedaemon");
415 
416 	/* Create process 3, the reaper daemon kernel thread. */
417 	if (kthread_create(start_reaper, NULL, NULL, "reaper"))
418 		panic("fork reaper");
419 
420 	/* Create process 4, the cleaner daemon kernel thread. */
421 	if (kthread_create(start_cleaner, NULL, NULL, "cleaner"))
422 		panic("fork cleaner");
423 
424 	/* Create process 5, the update daemon kernel thread. */
425 	if (kthread_create(start_update, NULL, NULL, "update"))
426 		panic("fork update");
427 
428 	/* Create process 6, the aiodone daemon kernel thread. */
429 	if (kthread_create(uvm_aiodone_daemon, NULL, NULL, "aiodoned"))
430 		panic("fork aiodoned");
431 
432 #ifdef CRYPTO
433 	/* Create process 7, the crypto kernel thread. */
434 	if (kthread_create(start_crypto, NULL, NULL, "crypto"))
435 		panic("crypto thread");
436 #endif /* CRYPTO */
437 
438 	/* Create any other deferred kernel threads. */
439 	kthread_run_deferred_queue();
440 
441 	microtime(&rtv);
442 	srandom((u_long)(rtv.tv_sec ^ rtv.tv_usec));
443 
444 	randompid = 1;
445 	/* The scheduler is an infinite loop. */
446 	uvm_scheduler();
447 	/* NOTREACHED */
448 }
449 
450 /*
451  * List of paths to try when searching for "init".
452  */
453 static char *initpaths[] = {
454 	"/sbin/init",
455 	"/sbin/oinit",
456 	"/sbin/init.bak",
457 	NULL,
458 };
459 
460 void
461 check_console(p)
462 	struct proc *p;
463 {
464 	struct nameidata nd;
465 	int error;
466 
467 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
468 	error = namei(&nd);
469 	if (error) {
470 		if (error == ENOENT)
471 			printf("warning: /dev/console does not exist\n");
472 		else
473 			printf("warning: /dev/console error %d\n", error);
474 	} else
475 		vrele(nd.ni_vp);
476 }
477 
478 /*
479  * Start the initial user process; try exec'ing each pathname in "initpaths".
480  * The program is invoked with one argument containing the boot flags.
481  */
482 void
483 start_init(arg)
484 	void *arg;
485 {
486 	struct proc *p = arg;
487 	vaddr_t addr;
488 	struct sys_execve_args /* {
489 		syscallarg(char *) path;
490 		syscallarg(char **) argp;
491 		syscallarg(char **) envp;
492 	} */ args;
493 	int options, error;
494 	long i;
495 	register_t retval[2];
496 	char flags[4], *flagsp;
497 	char **pathp, *path, *ucp, **uap, *arg0, *arg1 = NULL;
498 
499 	initproc = p;
500 
501 	/*
502 	 * Now in process 1.
503 	 */
504 	check_console(p);
505 
506 	/*
507 	 * Need just enough stack to hold the faked-up "execve()" arguments.
508 	 */
509 #ifdef MACHINE_STACK_GROWS_UP
510 	addr = USRSTACK;
511 #else
512 	addr = USRSTACK - PAGE_SIZE;
513 #endif
514 	if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
515 	    NULL, UVM_UNKNOWN_OFFSET, 0,
516 	    UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL, UVM_INH_COPY,
517 	    UVM_ADV_NORMAL, UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)))
518 		panic("init: couldn't allocate argument space");
519 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
520 
521 	for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
522 #ifdef MACHINE_STACK_GROWS_UP
523 		ucp = (char *)addr;
524 #else
525 		ucp = (char *)(addr + PAGE_SIZE);
526 #endif
527 		/*
528 		 * Construct the boot flag argument.
529 		 */
530 		flagsp = flags;
531 		*flagsp++ = '-';
532 		options = 0;
533 
534 		if (boothowto & RB_SINGLE) {
535 			*flagsp++ = 's';
536 			options = 1;
537 		}
538 #ifdef notyet
539 		if (boothowto & RB_FASTBOOT) {
540 			*flagsp++ = 'f';
541 			options = 1;
542 		}
543 #endif
544 
545 		/*
546 		 * Move out the flags (arg 1), if necessary.
547 		 */
548 		if (options != 0) {
549 			*flagsp++ = '\0';
550 			i = flagsp - flags;
551 #ifdef DEBUG
552 			printf("init: copying out flags `%s' %d\n", flags, i);
553 #endif
554 #ifdef MACHINE_STACK_GROWS_UP
555 			arg1 = ucp;
556 			(void)copyout((caddr_t)flags, (caddr_t)ucp, i);
557 			ucp += i;
558 #else
559 			(void)copyout((caddr_t)flags, (caddr_t)(ucp -= i), i);
560 			arg1 = ucp;
561 #endif
562 		}
563 
564 		/*
565 		 * Move out the file name (also arg 0).
566 		 */
567 		i = strlen(path) + 1;
568 #ifdef DEBUG
569 		printf("init: copying out path `%s' %d\n", path, i);
570 #endif
571 #ifdef MACHINE_STACK_GROWS_UP
572 		arg0 = ucp;
573 		(void)copyout((caddr_t)path, (caddr_t)ucp, i);
574 		ucp += i;
575 		ucp = (caddr_t)ALIGN((u_long)ucp);
576 		uap = (char **)ucp + 3;
577 #else
578 		(void)copyout((caddr_t)path, (caddr_t)(ucp -= i), i);
579 		arg0 = ucp;
580 		uap = (char **)((u_long)ucp & ~ALIGNBYTES);
581 #endif
582 
583 		/*
584 		 * Move out the arg pointers.
585 		 */
586 		i = 0;
587 		copyout(&i, (caddr_t)--uap, sizeof(register_t)); /* terminator */
588 		if (options != 0)
589 			copyout(&arg1, (caddr_t)--uap, sizeof(register_t));
590 		copyout(&arg0, (caddr_t)--uap, sizeof(register_t));
591 
592 		/*
593 		 * Point at the arguments.
594 		 */
595 		SCARG(&args, path) = arg0;
596 		SCARG(&args, argp) = uap;
597 		SCARG(&args, envp) = NULL;
598 
599 		/*
600 		 * Now try to exec the program.  If can't for any reason
601 		 * other than it doesn't exist, complain.
602 		 */
603 		if ((error = sys_execve(p, &args, retval)) == 0)
604 			return;
605 		if (error != ENOENT)
606 			printf("exec %s: error %d\n", path, error);
607 	}
608 	printf("init: not found\n");
609 	panic("no init");
610 }
611 
612 void
613 start_update(arg)
614 	void *arg;
615 {
616 	sched_sync(curproc);
617 	/* NOTREACHED */
618 }
619 
620 void
621 start_cleaner(arg)
622 	void *arg;
623 {
624 	buf_daemon(curproc);
625 	/* NOTREACHED */
626 }
627 
628 void
629 start_reaper(arg)
630 	void *arg;
631 {
632 	reaper();
633 	/* NOTREACHED */
634 }
635 
636 #ifdef CRYPTO
637 void
638 start_crypto(arg)
639 	void *arg;
640 {
641 	crypto_thread();
642 	/* NOTREACHED */
643 }
644 #endif /* CRYPTO */
645