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