xref: /openbsd-src/sys/kern/init_main.c (revision 8500990981f885cbe5e6a4958549cacc238b5ae6)
1 /*	$OpenBSD: init_main.c,v 1.108 2003/11/03 18:24:52 tedu 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 void	init_exec(void);
139 
140 extern char sigcode[], esigcode[];
141 #ifdef SYSCALL_DEBUG
142 extern char *syscallnames[];
143 #endif
144 
145 struct emul emul_native = {
146 	"native",
147 	NULL,
148 	sendsig,
149 	SYS_syscall,
150 	SYS_MAXSYSCALL,
151 	sysent,
152 #ifdef SYSCALL_DEBUG
153 	syscallnames,
154 #else
155 	NULL,
156 #endif
157 	0,
158 	copyargs,
159 	setregs,
160 	NULL,
161 	sigcode,
162 	esigcode,
163 	EMUL_ENABLED | EMUL_NATIVE,
164 };
165 
166 
167 /*
168  * System startup; initialize the world, create process 0, mount root
169  * filesystem, and fork to create init and pagedaemon.  Most of the
170  * hard work is done in the lower-level initialization routines including
171  * startup(), which does memory initialization and autoconfiguration.
172  */
173 /* XXX return int, so gcc -Werror won't complain */
174 int
175 main(framep)
176 	void *framep;				/* XXX should go away */
177 {
178 	struct proc *p;
179 	struct pdevinit *pdev;
180 	struct timeval rtv;
181 	quad_t lim;
182 	int s, i;
183 	register_t rval[2];
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 	arc4random_bytes(__guard, sizeof(__guard));
373 #endif
374 
375 	/* init exec and emul */
376 	init_exec();
377 
378 	/* Start the scheduler */
379 	scheduler_start();
380 
381 	dostartuphooks();
382 
383 	/* Configure root/swap devices */
384 	if (md_diskconf)
385 		(*md_diskconf)();
386 
387 	/* Mount the root file system. */
388 	if (vfs_mountroot())
389 		panic("cannot mount root");
390 	CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;
391 
392 	/* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
393 	if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
394 		panic("cannot find root vnode");
395 	p->p_fd->fd_cdir = rootvnode;
396 	VREF(p->p_fd->fd_cdir);
397 	VOP_UNLOCK(rootvnode, 0, p);
398 	p->p_fd->fd_rdir = NULL;
399 
400 	uvm_swap_init();
401 
402 	/*
403 	 * Now can look at time, having had a chance to verify the time
404 	 * from the file system.  Reset p->p_rtime as it may have been
405 	 * munched in mi_switch() after the time got set.
406 	 */
407 	p->p_stats->p_start = runtime = mono_time = boottime = time;
408 	p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
409 
410 	/* Create process 1 (init(8)). */
411 	if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, rval))
412 		panic("fork init");
413 
414 	/* Create process 2, the pageout daemon kernel thread. */
415 	if (kthread_create(uvm_pageout, NULL, NULL, "pagedaemon"))
416 		panic("fork pagedaemon");
417 
418 	/* Create process 3, the reaper daemon kernel thread. */
419 	if (kthread_create(start_reaper, NULL, NULL, "reaper"))
420 		panic("fork reaper");
421 
422 	/* Create process 4, the cleaner daemon kernel thread. */
423 	if (kthread_create(start_cleaner, NULL, NULL, "cleaner"))
424 		panic("fork cleaner");
425 
426 	/* Create process 5, the update daemon kernel thread. */
427 	if (kthread_create(start_update, NULL, NULL, "update"))
428 		panic("fork update");
429 
430 	/* Create process 6, the aiodone daemon kernel thread. */
431 	if (kthread_create(uvm_aiodone_daemon, NULL, NULL, "aiodoned"))
432 		panic("fork aiodoned");
433 
434 #ifdef CRYPTO
435 	/* Create process 7, the crypto kernel thread. */
436 	if (kthread_create(start_crypto, NULL, NULL, "crypto"))
437 		panic("crypto thread");
438 #endif /* CRYPTO */
439 
440 	/* Create any other deferred kernel threads. */
441 	kthread_run_deferred_queue();
442 
443 	microtime(&rtv);
444 	srandom((u_long)(rtv.tv_sec ^ rtv.tv_usec));
445 
446 	randompid = 1;
447 	/* The scheduler is an infinite loop. */
448 	uvm_scheduler();
449 	/* NOTREACHED */
450 }
451 
452 /*
453  * List of paths to try when searching for "init".
454  */
455 static char *initpaths[] = {
456 	"/sbin/init",
457 	"/sbin/oinit",
458 	"/sbin/init.bak",
459 	NULL,
460 };
461 
462 void
463 check_console(p)
464 	struct proc *p;
465 {
466 	struct nameidata nd;
467 	int error;
468 
469 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
470 	error = namei(&nd);
471 	if (error) {
472 		if (error == ENOENT)
473 			printf("warning: /dev/console does not exist\n");
474 		else
475 			printf("warning: /dev/console error %d\n", error);
476 	} else
477 		vrele(nd.ni_vp);
478 }
479 
480 /*
481  * Start the initial user process; try exec'ing each pathname in "initpaths".
482  * The program is invoked with one argument containing the boot flags.
483  */
484 void
485 start_init(arg)
486 	void *arg;
487 {
488 	struct proc *p = arg;
489 	vaddr_t addr;
490 	struct sys_execve_args /* {
491 		syscallarg(const char *) path;
492 		syscallarg(char *const *) argp;
493 		syscallarg(char *const *) envp;
494 	} */ args;
495 	int options, error;
496 	long i;
497 	register_t retval[2];
498 	char flags[4], *flagsp;
499 	char **pathp, *path, *ucp, **uap, *arg0, *arg1 = NULL;
500 
501 	initproc = p;
502 
503 	/*
504 	 * Now in process 1.
505 	 */
506 	check_console(p);
507 
508 	/*
509 	 * Need just enough stack to hold the faked-up "execve()" arguments.
510 	 */
511 #ifdef MACHINE_STACK_GROWS_UP
512 	addr = USRSTACK;
513 #else
514 	addr = USRSTACK - PAGE_SIZE;
515 #endif
516 	if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
517 	    NULL, UVM_UNKNOWN_OFFSET, 0,
518 	    UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL, UVM_INH_COPY,
519 	    UVM_ADV_NORMAL, UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)))
520 		panic("init: couldn't allocate argument space");
521 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
522 
523 	for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
524 #ifdef MACHINE_STACK_GROWS_UP
525 		ucp = (char *)addr;
526 #else
527 		ucp = (char *)(addr + PAGE_SIZE);
528 #endif
529 		/*
530 		 * Construct the boot flag argument.
531 		 */
532 		flagsp = flags;
533 		*flagsp++ = '-';
534 		options = 0;
535 
536 		if (boothowto & RB_SINGLE) {
537 			*flagsp++ = 's';
538 			options = 1;
539 		}
540 #ifdef notyet
541 		if (boothowto & RB_FASTBOOT) {
542 			*flagsp++ = 'f';
543 			options = 1;
544 		}
545 #endif
546 
547 		/*
548 		 * Move out the flags (arg 1), if necessary.
549 		 */
550 		if (options != 0) {
551 			*flagsp++ = '\0';
552 			i = flagsp - flags;
553 #ifdef DEBUG
554 			printf("init: copying out flags `%s' %d\n", flags, i);
555 #endif
556 #ifdef MACHINE_STACK_GROWS_UP
557 			arg1 = ucp;
558 			(void)copyout((caddr_t)flags, (caddr_t)ucp, i);
559 			ucp += i;
560 #else
561 			(void)copyout((caddr_t)flags, (caddr_t)(ucp -= i), i);
562 			arg1 = ucp;
563 #endif
564 		}
565 
566 		/*
567 		 * Move out the file name (also arg 0).
568 		 */
569 		i = strlen(path) + 1;
570 #ifdef DEBUG
571 		printf("init: copying out path `%s' %d\n", path, i);
572 #endif
573 #ifdef MACHINE_STACK_GROWS_UP
574 		arg0 = ucp;
575 		(void)copyout((caddr_t)path, (caddr_t)ucp, i);
576 		ucp += i;
577 		ucp = (caddr_t)ALIGN((u_long)ucp);
578 		uap = (char **)ucp + 3;
579 #else
580 		(void)copyout((caddr_t)path, (caddr_t)(ucp -= i), i);
581 		arg0 = ucp;
582 		uap = (char **)((u_long)ucp & ~ALIGNBYTES);
583 #endif
584 
585 		/*
586 		 * Move out the arg pointers.
587 		 */
588 		i = 0;
589 		copyout(&i, (caddr_t)--uap, sizeof(register_t)); /* terminator */
590 		if (options != 0)
591 			copyout(&arg1, (caddr_t)--uap, sizeof(register_t));
592 		copyout(&arg0, (caddr_t)--uap, sizeof(register_t));
593 
594 		/*
595 		 * Point at the arguments.
596 		 */
597 		SCARG(&args, path) = arg0;
598 		SCARG(&args, argp) = uap;
599 		SCARG(&args, envp) = NULL;
600 
601 		/*
602 		 * Now try to exec the program.  If can't for any reason
603 		 * other than it doesn't exist, complain.
604 		 */
605 		if ((error = sys_execve(p, &args, retval)) == 0)
606 			return;
607 		if (error != ENOENT)
608 			printf("exec %s: error %d\n", path, error);
609 	}
610 	printf("init: not found\n");
611 	panic("no init");
612 }
613 
614 void
615 start_update(arg)
616 	void *arg;
617 {
618 	sched_sync(curproc);
619 	/* NOTREACHED */
620 }
621 
622 void
623 start_cleaner(arg)
624 	void *arg;
625 {
626 	buf_daemon(curproc);
627 	/* NOTREACHED */
628 }
629 
630 void
631 start_reaper(arg)
632 	void *arg;
633 {
634 	reaper();
635 	/* NOTREACHED */
636 }
637 
638 #ifdef CRYPTO
639 void
640 start_crypto(arg)
641 	void *arg;
642 {
643 	crypto_thread();
644 	/* NOTREACHED */
645 }
646 #endif /* CRYPTO */
647