xref: /freebsd/sys/kern/init_main.c (revision 61afd5bb22d787b0641523e7b9b95c964d669bd5)
1 /*
2  * Copyright (c) 1995 Terrence R. Lambert
3  * All rights reserved.
4  *
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.9 (Berkeley) 1/21/94
42  * $Id: init_main.c,v 1.51 1996/10/28 11:34:42 phk Exp $
43  */
44 
45 #include "opt_rlimit.h"
46 #include "opt_devfs.h"
47 
48 #include <sys/param.h>
49 #include <sys/filedesc.h>
50 #include <sys/kernel.h>
51 #include <sys/sysctl.h>
52 #include <sys/proc.h>
53 #include <sys/resourcevar.h>
54 #include <sys/signalvar.h>
55 #include <sys/systm.h>
56 #include <sys/vnode.h>
57 #include <sys/sysent.h>
58 #include <sys/reboot.h>
59 #include <sys/sysproto.h>
60 #include <sys/vmmeter.h>
61 
62 #include <machine/cpu.h>
63 
64 #include <vm/vm.h>
65 #include <vm/vm_param.h>
66 #include <vm/vm_prot.h>
67 #include <vm/lock.h>
68 #include <vm/pmap.h>
69 #include <vm/vm_map.h>
70 #include <sys/user.h>
71 
72 extern struct linker_set	sysinit_set;	/* XXX */
73 
74 extern void __main __P((void));
75 extern void main __P((void *framep));
76 
77 /* Components of the first process -- never freed. */
78 static struct session session0;
79 static struct pgrp pgrp0;
80 struct	proc proc0;
81 static struct pcred cred0;
82 static struct filedesc0 filedesc0;
83 static struct plimit limit0;
84 static struct vmspace vmspace0;
85 struct	proc *curproc = &proc0;
86 struct	proc *initproc;
87 
88 int cmask = CMASK;
89 extern	struct user *proc0paddr;
90 
91 struct	vnode *rootvp;
92 int	boothowto;
93 
94 struct	timeval boottime;
95 SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime,
96 	CTLFLAG_RW, &boottime, timeval, "");
97 
98 struct	timeval runtime;
99 
100 /*
101  * Promiscuous argument pass for start_init()
102  *
103  * This is a kludge because we use a return from main() rather than a call
104  * to a new routine in locore.s to kick the kernel alive from locore.s.
105  */
106 static void	*init_framep;
107 
108 
109 #if __GNUC__ >= 2
110 void __main() {}
111 #endif
112 
113 
114 /*
115  * This ensures that there is at least one entry so that the sysinit_set
116  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
117  * executed.
118  */
119 SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
120 
121 
122 /*
123  * System startup; initialize the world, create process 0, mount root
124  * filesystem, and fork to create init and pagedaemon.  Most of the
125  * hard work is done in the lower-level initialization routines including
126  * startup(), which does memory initialization and autoconfiguration.
127  *
128  * This allows simple addition of new kernel subsystems that require
129  * boot time initialization.  It also allows substitution of subsystem
130  * (for instance, a scheduler, kernel profiler, or VM system) by object
131  * module.  Finally, it allows for optional "kernel threads", like an LFS
132  * cleaner.
133  */
134 void
135 main(framep)
136 	void *framep;
137 {
138 
139 	register struct sysinit **sipp;		/* system initialization*/
140 	register struct sysinit **xipp;		/* interior loop of sort*/
141 	register struct sysinit *save;		/* bubble*/
142 	int			rval[2];	/* SI_TYPE_KTHREAD support*/
143 
144 	/*
145 	 * Save the locore.s frame pointer for start_init().
146 	 */
147 	init_framep = framep;
148 
149 	/*
150 	 * Perform a bubble sort of the system initialization objects by
151 	 * their subsystem (primary key) and order (secondary key).
152 	 *
153 	 * Since some things care about execution order, this is the
154 	 * operation which ensures continued function.
155 	 */
156 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
157 		for( xipp = sipp + 1; *xipp; xipp++) {
158 			if( (*sipp)->subsystem < (*xipp)->subsystem ||
159 			    ( (*sipp)->subsystem == (*xipp)->subsystem &&
160 			      (*sipp)->order < (*xipp)->order))
161 				continue;	/* skip*/
162 			save = *sipp;
163 			*sipp = *xipp;
164 			*xipp = save;
165 		}
166 	}
167 
168 	/*
169 	 * Traverse the (now) ordered list of system initialization tasks.
170 	 * Perform each task, and continue on to the next task.
171 	 *
172 	 * The last item on the list is expected to be the scheduler,
173 	 * which will not return.
174 	 */
175 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
176 		if( (*sipp)->subsystem == SI_SUB_DUMMY)
177 			continue;	/* skip dummy task(s)*/
178 
179 		switch( (*sipp)->type) {
180 		case SI_TYPE_DEFAULT:
181 			/* no special processing*/
182 			(*((*sipp)->func))( (*sipp)->udata);
183 			break;
184 
185 		case SI_TYPE_KTHREAD:
186 			/* kernel thread*/
187 			if (fork(&proc0, NULL, rval))
188 				panic("fork kernel process");
189 			if (rval[1]) {
190 				(*((*sipp)->func))( (*sipp)->udata);
191 				/*
192 				 * The call to start "init" returns
193 				 * here after the scheduler has been
194 				 * started, and returns to the caller
195 				 * in i386/i386/locore.s.  This is a
196 				 * necessary part of initialization
197 				 * and is rather non-obvious.
198 				 *
199 				 * No other "kernel threads" should
200 				 * return here.  Call panic() instead.
201 				 */
202 				return;
203 			}
204 			break;
205 
206 		default:
207 			panic( "init_main: unrecognized init type");
208 		}
209 	}
210 
211 	/* NOTREACHED*/
212 }
213 
214 
215 /*
216  * Start a kernel process.  This is called after a fork() call in
217  * main() in the file kern/init_main.c.
218  *
219  * This function is used to start "internal" daemons.
220  */
221 /* ARGSUSED*/
222 void
223 kproc_start(udata)
224 	void *udata;
225 {
226 	struct kproc_desc	*kp = udata;
227 	struct proc		*p = curproc;
228 
229 	/* save a global descriptor, if desired*/
230 	if( kp->global_procpp != NULL)
231 		*kp->global_procpp	= p;
232 
233 	/* this is a non-swapped system process*/
234 	p->p_flag |= P_INMEM | P_SYSTEM;
235 
236 	/* set up arg0 for 'ps', et al*/
237 	strcpy( p->p_comm, kp->arg0);
238 
239 	/* call the processes' main()...*/
240 	(*kp->func)();
241 
242 	/* NOTREACHED */
243 	panic("kproc_start: %s", kp->arg0);
244 }
245 
246 
247 /*
248  ***************************************************************************
249  ****
250  **** The following SYSINIT's belong elsewhere, but have not yet
251  **** been moved.
252  ****
253  ***************************************************************************
254  */
255 #ifdef OMIT
256 /*
257  * Handled by vfs_mountroot (bad idea) at this time... should be
258  * done the same as 4.4Lite2.
259  */
260 SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
261 #endif	/* OMIT*/
262 
263 /*
264  * Should get its own file...
265  */
266 #ifdef HPFPLIB
267 char	copyright[] =
268 "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n";
269 #else
270 char	copyright[] =
271 "Copyright (c) 1992-1996 FreeBSD Inc.\n"
272 #ifdef PC98
273 "Copyright (c) 1994-1996  FreeBSD(98) porting team.\n"
274 "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\n"
275 "Copyright (c) 1992  A.Kojima F.Ukai M.Ishii (KMC).\n"
276 "\tAll rights reserved.\n\n";
277 #else
278 "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.  All rights reserved.\n\n";
279 #endif
280 #endif
281 static void print_caddr_t __P((void *data));
282 static void
283 print_caddr_t(data)
284 	void *data;
285 {
286 	printf("%s", (char *)data);
287 }
288 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
289 
290 
291 /*
292  ***************************************************************************
293  ****
294  **** The two following SYSINT's are proc0 specific glue code.  I am not
295  **** convinced that they can not be safely combined, but their order of
296  **** operation has been maintained as the same as the original init_main.c
297  **** for right now.
298  ****
299  **** These probably belong in init_proc.c or kern_proc.c, since they
300  **** deal with proc0 (the fork template process).
301  ****
302  ***************************************************************************
303  */
304 /* ARGSUSED*/
305 static void proc0_init __P((void *dummy));
306 static void
307 proc0_init(dummy)
308 	void *dummy;
309 {
310 	register struct proc		*p;
311 	register struct filedesc0	*fdp;
312 	register unsigned i;
313 
314 	/*
315 	 * Initialize the current process pointer (curproc) before
316 	 * any possible traps/probes to simplify trap processing.
317 	 */
318 	p = &proc0;
319 	curproc = p;			/* XXX redundant*/
320 
321 	/*
322 	 * Initialize process and pgrp structures.
323 	 */
324 	procinit();
325 
326 	/*
327 	 * Initialize sleep queue hash table
328 	 */
329 	sleepinit();
330 
331 	/*
332 	 * Create process 0 (the swapper).
333 	 */
334 	LIST_INSERT_HEAD(&allproc, p, p_list);
335 	p->p_pgrp = &pgrp0;
336 	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
337 	LIST_INIT(&pgrp0.pg_members);
338 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
339 
340 	pgrp0.pg_session = &session0;
341 	session0.s_count = 1;
342 	session0.s_leader = p;
343 
344 	p->p_sysent = &aout_sysvec;
345 
346 	p->p_flag = P_INMEM | P_SYSTEM;
347 	p->p_stat = SRUN;
348 	p->p_nice = NZERO;
349 	p->p_rtprio.type = RTP_PRIO_NORMAL;
350 	p->p_rtprio.prio = 0;
351 
352 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
353 
354 	/* Create credentials. */
355 	cred0.p_refcnt = 1;
356 	p->p_cred = &cred0;
357 	p->p_ucred = crget();
358 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
359 
360 	/* Create the file descriptor table. */
361 	fdp = &filedesc0;
362 	p->p_fd = &fdp->fd_fd;
363 	fdp->fd_fd.fd_refcnt = 1;
364 	fdp->fd_fd.fd_cmask = cmask;
365 	fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
366 	fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
367 	fdp->fd_fd.fd_nfiles = NDFILE;
368 
369 	/* Create the limits structures. */
370 	p->p_limit = &limit0;
371 	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
372 		limit0.pl_rlimit[i].rlim_cur =
373 		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
374 	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
375 	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
376 	i = ptoa(cnt.v_free_count);
377 	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
378 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
379 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
380 	limit0.p_refcnt = 1;
381 
382 	/* Allocate a prototype map so we have something to fork. */
383 	p->p_vmspace = &vmspace0;
384 	vmspace0.vm_refcnt = 1;
385 	pmap_pinit(&vmspace0.vm_pmap);
386 	vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
387 	    trunc_page(VM_MAXUSER_ADDRESS), TRUE);
388 	vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
389 	p->p_addr = proc0paddr;				/* XXX */
390 
391 #define INCOMPAT_LITES2
392 #ifdef INCOMPAT_LITES2
393 	/*
394 	 * proc0 needs to have a coherent frame base, too.
395 	 * This probably makes the identical call for the init proc
396 	 * that happens later unnecessary since it should inherit
397 	 * it during the fork.
398 	 */
399 	cpu_set_init_frame(p, init_framep);			/* XXX! */
400 #endif	/* INCOMPAT_LITES2*/
401 
402 	/*
403 	 * We continue to place resource usage info and signal
404 	 * actions in the user struct so they're pageable.
405 	 */
406 	p->p_stats = &p->p_addr->u_stats;
407 	p->p_sigacts = &p->p_addr->u_sigacts;
408 
409 	/*
410 	 * Charge root for one process.
411 	 */
412 	(void)chgproccnt(0, 1);
413 }
414 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
415 
416 /* ARGSUSED*/
417 static void proc0_post __P((void *dummy));
418 static void
419 proc0_post(dummy)
420 	void *dummy;
421 {
422 	struct timeval tv;
423 
424 	/*
425 	 * Now can look at time, having had a chance to verify the time
426 	 * from the file system.  Reset p->p_rtime as it may have been
427 	 * munched in mi_switch() after the time got set.
428 	 */
429 	proc0.p_stats->p_start = runtime = mono_time = boottime = time;
430 	proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0;
431 
432 	/*
433 	 * Give the ``random'' number generator a thump.
434 	 */
435 	microtime(&tv);
436 	srandom(tv.tv_sec ^ tv.tv_usec);
437 
438 	/* Initialize signal state for process 0. */
439 	siginit(&proc0);
440 }
441 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
442 
443 
444 
445 
446 /*
447  ***************************************************************************
448  ****
449  **** The following SYSINIT's and glue code should be moved to the
450  **** respective files on a per subsystem basis.
451  ****
452  ***************************************************************************
453  */
454 /* ARGSUSED*/
455 static void sched_setup __P((void *dummy));
456 static void
457 sched_setup(dummy)
458 	void *dummy;
459 {
460 	/* Kick off timeout driven events by calling first time. */
461 	roundrobin(NULL);
462 	schedcpu(NULL);
463 }
464 SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL)
465 
466 /* ARGSUSED*/
467 static void xxx_vfs_mountroot __P((void *dummy));
468 static void
469 xxx_vfs_mountroot(dummy)
470 	void *dummy;
471 {
472 	/* Mount the root file system. */
473 	if ((*mountroot)(mountrootvfsops))
474 		panic("cannot mount root");
475 }
476 SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL)
477 
478 /* ARGSUSED*/
479 static void xxx_vfs_root_fdtab __P((void *dummy));
480 static void
481 xxx_vfs_root_fdtab(dummy)
482 	void *dummy;
483 {
484 	register struct filedesc0	*fdp = &filedesc0;
485 
486 	/* Get the vnode for '/'.  Set fdp->fd_fd.fd_cdir to reference it. */
487 	if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
488 		panic("cannot find root vnode");
489 	fdp->fd_fd.fd_cdir = rootvnode;
490 	VREF(fdp->fd_fd.fd_cdir);
491 	VOP_UNLOCK(rootvnode);
492 	fdp->fd_fd.fd_rdir = NULL;
493 }
494 SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
495 
496 
497 /*
498  ***************************************************************************
499  ****
500  **** The following code probably belongs in another file, like
501  **** kern/init_init.c.  It is here for two reasons only:
502  ****
503  ****	1)	This code returns to startup the system; this is
504  ****		abnormal for a kernel thread.
505  ****	2)	This code promiscuously uses init_frame
506  ****
507  ***************************************************************************
508  */
509 
510 static void kthread_init __P((void *dummy));
511 SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
512 
513 
514 static void start_init __P((struct proc *p, void *framep));
515 
516 /* ARGSUSED*/
517 static void
518 kthread_init(dummy)
519 	void *dummy;
520 {
521 
522 	/* Create process 1 (init(8)). */
523 	start_init(curproc, init_framep);
524 
525 	/*
526 	 * This is the only kernel thread allowed to return yo the
527 	 * caller!!!
528 	 */
529 	return;
530 }
531 
532 
533 /*
534  * List of paths to try when searching for "init".
535  */
536 static char *initpaths[] = {
537 	"/sbin/init",
538 	"/sbin/oinit",
539 	"/sbin/init.bak",
540 	"/stand/sysinstall",
541 	NULL,
542 };
543 
544 /*
545  * Start the initial user process; try exec'ing each pathname in "initpaths".
546  * The program is invoked with one argument containing the boot flags.
547  */
548 static void
549 start_init(p, framep)
550 	struct proc *p;
551 	void *framep;
552 {
553 	vm_offset_t addr;
554 	struct execve_args args;
555 	int options, i, retval[2], error;
556 	char **pathp, *path, *ucp, **uap, *arg0, *arg1;
557 
558 	initproc = p;
559 
560 	/*
561 	 * We need to set the system call frame as if we were entered through
562 	 * a syscall() so that when we call execve() below, it will be able
563 	 * to set the entry point (see setregs) when it tries to exec.  The
564 	 * startup code in "locore.s" has allocated space for the frame and
565 	 * passed a pointer to that space as main's argument.
566 	 */
567 	cpu_set_init_frame(p, framep);
568 
569 	/*
570 	 * Need just enough stack to hold the faked-up "execve()" arguments.
571 	 */
572 	addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE);
573 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
574 		panic("init: couldn't allocate argument space");
575 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
576 	p->p_vmspace->vm_ssize = 1;
577 
578 	for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
579 		/*
580 		 * Move out the boot flag argument.
581 		 */
582 		options = 0;
583 		ucp = (char *)USRSTACK;
584 		(void)subyte(--ucp, 0);		/* trailing zero */
585 		if (boothowto & RB_SINGLE) {
586 			(void)subyte(--ucp, 's');
587 			options = 1;
588 		}
589 #ifdef notyet
590                 if (boothowto & RB_FASTBOOT) {
591 			(void)subyte(--ucp, 'f');
592 			options = 1;
593 		}
594 #endif
595 
596 #ifdef BOOTCDROM
597 		(void)subyte(--ucp, 'C');
598 		options = 1;
599 #endif
600 
601 #if defined(DEVFS) && defined(DEVFS_ROOT)
602 		(void)subyte(--ucp, 'd');
603 		options = 1;
604 #endif
605 		if (options == 0)
606 			(void)subyte(--ucp, '-');
607 		(void)subyte(--ucp, '-');		/* leading hyphen */
608 		arg1 = ucp;
609 
610 		/*
611 		 * Move out the file name (also arg 0).
612 		 */
613 		for (i = strlen(path) + 1; i >= 0; i--)
614 			(void)subyte(--ucp, path[i]);
615 		arg0 = ucp;
616 
617 		/*
618 		 * Move out the arg pointers.
619 		 */
620 		uap = (char **)((int)ucp & ~(NBPW-1));
621 		(void)suword((caddr_t)--uap, 0);	/* terminator */
622 		(void)suword((caddr_t)--uap, (int)arg1);
623 		(void)suword((caddr_t)--uap, (int)arg0);
624 
625 		/*
626 		 * Point at the arguments.
627 		 */
628 		args.fname = arg0;
629 		args.argv = uap;
630 		args.envv = NULL;
631 
632 		/*
633 		 * Now try to exec the program.  If can't for any reason
634 		 * other than it doesn't exist, complain.
635 		 *
636 		 * Otherwise return to main() which returns to btext
637 		 * which completes the system startup.
638 		 */
639 		if ((error = execve(p, &args, &retval[0])) == 0)
640 			return;
641 		if (error != ENOENT)
642 			printf("exec %s: error %d\n", path, error);
643 	}
644 	printf("init: not found\n");
645 	panic("no init");
646 }
647