xref: /freebsd/sys/kern/init_main.c (revision 154c04e573d8936b2a3a86222dfe6a1cf333ed44)
1df8bae1dSRodney W. Grimes /*
22b14f991SJulian Elischer  * Copyright (c) 1995 Terrence R. Lambert
32b14f991SJulian Elischer  * All rights reserved.
42b14f991SJulian Elischer  *
5df8bae1dSRodney W. Grimes  * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
6df8bae1dSRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
7df8bae1dSRodney W. Grimes  * (c) UNIX System Laboratories, Inc.
8df8bae1dSRodney W. Grimes  * All or some portions of this file are derived from material licensed
9df8bae1dSRodney W. Grimes  * to the University of California by American Telephone and Telegraph
10df8bae1dSRodney W. Grimes  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11df8bae1dSRodney W. Grimes  * the permission of UNIX System Laboratories, Inc.
12df8bae1dSRodney W. Grimes  *
13df8bae1dSRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
14df8bae1dSRodney W. Grimes  * modification, are permitted provided that the following conditions
15df8bae1dSRodney W. Grimes  * are met:
16df8bae1dSRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
17df8bae1dSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
18df8bae1dSRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
19df8bae1dSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
20df8bae1dSRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
21df8bae1dSRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
22df8bae1dSRodney W. Grimes  *    must display the following acknowledgement:
23df8bae1dSRodney W. Grimes  *	This product includes software developed by the University of
24df8bae1dSRodney W. Grimes  *	California, Berkeley and its contributors.
25df8bae1dSRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
26df8bae1dSRodney W. Grimes  *    may be used to endorse or promote products derived from this software
27df8bae1dSRodney W. Grimes  *    without specific prior written permission.
28df8bae1dSRodney W. Grimes  *
29df8bae1dSRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30df8bae1dSRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31df8bae1dSRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32df8bae1dSRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33df8bae1dSRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34df8bae1dSRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35df8bae1dSRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36df8bae1dSRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37df8bae1dSRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38df8bae1dSRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39df8bae1dSRodney W. Grimes  * SUCH DAMAGE.
40df8bae1dSRodney W. Grimes  *
41df8bae1dSRodney W. Grimes  *	@(#)init_main.c	8.9 (Berkeley) 1/21/94
42154c04e5SPoul-Henning Kamp  * $Id: init_main.c,v 1.35 1995/12/07 12:46:36 davidg Exp $
43df8bae1dSRodney W. Grimes  */
44df8bae1dSRodney W. Grimes 
45df8bae1dSRodney W. Grimes #include <sys/param.h>
46df8bae1dSRodney W. Grimes #include <sys/filedesc.h>
47df8bae1dSRodney W. Grimes #include <sys/errno.h>
48df8bae1dSRodney W. Grimes #include <sys/exec.h>
49df8bae1dSRodney W. Grimes #include <sys/kernel.h>
50946bb7a2SPoul-Henning Kamp #include <sys/sysctl.h>
51b5e8ce9fSBruce Evans #ifdef GPROF
52b5e8ce9fSBruce Evans #include <sys/gmon.h>
53b5e8ce9fSBruce Evans #endif
54df8bae1dSRodney W. Grimes #include <sys/mount.h>
55df8bae1dSRodney W. Grimes #include <sys/proc.h>
56df8bae1dSRodney W. Grimes #include <sys/resourcevar.h>
57df8bae1dSRodney W. Grimes #include <sys/signalvar.h>
58df8bae1dSRodney W. Grimes #include <sys/systm.h>
59df8bae1dSRodney W. Grimes #include <sys/vnode.h>
60f3f0ca60SSøren Schmidt #include <sys/sysent.h>
61df8bae1dSRodney W. Grimes #include <sys/conf.h>
62df8bae1dSRodney W. Grimes #include <sys/buf.h>
63df8bae1dSRodney W. Grimes #include <sys/clist.h>
643aa12267SBruce Evans #include <sys/msg.h>
65df8bae1dSRodney W. Grimes #include <sys/protosw.h>
66df8bae1dSRodney W. Grimes #include <sys/reboot.h>
673aa12267SBruce Evans #include <sys/sem.h>
683aa12267SBruce Evans #include <sys/shm.h>
69ad7507e2SSteven Wallace #include <sys/sysproto.h>
70efeaf95aSDavid Greenman #include <sys/vmmeter.h>
71df8bae1dSRodney W. Grimes 
72df8bae1dSRodney W. Grimes #include <ufs/ufs/quota.h>
73df8bae1dSRodney W. Grimes 
74df8bae1dSRodney W. Grimes #include <machine/cpu.h>
75df8bae1dSRodney W. Grimes 
76df8bae1dSRodney W. Grimes #include <vm/vm.h>
77efeaf95aSDavid Greenman #include <vm/vm_param.h>
78efeaf95aSDavid Greenman #include <vm/vm_prot.h>
79efeaf95aSDavid Greenman #include <vm/lock.h>
80efeaf95aSDavid Greenman #include <vm/pmap.h>
81efeaf95aSDavid Greenman #include <vm/vm_map.h>
82efeaf95aSDavid Greenman #include <vm/vm_extern.h>
83efeaf95aSDavid Greenman #include <sys/user.h>
84df8bae1dSRodney W. Grimes 
859ef6c28aSBruce Evans extern struct linker_set	sysinit_set;	/* XXX */
869ef6c28aSBruce Evans 
879ef6c28aSBruce Evans extern void __main __P((void));
889ef6c28aSBruce Evans extern void main __P((void *framep));
89df8bae1dSRodney W. Grimes 
90df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */
91154c04e5SPoul-Henning Kamp static struct session session0;
92154c04e5SPoul-Henning Kamp static struct pgrp pgrp0;
93df8bae1dSRodney W. Grimes struct	proc proc0;
94154c04e5SPoul-Henning Kamp static struct pcred cred0;
95154c04e5SPoul-Henning Kamp static struct filedesc0 filedesc0;
96154c04e5SPoul-Henning Kamp static struct plimit limit0;
97154c04e5SPoul-Henning Kamp static struct vmspace vmspace0;
98df8bae1dSRodney W. Grimes struct	proc *curproc = &proc0;
992b14f991SJulian Elischer struct	proc *initproc;
100df8bae1dSRodney W. Grimes 
101154c04e5SPoul-Henning Kamp static int cmask = CMASK;
102df8bae1dSRodney W. Grimes extern	struct user *proc0paddr;
103df8bae1dSRodney W. Grimes 
1042976b7f1SDavid Greenman struct	vnode *rootvp;
105df8bae1dSRodney W. Grimes int	boothowto;
106946bb7a2SPoul-Henning Kamp 
107df8bae1dSRodney W. Grimes struct	timeval boottime;
108946bb7a2SPoul-Henning Kamp SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime,
109946bb7a2SPoul-Henning Kamp 	CTLFLAG_RW, &boottime, timeval, "");
110946bb7a2SPoul-Henning Kamp 
111df8bae1dSRodney W. Grimes struct	timeval runtime;
112df8bae1dSRodney W. Grimes 
1132b14f991SJulian Elischer /*
1142b14f991SJulian Elischer  * Promiscuous argument pass for start_init()
1152b14f991SJulian Elischer  *
1162b14f991SJulian Elischer  * This is a kludge because we use a return from main() rather than a call
1172b14f991SJulian Elischer  * to a new reoutine in locore.s to kick the kernel alive from locore.s.
1182b14f991SJulian Elischer  */
1192b14f991SJulian Elischer static void	*init_framep;
1202b14f991SJulian Elischer 
121df8bae1dSRodney W. Grimes 
12226f9a767SRodney W. Grimes #if __GNUC__ >= 2
12326f9a767SRodney W. Grimes void __main() {}
12426f9a767SRodney W. Grimes #endif
12526f9a767SRodney W. Grimes 
1262b14f991SJulian Elischer 
12726f9a767SRodney W. Grimes /*
1282b14f991SJulian Elischer  * This ensures that there is at least one entry so that the sysinit_set
1292b14f991SJulian Elischer  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
1302b14f991SJulian Elischer  * executed.
13126f9a767SRodney W. Grimes  */
1322b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
1338a129caeSDavid Greenman 
13426f9a767SRodney W. Grimes 
135df8bae1dSRodney W. Grimes /*
136df8bae1dSRodney W. Grimes  * System startup; initialize the world, create process 0, mount root
137df8bae1dSRodney W. Grimes  * filesystem, and fork to create init and pagedaemon.  Most of the
138df8bae1dSRodney W. Grimes  * hard work is done in the lower-level initialization routines including
139df8bae1dSRodney W. Grimes  * startup(), which does memory initialization and autoconfiguration.
1402b14f991SJulian Elischer  *
1412b14f991SJulian Elischer  * This allows simple addition of new kernel subsystems that require
1422b14f991SJulian Elischer  * boot time initialization.  It also allows substitution of subsystem
1432b14f991SJulian Elischer  * (for instance, a scheduler, kernel profiler, or VM system) by object
1442b14f991SJulian Elischer  * module.  Finally, it allows for optional "kernel threads", like an LFS
1452b14f991SJulian Elischer  * cleaner.
146df8bae1dSRodney W. Grimes  */
14726f9a767SRodney W. Grimes void
148df8bae1dSRodney W. Grimes main(framep)
149df8bae1dSRodney W. Grimes 	void *framep;
150df8bae1dSRodney W. Grimes {
1512b14f991SJulian Elischer 
1522b14f991SJulian Elischer 	register struct sysinit **sipp;		/* system initialization*/
1532b14f991SJulian Elischer 	register struct sysinit **xipp;		/* interior loop of sort*/
1542b14f991SJulian Elischer 	register struct sysinit *save;		/* bubble*/
1552b14f991SJulian Elischer 	int			rval[2];	/* SI_TYPE_KTHREAD support*/
1562b14f991SJulian Elischer 
1572b14f991SJulian Elischer 	/*
1582b14f991SJulian Elischer 	 * Save the locore.s frame pointer for start_init().
1592b14f991SJulian Elischer 	 */
1602b14f991SJulian Elischer 	init_framep = framep;
1612b14f991SJulian Elischer 
1622b14f991SJulian Elischer 	/*
1632b14f991SJulian Elischer 	 * Perform a bubble sort of the system initialization objects by
1642b14f991SJulian Elischer 	 * their subsystem (primary key) and order (secondary key).
1652b14f991SJulian Elischer 	 *
1662b14f991SJulian Elischer 	 * Since some things care about execution order, this is the
1672b14f991SJulian Elischer 	 * operation which ensures continued function.
1682b14f991SJulian Elischer 	 */
1692b14f991SJulian Elischer 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
1702b14f991SJulian Elischer 		for( xipp = sipp + 1; *xipp; xipp++) {
1712b14f991SJulian Elischer 			if( (*sipp)->subsystem < (*xipp)->subsystem ||
1722b14f991SJulian Elischer 			    ( (*sipp)->subsystem == (*xipp)->subsystem &&
1732b14f991SJulian Elischer 			      (*sipp)->order < (*xipp)->order))
1742b14f991SJulian Elischer 				continue;	/* skip*/
1752b14f991SJulian Elischer 			save = *sipp;
1762b14f991SJulian Elischer 			*sipp = *xipp;
1772b14f991SJulian Elischer 			*xipp = save;
1782b14f991SJulian Elischer 		}
1792b14f991SJulian Elischer 	}
1802b14f991SJulian Elischer 
1812b14f991SJulian Elischer 	/*
1822b14f991SJulian Elischer 	 * Traverse the (now) ordered list of system initialization tasks.
1832b14f991SJulian Elischer 	 * Perform each task, and continue on to the next task.
1842b14f991SJulian Elischer 	 *
1852b14f991SJulian Elischer 	 * The last item on the list is expected to be the scheduler,
1862b14f991SJulian Elischer 	 * which will not return.
1872b14f991SJulian Elischer 	 */
1882b14f991SJulian Elischer 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
1892b14f991SJulian Elischer 		if( (*sipp)->subsystem == SI_SUB_DUMMY)
1902b14f991SJulian Elischer 			continue;	/* skip dummy task(s)*/
1912b14f991SJulian Elischer 
1922b14f991SJulian Elischer 		switch( (*sipp)->type) {
1932b14f991SJulian Elischer 		case SI_TYPE_DEFAULT:
1942b14f991SJulian Elischer 			/* no special processing*/
1952b14f991SJulian Elischer 			(*((*sipp)->func))( (*sipp)->udata);
1962b14f991SJulian Elischer 			break;
1972b14f991SJulian Elischer 
1982b14f991SJulian Elischer 		case SI_TYPE_KTHREAD:
1992b14f991SJulian Elischer 			/* kernel thread*/
2002b14f991SJulian Elischer 			if (fork(&proc0, NULL, rval))
2012b14f991SJulian Elischer 				panic("fork kernel process");
2022b14f991SJulian Elischer 			if (rval[1]) {
2032b14f991SJulian Elischer 				(*((*sipp)->func))( (*sipp)->udata);
2042b14f991SJulian Elischer 				/*
2052b14f991SJulian Elischer 				 * The call to start "init" returns
2062b14f991SJulian Elischer 				 * here after the scheduler has been
2072b14f991SJulian Elischer 				 * started, and returns to the caller
2082b14f991SJulian Elischer 				 * in i386/i386/locore.s.  This is a
2092b14f991SJulian Elischer 				 * necessary part of initialization
2102b14f991SJulian Elischer 				 * and is rather non-obvious.
2112b14f991SJulian Elischer 				 *
2122b14f991SJulian Elischer 				 * No other "kernel threads" should
2132b14f991SJulian Elischer 				 * return here.  Call panic() instead.
2142b14f991SJulian Elischer 				 */
2152b14f991SJulian Elischer 				return;
2162b14f991SJulian Elischer 			}
2172b14f991SJulian Elischer 			break;
2182b14f991SJulian Elischer 
2192b14f991SJulian Elischer 		default:
2202b14f991SJulian Elischer 			panic( "init_main: unrecognized init type");
2212b14f991SJulian Elischer 		}
2222b14f991SJulian Elischer 	}
2232b14f991SJulian Elischer 
2242b14f991SJulian Elischer 	/* NOTREACHED*/
2252b14f991SJulian Elischer }
2262b14f991SJulian Elischer 
2272b14f991SJulian Elischer 
2282b14f991SJulian Elischer /*
2292b14f991SJulian Elischer  * Start a kernel process.  This is called after a fork() call in
2302b14f991SJulian Elischer  * main() in the file kern/init_main.c.
2312b14f991SJulian Elischer  *
2322b14f991SJulian Elischer  * This function is used to start "internal" daemons.
2332b14f991SJulian Elischer  */
2342b14f991SJulian Elischer /* ARGSUSED*/
2352b14f991SJulian Elischer void
2362b14f991SJulian Elischer kproc_start(udata)
237d841aaa7SBruce Evans 	void *udata;
2382b14f991SJulian Elischer {
239d841aaa7SBruce Evans 	struct kproc_desc	*kp = udata;
2402b14f991SJulian Elischer 	struct proc		*p = curproc;
2412b14f991SJulian Elischer 
2422b14f991SJulian Elischer 	/* save a global descriptor, if desired*/
2432b14f991SJulian Elischer 	if( kp->global_procpp != NULL)
2442b14f991SJulian Elischer 		*kp->global_procpp	= p;
2452b14f991SJulian Elischer 
2462b14f991SJulian Elischer 	/* this is a non-swapped system process*/
2472b14f991SJulian Elischer 	p->p_flag |= P_INMEM | P_SYSTEM;
2482b14f991SJulian Elischer 
2492b14f991SJulian Elischer 	/* set up arg0 for 'ps', et al*/
2502b14f991SJulian Elischer 	strcpy( p->p_comm, kp->arg0);
2512b14f991SJulian Elischer 
2522b14f991SJulian Elischer 	/* call the processes' main()...*/
2532b14f991SJulian Elischer 	(*kp->func)();
2542b14f991SJulian Elischer 
2552b14f991SJulian Elischer 	/* NOTREACHED */
2562b14f991SJulian Elischer 	panic("kproc_start: %s", kp->arg0);
2572b14f991SJulian Elischer }
2582b14f991SJulian Elischer 
2592b14f991SJulian Elischer 
2602b14f991SJulian Elischer /*
2612b14f991SJulian Elischer  ***************************************************************************
2622b14f991SJulian Elischer  ****
2632b14f991SJulian Elischer  **** The following SYSINIT's belong elsewhere, but have not yet
2642b14f991SJulian Elischer  **** been moved.
2652b14f991SJulian Elischer  ****
2662b14f991SJulian Elischer  ***************************************************************************
2672b14f991SJulian Elischer  */
2682b14f991SJulian Elischer #ifdef OMIT
2692b14f991SJulian Elischer /*
2702b14f991SJulian Elischer  * Handled by vfs_mountroot (bad idea) at this time... should be
2712b14f991SJulian Elischer  * done the same as 4.4Lite2.
2722b14f991SJulian Elischer  */
2732b14f991SJulian Elischer SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
2742b14f991SJulian Elischer #endif	/* OMIT*/
2752b14f991SJulian Elischer 
2762b14f991SJulian Elischer /*
2772b14f991SJulian Elischer  * Should get its own file...
2782b14f991SJulian Elischer  */
2792b14f991SJulian Elischer #ifdef HPFPLIB
2802b14f991SJulian Elischer char	copyright[] =
2812b14f991SJulian Elischer "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";
2822b14f991SJulian Elischer #else
2832b14f991SJulian Elischer char	copyright[] =
2842b14f991SJulian Elischer "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.  All rights reserved.\n\n";
2852b14f991SJulian Elischer #endif
2864590fd3aSDavid Greenman static void print_caddr_t __P((void *data));
2879ef6c28aSBruce Evans static void
2889ef6c28aSBruce Evans print_caddr_t(data)
2894590fd3aSDavid Greenman 	void *data;
2909ef6c28aSBruce Evans {
2919ef6c28aSBruce Evans 	printf("%s", (char *)data);
2929ef6c28aSBruce Evans }
293d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
2942b14f991SJulian Elischer 
2952b14f991SJulian Elischer 
2962b14f991SJulian Elischer /*
2972b14f991SJulian Elischer  ***************************************************************************
2982b14f991SJulian Elischer  ****
2992b14f991SJulian Elischer  **** The two following SYSINT's are proc0 specific glue code.  I am not
3002b14f991SJulian Elischer  **** convinced that they can not be safely combined, but their order of
3012b14f991SJulian Elischer  **** operation has been maintained as the same as the original init_main.c
3022b14f991SJulian Elischer  **** for right now.
3032b14f991SJulian Elischer  ****
3042b14f991SJulian Elischer  **** These probably belong in init_proc.c or kern_proc.c, since they
3052b14f991SJulian Elischer  **** deal with proc0 (the fork template process).
3062b14f991SJulian Elischer  ****
3072b14f991SJulian Elischer  ***************************************************************************
3082b14f991SJulian Elischer  */
3092b14f991SJulian Elischer /* ARGSUSED*/
310154c04e5SPoul-Henning Kamp static void proc0_init __P((void *dummy));
311154c04e5SPoul-Henning Kamp static void
312d841aaa7SBruce Evans proc0_init(dummy)
313d841aaa7SBruce Evans 	void *dummy;
3142b14f991SJulian Elischer {
315df8bae1dSRodney W. Grimes 	register struct proc		*p;
316df8bae1dSRodney W. Grimes 	register struct filedesc0	*fdp;
317df8bae1dSRodney W. Grimes 	register int i;
318df8bae1dSRodney W. Grimes 
319df8bae1dSRodney W. Grimes 	/*
320df8bae1dSRodney W. Grimes 	 * Initialize the current process pointer (curproc) before
321df8bae1dSRodney W. Grimes 	 * any possible traps/probes to simplify trap processing.
322df8bae1dSRodney W. Grimes 	 */
323df8bae1dSRodney W. Grimes 	p = &proc0;
3242b14f991SJulian Elischer 	curproc = p;			/* XXX redundant*/
325df8bae1dSRodney W. Grimes 
326df8bae1dSRodney W. Grimes 	/*
327df8bae1dSRodney W. Grimes 	 * Create process 0 (the swapper).
328df8bae1dSRodney W. Grimes 	 */
329df8bae1dSRodney W. Grimes 	allproc = (volatile struct proc *)p;
330df8bae1dSRodney W. Grimes 	p->p_prev = (struct proc **)&allproc;
331df8bae1dSRodney W. Grimes 	p->p_pgrp = &pgrp0;
332df8bae1dSRodney W. Grimes 	pgrphash[0] = &pgrp0;
333df8bae1dSRodney W. Grimes 	pgrp0.pg_mem = p;
334df8bae1dSRodney W. Grimes 	pgrp0.pg_session = &session0;
335df8bae1dSRodney W. Grimes 	session0.s_count = 1;
336df8bae1dSRodney W. Grimes 	session0.s_leader = p;
337df8bae1dSRodney W. Grimes 
338f3f0ca60SSøren Schmidt 	p->p_sysent = &aout_sysvec;
339f3f0ca60SSøren Schmidt 
340df8bae1dSRodney W. Grimes 	p->p_flag = P_INMEM | P_SYSTEM;
341df8bae1dSRodney W. Grimes 	p->p_stat = SRUN;
342df8bae1dSRodney W. Grimes 	p->p_nice = NZERO;
3437216391eSDavid Greenman 	p->p_rtprio.type = RTP_PRIO_NORMAL;
3447216391eSDavid Greenman 	p->p_rtprio.prio = 0;
345f992f480SDavid Greenman 
346df8bae1dSRodney W. Grimes 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
347df8bae1dSRodney W. Grimes 
348df8bae1dSRodney W. Grimes 	/* Create credentials. */
349df8bae1dSRodney W. Grimes 	cred0.p_refcnt = 1;
350df8bae1dSRodney W. Grimes 	p->p_cred = &cred0;
351df8bae1dSRodney W. Grimes 	p->p_ucred = crget();
352df8bae1dSRodney W. Grimes 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
353df8bae1dSRodney W. Grimes 
354df8bae1dSRodney W. Grimes 	/* Create the file descriptor table. */
355df8bae1dSRodney W. Grimes 	fdp = &filedesc0;
356df8bae1dSRodney W. Grimes 	p->p_fd = &fdp->fd_fd;
357df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_refcnt = 1;
358df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_cmask = cmask;
359df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
360df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
361df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_nfiles = NDFILE;
362df8bae1dSRodney W. Grimes 
363df8bae1dSRodney W. Grimes 	/* Create the limits structures. */
364df8bae1dSRodney W. Grimes 	p->p_limit = &limit0;
365df8bae1dSRodney W. Grimes 	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
366df8bae1dSRodney W. Grimes 		limit0.pl_rlimit[i].rlim_cur =
367df8bae1dSRodney W. Grimes 		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
368df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
369df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
370df8bae1dSRodney W. Grimes 	i = ptoa(cnt.v_free_count);
371df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
372df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
373df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
374df8bae1dSRodney W. Grimes 	limit0.p_refcnt = 1;
375df8bae1dSRodney W. Grimes 
376df8bae1dSRodney W. Grimes 	/* Allocate a prototype map so we have something to fork. */
377df8bae1dSRodney W. Grimes 	p->p_vmspace = &vmspace0;
378df8bae1dSRodney W. Grimes 	vmspace0.vm_refcnt = 1;
379df8bae1dSRodney W. Grimes 	pmap_pinit(&vmspace0.vm_pmap);
38026f9a767SRodney W. Grimes 	vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
381df8bae1dSRodney W. Grimes 	    trunc_page(VM_MAX_ADDRESS), TRUE);
382df8bae1dSRodney W. Grimes 	vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
383df8bae1dSRodney W. Grimes 	p->p_addr = proc0paddr;				/* XXX */
384df8bae1dSRodney W. Grimes 
3852b14f991SJulian Elischer #define INCOMPAT_LITES2
3862b14f991SJulian Elischer #ifdef INCOMPAT_LITES2
387df8bae1dSRodney W. Grimes 	/*
3882384fde5SDavid Greenman 	 * proc0 needs to have a coherent frame base, too.
3892384fde5SDavid Greenman 	 * This probably makes the identical call for the init proc
3902384fde5SDavid Greenman 	 * that happens later unnecessary since it should inherit
3912384fde5SDavid Greenman 	 * it during the fork.
3922384fde5SDavid Greenman 	 */
3932b14f991SJulian Elischer 	cpu_set_init_frame(p, init_framep);			/* XXX! */
3942b14f991SJulian Elischer #endif	/* INCOMPAT_LITES2*/
3952384fde5SDavid Greenman 
3962384fde5SDavid Greenman 	/*
397df8bae1dSRodney W. Grimes 	 * We continue to place resource usage info and signal
398df8bae1dSRodney W. Grimes 	 * actions in the user struct so they're pageable.
399df8bae1dSRodney W. Grimes 	 */
400df8bae1dSRodney W. Grimes 	p->p_stats = &p->p_addr->u_stats;
401df8bae1dSRodney W. Grimes 	p->p_sigacts = &p->p_addr->u_sigacts;
402df8bae1dSRodney W. Grimes 
403df8bae1dSRodney W. Grimes 	/*
404df8bae1dSRodney W. Grimes 	 * Initialize per uid information structure and charge
405df8bae1dSRodney W. Grimes 	 * root for one process.
406df8bae1dSRodney W. Grimes 	 */
407df8bae1dSRodney W. Grimes 	usrinfoinit();
408df8bae1dSRodney W. Grimes 	(void)chgproccnt(0, 1);
40926f9a767SRodney W. Grimes }
4102b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
4112b14f991SJulian Elischer 
4122b14f991SJulian Elischer /* ARGSUSED*/
413154c04e5SPoul-Henning Kamp static void proc0_post __P((void *dummy));
414154c04e5SPoul-Henning Kamp static void
415d841aaa7SBruce Evans proc0_post(dummy)
416d841aaa7SBruce Evans 	void *dummy;
4172b14f991SJulian Elischer {
4182b14f991SJulian Elischer 	/*
4192b14f991SJulian Elischer 	 * Now can look at time, having had a chance to verify the time
4202b14f991SJulian Elischer 	 * from the file system.  Reset p->p_rtime as it may have been
4212b14f991SJulian Elischer 	 * munched in mi_switch() after the time got set.
4222b14f991SJulian Elischer 	 */
4232b14f991SJulian Elischer 	proc0.p_stats->p_start = runtime = mono_time = boottime = time;
4242b14f991SJulian Elischer 	proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0;
4252b14f991SJulian Elischer 
4262b14f991SJulian Elischer 	/* Initialize signal state for process 0. */
4272b14f991SJulian Elischer 	siginit(&proc0);
4282b14f991SJulian Elischer }
4292b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
4302b14f991SJulian Elischer 
4312b14f991SJulian Elischer 
4322b14f991SJulian Elischer 
433df8bae1dSRodney W. Grimes 
434df8bae1dSRodney W. Grimes /*
4352b14f991SJulian Elischer  ***************************************************************************
4362b14f991SJulian Elischer  ****
4372b14f991SJulian Elischer  **** The following SYSINIT's and glue code should be moved to the
4382b14f991SJulian Elischer  **** respective files on a per subsystem basis.
4392b14f991SJulian Elischer  ****
4402b14f991SJulian Elischer  ***************************************************************************
441df8bae1dSRodney W. Grimes  */
4422b14f991SJulian Elischer /* ARGSUSED*/
443154c04e5SPoul-Henning Kamp static void sched_setup __P((void *dummy));
444154c04e5SPoul-Henning Kamp static void
445d841aaa7SBruce Evans sched_setup(dummy)
446d841aaa7SBruce Evans 	void *dummy;
4472b14f991SJulian Elischer {
448df8bae1dSRodney W. Grimes 	/* Kick off timeout driven events by calling first time. */
449df8bae1dSRodney W. Grimes 	roundrobin(NULL);
450df8bae1dSRodney W. Grimes 	schedcpu(NULL);
4512b14f991SJulian Elischer }
4522b14f991SJulian Elischer SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL)
453df8bae1dSRodney W. Grimes 
4542b14f991SJulian Elischer /* ARGSUSED*/
455154c04e5SPoul-Henning Kamp static void xxx_vfs_mountroot __P((void *dummy));
456154c04e5SPoul-Henning Kamp static void
457d841aaa7SBruce Evans xxx_vfs_mountroot(dummy)
458d841aaa7SBruce Evans 	void *dummy;
4592b14f991SJulian Elischer {
460df8bae1dSRodney W. Grimes 	/* Mount the root file system. */
4614590fd3aSDavid Greenman 	if ((*mountroot)(mountrootvfsops))
462df8bae1dSRodney W. Grimes 		panic("cannot mount root");
4632b14f991SJulian Elischer }
4642b14f991SJulian Elischer SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL)
4652b14f991SJulian Elischer 
4662b14f991SJulian Elischer /* ARGSUSED*/
467154c04e5SPoul-Henning Kamp static void xxx_vfs_root_fdtab __P((void *dummy));
468154c04e5SPoul-Henning Kamp static void
469d841aaa7SBruce Evans xxx_vfs_root_fdtab(dummy)
470d841aaa7SBruce Evans 	void *dummy;
4712b14f991SJulian Elischer {
4722b14f991SJulian Elischer 	register struct filedesc0	*fdp = &filedesc0;
473df8bae1dSRodney W. Grimes 
474df8bae1dSRodney W. Grimes 	/* Get the vnode for '/'.  Set fdp->fd_fd.fd_cdir to reference it. */
475628641f8SDavid Greenman 	if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
476df8bae1dSRodney W. Grimes 		panic("cannot find root vnode");
477df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_cdir = rootvnode;
478df8bae1dSRodney W. Grimes 	VREF(fdp->fd_fd.fd_cdir);
479df8bae1dSRodney W. Grimes 	VOP_UNLOCK(rootvnode);
480df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_rdir = NULL;
4812b14f991SJulian Elischer }
4822b14f991SJulian Elischer SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
4832b14f991SJulian Elischer 
484df8bae1dSRodney W. Grimes 
485df8bae1dSRodney W. Grimes /*
4862b14f991SJulian Elischer  ***************************************************************************
4872b14f991SJulian Elischer  ****
4882b14f991SJulian Elischer  **** The following code probably belongs in another file, like
4892b14f991SJulian Elischer  **** kern/init_init.c.  It is here for two reasons only:
4902b14f991SJulian Elischer  ****
4912b14f991SJulian Elischer  ****	1)	This code returns to startup the system; this is
4922b14f991SJulian Elischer  ****		abnormal for a kernel thread.
4932b14f991SJulian Elischer  ****	2)	This code promiscuously uses init_frame
4942b14f991SJulian Elischer  ****
4952b14f991SJulian Elischer  ***************************************************************************
496df8bae1dSRodney W. Grimes  */
497df8bae1dSRodney W. Grimes 
498d841aaa7SBruce Evans static void kthread_init __P((void *dummy));
4992b14f991SJulian Elischer SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
5002b14f991SJulian Elischer 
5012b14f991SJulian Elischer 
5022b14f991SJulian Elischer static void start_init __P((struct proc *p, void *framep));
5032b14f991SJulian Elischer 
5042b14f991SJulian Elischer /* ARGSUSED*/
5052b14f991SJulian Elischer static void
506d841aaa7SBruce Evans kthread_init(dummy)
507d841aaa7SBruce Evans 	void *dummy;
5082b14f991SJulian Elischer {
509df8bae1dSRodney W. Grimes 
510df8bae1dSRodney W. Grimes 	/* Create process 1 (init(8)). */
5112b14f991SJulian Elischer 	start_init(curproc, init_framep);
5122b14f991SJulian Elischer 
5132b14f991SJulian Elischer 	/*
5142b14f991SJulian Elischer 	 * This is the only kernel thread allowed to return yo the
5152b14f991SJulian Elischer 	 * caller!!!
5162b14f991SJulian Elischer 	 */
517df8bae1dSRodney W. Grimes 	return;
518df8bae1dSRodney W. Grimes }
519df8bae1dSRodney W. Grimes 
520df8bae1dSRodney W. Grimes 
521df8bae1dSRodney W. Grimes /*
522df8bae1dSRodney W. Grimes  * List of paths to try when searching for "init".
523df8bae1dSRodney W. Grimes  */
524df8bae1dSRodney W. Grimes static char *initpaths[] = {
525df8bae1dSRodney W. Grimes 	"/sbin/init",
526df8bae1dSRodney W. Grimes 	"/sbin/oinit",
527df8bae1dSRodney W. Grimes 	"/sbin/init.bak",
5282257b745SPoul-Henning Kamp 	"/stand/sysinstall",
529df8bae1dSRodney W. Grimes 	NULL,
530df8bae1dSRodney W. Grimes };
531df8bae1dSRodney W. Grimes 
532df8bae1dSRodney W. Grimes /*
533df8bae1dSRodney W. Grimes  * Start the initial user process; try exec'ing each pathname in "initpaths".
534df8bae1dSRodney W. Grimes  * The program is invoked with one argument containing the boot flags.
535df8bae1dSRodney W. Grimes  */
536df8bae1dSRodney W. Grimes static void
537df8bae1dSRodney W. Grimes start_init(p, framep)
538df8bae1dSRodney W. Grimes 	struct proc *p;
539df8bae1dSRodney W. Grimes 	void *framep;
540df8bae1dSRodney W. Grimes {
541df8bae1dSRodney W. Grimes 	vm_offset_t addr;
542df8bae1dSRodney W. Grimes 	struct execve_args args;
543df8bae1dSRodney W. Grimes 	int options, i, retval[2], error;
544df8bae1dSRodney W. Grimes 	char **pathp, *path, *ucp, **uap, *arg0, *arg1;
545df8bae1dSRodney W. Grimes 
546df8bae1dSRodney W. Grimes 	initproc = p;
547df8bae1dSRodney W. Grimes 
548df8bae1dSRodney W. Grimes 	/*
549df8bae1dSRodney W. Grimes 	 * We need to set the system call frame as if we were entered through
550df8bae1dSRodney W. Grimes 	 * a syscall() so that when we call execve() below, it will be able
551df8bae1dSRodney W. Grimes 	 * to set the entry point (see setregs) when it tries to exec.  The
552df8bae1dSRodney W. Grimes 	 * startup code in "locore.s" has allocated space for the frame and
553df8bae1dSRodney W. Grimes 	 * passed a pointer to that space as main's argument.
554df8bae1dSRodney W. Grimes 	 */
555df8bae1dSRodney W. Grimes 	cpu_set_init_frame(p, framep);
556df8bae1dSRodney W. Grimes 
557df8bae1dSRodney W. Grimes 	/*
558df8bae1dSRodney W. Grimes 	 * Need just enough stack to hold the faked-up "execve()" arguments.
559df8bae1dSRodney W. Grimes 	 */
56026f9a767SRodney W. Grimes 	addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE);
56168940ac1SDavid Greenman 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE) != 0)
562df8bae1dSRodney W. Grimes 		panic("init: couldn't allocate argument space");
563df8bae1dSRodney W. Grimes 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
56426f9a767SRodney W. Grimes 	p->p_vmspace->vm_ssize = 1;
565df8bae1dSRodney W. Grimes 
566df8bae1dSRodney W. Grimes 	for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
567df8bae1dSRodney W. Grimes 		/*
568df8bae1dSRodney W. Grimes 		 * Move out the boot flag argument.
569df8bae1dSRodney W. Grimes 		 */
570df8bae1dSRodney W. Grimes 		options = 0;
571df8bae1dSRodney W. Grimes 		ucp = (char *)USRSTACK;
572df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, 0);		/* trailing zero */
573df8bae1dSRodney W. Grimes 		if (boothowto & RB_SINGLE) {
574df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 's');
575df8bae1dSRodney W. Grimes 			options = 1;
576df8bae1dSRodney W. Grimes 		}
577df8bae1dSRodney W. Grimes #ifdef notyet
578df8bae1dSRodney W. Grimes                 if (boothowto & RB_FASTBOOT) {
579df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 'f');
580df8bae1dSRodney W. Grimes 			options = 1;
581df8bae1dSRodney W. Grimes 		}
582df8bae1dSRodney W. Grimes #endif
58317755ac8SPoul-Henning Kamp 
58417755ac8SPoul-Henning Kamp #ifdef BOOTCDROM
58517755ac8SPoul-Henning Kamp 		(void)subyte(--ucp, 'C');
58617755ac8SPoul-Henning Kamp 		options = 1;
58717755ac8SPoul-Henning Kamp #endif
588df8bae1dSRodney W. Grimes 		if (options == 0)
589df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, '-');
590df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, '-');		/* leading hyphen */
591df8bae1dSRodney W. Grimes 		arg1 = ucp;
592df8bae1dSRodney W. Grimes 
593df8bae1dSRodney W. Grimes 		/*
594df8bae1dSRodney W. Grimes 		 * Move out the file name (also arg 0).
595df8bae1dSRodney W. Grimes 		 */
596df8bae1dSRodney W. Grimes 		for (i = strlen(path) + 1; i >= 0; i--)
597df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, path[i]);
598df8bae1dSRodney W. Grimes 		arg0 = ucp;
599df8bae1dSRodney W. Grimes 
600df8bae1dSRodney W. Grimes 		/*
601df8bae1dSRodney W. Grimes 		 * Move out the arg pointers.
602df8bae1dSRodney W. Grimes 		 */
603df8bae1dSRodney W. Grimes 		uap = (char **)((int)ucp & ~(NBPW-1));
604df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, 0);	/* terminator */
605df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, (int)arg1);
606df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, (int)arg0);
607df8bae1dSRodney W. Grimes 
608df8bae1dSRodney W. Grimes 		/*
609df8bae1dSRodney W. Grimes 		 * Point at the arguments.
610df8bae1dSRodney W. Grimes 		 */
611df8bae1dSRodney W. Grimes 		args.fname = arg0;
61226f9a767SRodney W. Grimes 		args.argv = uap;
61326f9a767SRodney W. Grimes 		args.envv = NULL;
614df8bae1dSRodney W. Grimes 
615df8bae1dSRodney W. Grimes 		/*
616df8bae1dSRodney W. Grimes 		 * Now try to exec the program.  If can't for any reason
617df8bae1dSRodney W. Grimes 		 * other than it doesn't exist, complain.
6182b14f991SJulian Elischer 		 *
6192b14f991SJulian Elischer 		 * Otherwise return to main() which returns to btext
6202b14f991SJulian Elischer 		 * which completes the system startup.
621df8bae1dSRodney W. Grimes 		 */
622b5e8ce9fSBruce Evans 		if ((error = execve(p, &args, &retval[0])) == 0)
623df8bae1dSRodney W. Grimes 			return;
624df8bae1dSRodney W. Grimes 		if (error != ENOENT)
625df8bae1dSRodney W. Grimes 			printf("exec %s: error %d\n", path, error);
626df8bae1dSRodney W. Grimes 	}
627df8bae1dSRodney W. Grimes 	printf("init: not found\n");
628df8bae1dSRodney W. Grimes 	panic("no init");
629df8bae1dSRodney W. Grimes }
630