xref: /freebsd/sys/kern/init_main.c (revision 946bb7a2680974d0d7f32392360268edb1433b4f)
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
42946bb7a2SPoul-Henning Kamp  * $Id: init_main.c,v 1.33 1995/12/02 17:10:29 bde 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>
69df8bae1dSRodney W. Grimes #include <sys/user.h>
70ad7507e2SSteven Wallace #include <sys/sysproto.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>
77b5e8ce9fSBruce Evans #include <vm/vm_pageout.h>
78df8bae1dSRodney W. Grimes 
799ef6c28aSBruce Evans extern struct linker_set	sysinit_set;	/* XXX */
809ef6c28aSBruce Evans 
819ef6c28aSBruce Evans extern void __main __P((void));
829ef6c28aSBruce Evans extern void main __P((void *framep));
83df8bae1dSRodney W. Grimes 
84df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */
85df8bae1dSRodney W. Grimes struct	session session0;
86df8bae1dSRodney W. Grimes struct	pgrp pgrp0;
87df8bae1dSRodney W. Grimes struct	proc proc0;
88df8bae1dSRodney W. Grimes struct	pcred cred0;
89df8bae1dSRodney W. Grimes struct	filedesc0 filedesc0;
90df8bae1dSRodney W. Grimes struct	plimit limit0;
91df8bae1dSRodney W. Grimes struct	vmspace vmspace0;
92df8bae1dSRodney W. Grimes struct	proc *curproc = &proc0;
932b14f991SJulian Elischer struct	proc *initproc;
94df8bae1dSRodney W. Grimes 
95df8bae1dSRodney W. Grimes int	cmask = CMASK;
96df8bae1dSRodney W. Grimes extern	struct user *proc0paddr;
97df8bae1dSRodney W. Grimes 
982976b7f1SDavid Greenman struct	vnode *rootvp;
99df8bae1dSRodney W. Grimes int	boothowto;
100946bb7a2SPoul-Henning Kamp 
101df8bae1dSRodney W. Grimes struct	timeval boottime;
102946bb7a2SPoul-Henning Kamp SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime,
103946bb7a2SPoul-Henning Kamp 	CTLFLAG_RW, &boottime, timeval, "");
104946bb7a2SPoul-Henning Kamp 
105df8bae1dSRodney W. Grimes struct	timeval runtime;
106df8bae1dSRodney W. Grimes 
1072b14f991SJulian Elischer /*
1082b14f991SJulian Elischer  * Promiscuous argument pass for start_init()
1092b14f991SJulian Elischer  *
1102b14f991SJulian Elischer  * This is a kludge because we use a return from main() rather than a call
1112b14f991SJulian Elischer  * to a new reoutine in locore.s to kick the kernel alive from locore.s.
1122b14f991SJulian Elischer  */
1132b14f991SJulian Elischer static void	*init_framep;
1142b14f991SJulian Elischer 
115df8bae1dSRodney W. Grimes 
11626f9a767SRodney W. Grimes #if __GNUC__ >= 2
11726f9a767SRodney W. Grimes void __main() {}
11826f9a767SRodney W. Grimes #endif
11926f9a767SRodney W. Grimes 
1202b14f991SJulian Elischer 
12126f9a767SRodney W. Grimes /*
1222b14f991SJulian Elischer  * This ensures that there is at least one entry so that the sysinit_set
1232b14f991SJulian Elischer  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
1242b14f991SJulian Elischer  * executed.
12526f9a767SRodney W. Grimes  */
1262b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
1278a129caeSDavid Greenman 
12826f9a767SRodney W. Grimes 
129df8bae1dSRodney W. Grimes /*
130df8bae1dSRodney W. Grimes  * System startup; initialize the world, create process 0, mount root
131df8bae1dSRodney W. Grimes  * filesystem, and fork to create init and pagedaemon.  Most of the
132df8bae1dSRodney W. Grimes  * hard work is done in the lower-level initialization routines including
133df8bae1dSRodney W. Grimes  * startup(), which does memory initialization and autoconfiguration.
1342b14f991SJulian Elischer  *
1352b14f991SJulian Elischer  * This allows simple addition of new kernel subsystems that require
1362b14f991SJulian Elischer  * boot time initialization.  It also allows substitution of subsystem
1372b14f991SJulian Elischer  * (for instance, a scheduler, kernel profiler, or VM system) by object
1382b14f991SJulian Elischer  * module.  Finally, it allows for optional "kernel threads", like an LFS
1392b14f991SJulian Elischer  * cleaner.
140df8bae1dSRodney W. Grimes  */
14126f9a767SRodney W. Grimes void
142df8bae1dSRodney W. Grimes main(framep)
143df8bae1dSRodney W. Grimes 	void *framep;
144df8bae1dSRodney W. Grimes {
1452b14f991SJulian Elischer 
1462b14f991SJulian Elischer 	register struct sysinit **sipp;		/* system initialization*/
1472b14f991SJulian Elischer 	register struct sysinit **xipp;		/* interior loop of sort*/
1482b14f991SJulian Elischer 	register struct sysinit *save;		/* bubble*/
1492b14f991SJulian Elischer 	int			rval[2];	/* SI_TYPE_KTHREAD support*/
1502b14f991SJulian Elischer 
1512b14f991SJulian Elischer 	/*
1522b14f991SJulian Elischer 	 * Save the locore.s frame pointer for start_init().
1532b14f991SJulian Elischer 	 */
1542b14f991SJulian Elischer 	init_framep = framep;
1552b14f991SJulian Elischer 
1562b14f991SJulian Elischer 	/*
1572b14f991SJulian Elischer 	 * Perform a bubble sort of the system initialization objects by
1582b14f991SJulian Elischer 	 * their subsystem (primary key) and order (secondary key).
1592b14f991SJulian Elischer 	 *
1602b14f991SJulian Elischer 	 * Since some things care about execution order, this is the
1612b14f991SJulian Elischer 	 * operation which ensures continued function.
1622b14f991SJulian Elischer 	 */
1632b14f991SJulian Elischer 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
1642b14f991SJulian Elischer 		for( xipp = sipp + 1; *xipp; xipp++) {
1652b14f991SJulian Elischer 			if( (*sipp)->subsystem < (*xipp)->subsystem ||
1662b14f991SJulian Elischer 			    ( (*sipp)->subsystem == (*xipp)->subsystem &&
1672b14f991SJulian Elischer 			      (*sipp)->order < (*xipp)->order))
1682b14f991SJulian Elischer 				continue;	/* skip*/
1692b14f991SJulian Elischer 			save = *sipp;
1702b14f991SJulian Elischer 			*sipp = *xipp;
1712b14f991SJulian Elischer 			*xipp = save;
1722b14f991SJulian Elischer 		}
1732b14f991SJulian Elischer 	}
1742b14f991SJulian Elischer 
1752b14f991SJulian Elischer 	/*
1762b14f991SJulian Elischer 	 * Traverse the (now) ordered list of system initialization tasks.
1772b14f991SJulian Elischer 	 * Perform each task, and continue on to the next task.
1782b14f991SJulian Elischer 	 *
1792b14f991SJulian Elischer 	 * The last item on the list is expected to be the scheduler,
1802b14f991SJulian Elischer 	 * which will not return.
1812b14f991SJulian Elischer 	 */
1822b14f991SJulian Elischer 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
1832b14f991SJulian Elischer 		if( (*sipp)->subsystem == SI_SUB_DUMMY)
1842b14f991SJulian Elischer 			continue;	/* skip dummy task(s)*/
1852b14f991SJulian Elischer 
1862b14f991SJulian Elischer 		switch( (*sipp)->type) {
1872b14f991SJulian Elischer 		case SI_TYPE_DEFAULT:
1882b14f991SJulian Elischer 			/* no special processing*/
1892b14f991SJulian Elischer 			(*((*sipp)->func))( (*sipp)->udata);
1902b14f991SJulian Elischer 			break;
1912b14f991SJulian Elischer 
1922b14f991SJulian Elischer 		case SI_TYPE_KTHREAD:
1932b14f991SJulian Elischer 			/* kernel thread*/
1942b14f991SJulian Elischer 			if (fork(&proc0, NULL, rval))
1952b14f991SJulian Elischer 				panic("fork kernel process");
1962b14f991SJulian Elischer 			if (rval[1]) {
1972b14f991SJulian Elischer 				(*((*sipp)->func))( (*sipp)->udata);
1982b14f991SJulian Elischer 				/*
1992b14f991SJulian Elischer 				 * The call to start "init" returns
2002b14f991SJulian Elischer 				 * here after the scheduler has been
2012b14f991SJulian Elischer 				 * started, and returns to the caller
2022b14f991SJulian Elischer 				 * in i386/i386/locore.s.  This is a
2032b14f991SJulian Elischer 				 * necessary part of initialization
2042b14f991SJulian Elischer 				 * and is rather non-obvious.
2052b14f991SJulian Elischer 				 *
2062b14f991SJulian Elischer 				 * No other "kernel threads" should
2072b14f991SJulian Elischer 				 * return here.  Call panic() instead.
2082b14f991SJulian Elischer 				 */
2092b14f991SJulian Elischer 				return;
2102b14f991SJulian Elischer 			}
2112b14f991SJulian Elischer 			break;
2122b14f991SJulian Elischer 
2132b14f991SJulian Elischer 		default:
2142b14f991SJulian Elischer 			panic( "init_main: unrecognized init type");
2152b14f991SJulian Elischer 		}
2162b14f991SJulian Elischer 	}
2172b14f991SJulian Elischer 
2182b14f991SJulian Elischer 	/* NOTREACHED*/
2192b14f991SJulian Elischer }
2202b14f991SJulian Elischer 
2212b14f991SJulian Elischer 
2222b14f991SJulian Elischer /*
2232b14f991SJulian Elischer  * Start a kernel process.  This is called after a fork() call in
2242b14f991SJulian Elischer  * main() in the file kern/init_main.c.
2252b14f991SJulian Elischer  *
2262b14f991SJulian Elischer  * This function is used to start "internal" daemons.
2272b14f991SJulian Elischer  */
2282b14f991SJulian Elischer /* ARGSUSED*/
2292b14f991SJulian Elischer void
2302b14f991SJulian Elischer kproc_start(udata)
231d841aaa7SBruce Evans 	void *udata;
2322b14f991SJulian Elischer {
233d841aaa7SBruce Evans 	struct kproc_desc	*kp = udata;
2342b14f991SJulian Elischer 	struct proc		*p = curproc;
2352b14f991SJulian Elischer 
2362b14f991SJulian Elischer 	/* save a global descriptor, if desired*/
2372b14f991SJulian Elischer 	if( kp->global_procpp != NULL)
2382b14f991SJulian Elischer 		*kp->global_procpp	= p;
2392b14f991SJulian Elischer 
2402b14f991SJulian Elischer 	/* this is a non-swapped system process*/
2412b14f991SJulian Elischer 	p->p_flag |= P_INMEM | P_SYSTEM;
2422b14f991SJulian Elischer 
2432b14f991SJulian Elischer 	/* set up arg0 for 'ps', et al*/
2442b14f991SJulian Elischer 	strcpy( p->p_comm, kp->arg0);
2452b14f991SJulian Elischer 
2462b14f991SJulian Elischer 	/* call the processes' main()...*/
2472b14f991SJulian Elischer 	(*kp->func)();
2482b14f991SJulian Elischer 
2492b14f991SJulian Elischer 	/* NOTREACHED */
2502b14f991SJulian Elischer 	panic("kproc_start: %s", kp->arg0);
2512b14f991SJulian Elischer }
2522b14f991SJulian Elischer 
2532b14f991SJulian Elischer 
2542b14f991SJulian Elischer /*
2552b14f991SJulian Elischer  ***************************************************************************
2562b14f991SJulian Elischer  ****
2572b14f991SJulian Elischer  **** The following SYSINIT's belong elsewhere, but have not yet
2582b14f991SJulian Elischer  **** been moved.
2592b14f991SJulian Elischer  ****
2602b14f991SJulian Elischer  ***************************************************************************
2612b14f991SJulian Elischer  */
2622b14f991SJulian Elischer #ifdef OMIT
2632b14f991SJulian Elischer /*
2642b14f991SJulian Elischer  * Handled by vfs_mountroot (bad idea) at this time... should be
2652b14f991SJulian Elischer  * done the same as 4.4Lite2.
2662b14f991SJulian Elischer  */
2672b14f991SJulian Elischer SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
2682b14f991SJulian Elischer #endif	/* OMIT*/
2692b14f991SJulian Elischer 
2702b14f991SJulian Elischer /*
2712b14f991SJulian Elischer  * Should get its own file...
2722b14f991SJulian Elischer  */
2732b14f991SJulian Elischer #ifdef HPFPLIB
2742b14f991SJulian Elischer char	copyright[] =
2752b14f991SJulian 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";
2762b14f991SJulian Elischer #else
2772b14f991SJulian Elischer char	copyright[] =
2782b14f991SJulian Elischer "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.  All rights reserved.\n\n";
2792b14f991SJulian Elischer #endif
2804590fd3aSDavid Greenman static void print_caddr_t __P((void *data));
2819ef6c28aSBruce Evans static void
2829ef6c28aSBruce Evans print_caddr_t(data)
2834590fd3aSDavid Greenman 	void *data;
2849ef6c28aSBruce Evans {
2859ef6c28aSBruce Evans 	printf("%s", (char *)data);
2869ef6c28aSBruce Evans }
287d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
2882b14f991SJulian Elischer 
2892b14f991SJulian Elischer 
2902b14f991SJulian Elischer /*
2912b14f991SJulian Elischer  ***************************************************************************
2922b14f991SJulian Elischer  ****
2932b14f991SJulian Elischer  **** The two following SYSINT's are proc0 specific glue code.  I am not
2942b14f991SJulian Elischer  **** convinced that they can not be safely combined, but their order of
2952b14f991SJulian Elischer  **** operation has been maintained as the same as the original init_main.c
2962b14f991SJulian Elischer  **** for right now.
2972b14f991SJulian Elischer  ****
2982b14f991SJulian Elischer  **** These probably belong in init_proc.c or kern_proc.c, since they
2992b14f991SJulian Elischer  **** deal with proc0 (the fork template process).
3002b14f991SJulian Elischer  ****
3012b14f991SJulian Elischer  ***************************************************************************
3022b14f991SJulian Elischer  */
3032b14f991SJulian Elischer /* ARGSUSED*/
304d841aaa7SBruce Evans void proc0_init __P((void *dummy));
3052b14f991SJulian Elischer void
306d841aaa7SBruce Evans proc0_init(dummy)
307d841aaa7SBruce Evans 	void *dummy;
3082b14f991SJulian Elischer {
309df8bae1dSRodney W. Grimes 	register struct proc		*p;
310df8bae1dSRodney W. Grimes 	register struct filedesc0	*fdp;
311df8bae1dSRodney W. Grimes 	register int i;
312df8bae1dSRodney W. Grimes 
313df8bae1dSRodney W. Grimes 	/*
314df8bae1dSRodney W. Grimes 	 * Initialize the current process pointer (curproc) before
315df8bae1dSRodney W. Grimes 	 * any possible traps/probes to simplify trap processing.
316df8bae1dSRodney W. Grimes 	 */
317df8bae1dSRodney W. Grimes 	p = &proc0;
3182b14f991SJulian Elischer 	curproc = p;			/* XXX redundant*/
319df8bae1dSRodney W. Grimes 
320df8bae1dSRodney W. Grimes 	/*
321df8bae1dSRodney W. Grimes 	 * Create process 0 (the swapper).
322df8bae1dSRodney W. Grimes 	 */
323df8bae1dSRodney W. Grimes 	allproc = (volatile struct proc *)p;
324df8bae1dSRodney W. Grimes 	p->p_prev = (struct proc **)&allproc;
325df8bae1dSRodney W. Grimes 	p->p_pgrp = &pgrp0;
326df8bae1dSRodney W. Grimes 	pgrphash[0] = &pgrp0;
327df8bae1dSRodney W. Grimes 	pgrp0.pg_mem = p;
328df8bae1dSRodney W. Grimes 	pgrp0.pg_session = &session0;
329df8bae1dSRodney W. Grimes 	session0.s_count = 1;
330df8bae1dSRodney W. Grimes 	session0.s_leader = p;
331df8bae1dSRodney W. Grimes 
332f3f0ca60SSøren Schmidt 	p->p_sysent = &aout_sysvec;
333f3f0ca60SSøren Schmidt 
334df8bae1dSRodney W. Grimes 	p->p_flag = P_INMEM | P_SYSTEM;
335df8bae1dSRodney W. Grimes 	p->p_stat = SRUN;
336df8bae1dSRodney W. Grimes 	p->p_nice = NZERO;
3377216391eSDavid Greenman 	p->p_rtprio.type = RTP_PRIO_NORMAL;
3387216391eSDavid Greenman 	p->p_rtprio.prio = 0;
339f992f480SDavid Greenman 
340df8bae1dSRodney W. Grimes 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
341df8bae1dSRodney W. Grimes 
342df8bae1dSRodney W. Grimes 	/* Create credentials. */
343df8bae1dSRodney W. Grimes 	cred0.p_refcnt = 1;
344df8bae1dSRodney W. Grimes 	p->p_cred = &cred0;
345df8bae1dSRodney W. Grimes 	p->p_ucred = crget();
346df8bae1dSRodney W. Grimes 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
347df8bae1dSRodney W. Grimes 
348df8bae1dSRodney W. Grimes 	/* Create the file descriptor table. */
349df8bae1dSRodney W. Grimes 	fdp = &filedesc0;
350df8bae1dSRodney W. Grimes 	p->p_fd = &fdp->fd_fd;
351df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_refcnt = 1;
352df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_cmask = cmask;
353df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
354df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
355df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_nfiles = NDFILE;
356df8bae1dSRodney W. Grimes 
357df8bae1dSRodney W. Grimes 	/* Create the limits structures. */
358df8bae1dSRodney W. Grimes 	p->p_limit = &limit0;
359df8bae1dSRodney W. Grimes 	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
360df8bae1dSRodney W. Grimes 		limit0.pl_rlimit[i].rlim_cur =
361df8bae1dSRodney W. Grimes 		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
362df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
363df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
364df8bae1dSRodney W. Grimes 	i = ptoa(cnt.v_free_count);
365df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
366df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
367df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
368df8bae1dSRodney W. Grimes 	limit0.p_refcnt = 1;
369df8bae1dSRodney W. Grimes 
370df8bae1dSRodney W. Grimes 	/* Allocate a prototype map so we have something to fork. */
371df8bae1dSRodney W. Grimes 	p->p_vmspace = &vmspace0;
372df8bae1dSRodney W. Grimes 	vmspace0.vm_refcnt = 1;
373df8bae1dSRodney W. Grimes 	pmap_pinit(&vmspace0.vm_pmap);
37426f9a767SRodney W. Grimes 	vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
375df8bae1dSRodney W. Grimes 	    trunc_page(VM_MAX_ADDRESS), TRUE);
376df8bae1dSRodney W. Grimes 	vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
377df8bae1dSRodney W. Grimes 	p->p_addr = proc0paddr;				/* XXX */
378df8bae1dSRodney W. Grimes 
3792b14f991SJulian Elischer #define INCOMPAT_LITES2
3802b14f991SJulian Elischer #ifdef INCOMPAT_LITES2
381df8bae1dSRodney W. Grimes 	/*
3822384fde5SDavid Greenman 	 * proc0 needs to have a coherent frame base, too.
3832384fde5SDavid Greenman 	 * This probably makes the identical call for the init proc
3842384fde5SDavid Greenman 	 * that happens later unnecessary since it should inherit
3852384fde5SDavid Greenman 	 * it during the fork.
3862384fde5SDavid Greenman 	 */
3872b14f991SJulian Elischer 	cpu_set_init_frame(p, init_framep);			/* XXX! */
3882b14f991SJulian Elischer #endif	/* INCOMPAT_LITES2*/
3892384fde5SDavid Greenman 
3902384fde5SDavid Greenman 	/*
391df8bae1dSRodney W. Grimes 	 * We continue to place resource usage info and signal
392df8bae1dSRodney W. Grimes 	 * actions in the user struct so they're pageable.
393df8bae1dSRodney W. Grimes 	 */
394df8bae1dSRodney W. Grimes 	p->p_stats = &p->p_addr->u_stats;
395df8bae1dSRodney W. Grimes 	p->p_sigacts = &p->p_addr->u_sigacts;
396df8bae1dSRodney W. Grimes 
397df8bae1dSRodney W. Grimes 	/*
398df8bae1dSRodney W. Grimes 	 * Initialize per uid information structure and charge
399df8bae1dSRodney W. Grimes 	 * root for one process.
400df8bae1dSRodney W. Grimes 	 */
401df8bae1dSRodney W. Grimes 	usrinfoinit();
402df8bae1dSRodney W. Grimes 	(void)chgproccnt(0, 1);
40326f9a767SRodney W. Grimes }
4042b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
4052b14f991SJulian Elischer 
4062b14f991SJulian Elischer /* ARGSUSED*/
407d841aaa7SBruce Evans void proc0_post __P((void *dummy));
4082b14f991SJulian Elischer void
409d841aaa7SBruce Evans proc0_post(dummy)
410d841aaa7SBruce Evans 	void *dummy;
4112b14f991SJulian Elischer {
4122b14f991SJulian Elischer 	/*
4132b14f991SJulian Elischer 	 * Now can look at time, having had a chance to verify the time
4142b14f991SJulian Elischer 	 * from the file system.  Reset p->p_rtime as it may have been
4152b14f991SJulian Elischer 	 * munched in mi_switch() after the time got set.
4162b14f991SJulian Elischer 	 */
4172b14f991SJulian Elischer 	proc0.p_stats->p_start = runtime = mono_time = boottime = time;
4182b14f991SJulian Elischer 	proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0;
4192b14f991SJulian Elischer 
4202b14f991SJulian Elischer 	/* Initialize signal state for process 0. */
4212b14f991SJulian Elischer 	siginit(&proc0);
4222b14f991SJulian Elischer }
4232b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
4242b14f991SJulian Elischer 
4252b14f991SJulian Elischer 
4262b14f991SJulian Elischer 
427df8bae1dSRodney W. Grimes 
428df8bae1dSRodney W. Grimes /*
4292b14f991SJulian Elischer  ***************************************************************************
4302b14f991SJulian Elischer  ****
4312b14f991SJulian Elischer  **** The following SYSINIT's and glue code should be moved to the
4322b14f991SJulian Elischer  **** respective files on a per subsystem basis.
4332b14f991SJulian Elischer  ****
4342b14f991SJulian Elischer  ***************************************************************************
435df8bae1dSRodney W. Grimes  */
4362b14f991SJulian Elischer /* ARGSUSED*/
437d841aaa7SBruce Evans void sched_setup __P((void *dummy));
4382b14f991SJulian Elischer void
439d841aaa7SBruce Evans sched_setup(dummy)
440d841aaa7SBruce Evans 	void *dummy;
4412b14f991SJulian Elischer {
442df8bae1dSRodney W. Grimes 	/* Kick off timeout driven events by calling first time. */
443df8bae1dSRodney W. Grimes 	roundrobin(NULL);
444df8bae1dSRodney W. Grimes 	schedcpu(NULL);
4452b14f991SJulian Elischer }
4462b14f991SJulian Elischer SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL)
447df8bae1dSRodney W. Grimes 
4482b14f991SJulian Elischer /* ARGSUSED*/
449d841aaa7SBruce Evans void xxx_vfs_mountroot __P((void *dummy));
4502b14f991SJulian Elischer void
451d841aaa7SBruce Evans xxx_vfs_mountroot(dummy)
452d841aaa7SBruce Evans 	void *dummy;
4532b14f991SJulian Elischer {
454df8bae1dSRodney W. Grimes 	/* Mount the root file system. */
4554590fd3aSDavid Greenman 	if ((*mountroot)(mountrootvfsops))
456df8bae1dSRodney W. Grimes 		panic("cannot mount root");
4572b14f991SJulian Elischer }
4582b14f991SJulian Elischer SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL)
4592b14f991SJulian Elischer 
4602b14f991SJulian Elischer /* ARGSUSED*/
461d841aaa7SBruce Evans void xxx_vfs_root_fdtab __P((void *dummy));
4622b14f991SJulian Elischer void
463d841aaa7SBruce Evans xxx_vfs_root_fdtab(dummy)
464d841aaa7SBruce Evans 	void *dummy;
4652b14f991SJulian Elischer {
4662b14f991SJulian Elischer 	register struct filedesc0	*fdp = &filedesc0;
467df8bae1dSRodney W. Grimes 
468df8bae1dSRodney W. Grimes 	/* Get the vnode for '/'.  Set fdp->fd_fd.fd_cdir to reference it. */
469628641f8SDavid Greenman 	if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
470df8bae1dSRodney W. Grimes 		panic("cannot find root vnode");
471df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_cdir = rootvnode;
472df8bae1dSRodney W. Grimes 	VREF(fdp->fd_fd.fd_cdir);
473df8bae1dSRodney W. Grimes 	VOP_UNLOCK(rootvnode);
474df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_rdir = NULL;
4752b14f991SJulian Elischer }
4762b14f991SJulian Elischer SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
4772b14f991SJulian Elischer 
478df8bae1dSRodney W. Grimes 
479df8bae1dSRodney W. Grimes /*
4802b14f991SJulian Elischer  ***************************************************************************
4812b14f991SJulian Elischer  ****
4822b14f991SJulian Elischer  **** The following code probably belongs in another file, like
4832b14f991SJulian Elischer  **** kern/init_init.c.  It is here for two reasons only:
4842b14f991SJulian Elischer  ****
4852b14f991SJulian Elischer  ****	1)	This code returns to startup the system; this is
4862b14f991SJulian Elischer  ****		abnormal for a kernel thread.
4872b14f991SJulian Elischer  ****	2)	This code promiscuously uses init_frame
4882b14f991SJulian Elischer  ****
4892b14f991SJulian Elischer  ***************************************************************************
490df8bae1dSRodney W. Grimes  */
491df8bae1dSRodney W. Grimes 
492d841aaa7SBruce Evans static void kthread_init __P((void *dummy));
4932b14f991SJulian Elischer SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
4942b14f991SJulian Elischer 
4952b14f991SJulian Elischer 
4962b14f991SJulian Elischer static void start_init __P((struct proc *p, void *framep));
4972b14f991SJulian Elischer 
4982b14f991SJulian Elischer /* ARGSUSED*/
4992b14f991SJulian Elischer static void
500d841aaa7SBruce Evans kthread_init(dummy)
501d841aaa7SBruce Evans 	void *dummy;
5022b14f991SJulian Elischer {
503df8bae1dSRodney W. Grimes 
504df8bae1dSRodney W. Grimes 	/* Create process 1 (init(8)). */
5052b14f991SJulian Elischer 	start_init(curproc, init_framep);
5062b14f991SJulian Elischer 
5072b14f991SJulian Elischer 	/*
5082b14f991SJulian Elischer 	 * This is the only kernel thread allowed to return yo the
5092b14f991SJulian Elischer 	 * caller!!!
5102b14f991SJulian Elischer 	 */
511df8bae1dSRodney W. Grimes 	return;
512df8bae1dSRodney W. Grimes }
513df8bae1dSRodney W. Grimes 
514df8bae1dSRodney W. Grimes 
515df8bae1dSRodney W. Grimes /*
516df8bae1dSRodney W. Grimes  * List of paths to try when searching for "init".
517df8bae1dSRodney W. Grimes  */
518df8bae1dSRodney W. Grimes static char *initpaths[] = {
519df8bae1dSRodney W. Grimes 	"/sbin/init",
520df8bae1dSRodney W. Grimes 	"/sbin/oinit",
521df8bae1dSRodney W. Grimes 	"/sbin/init.bak",
5222257b745SPoul-Henning Kamp 	"/stand/sysinstall",
523df8bae1dSRodney W. Grimes 	NULL,
524df8bae1dSRodney W. Grimes };
525df8bae1dSRodney W. Grimes 
526df8bae1dSRodney W. Grimes /*
527df8bae1dSRodney W. Grimes  * Start the initial user process; try exec'ing each pathname in "initpaths".
528df8bae1dSRodney W. Grimes  * The program is invoked with one argument containing the boot flags.
529df8bae1dSRodney W. Grimes  */
530df8bae1dSRodney W. Grimes static void
531df8bae1dSRodney W. Grimes start_init(p, framep)
532df8bae1dSRodney W. Grimes 	struct proc *p;
533df8bae1dSRodney W. Grimes 	void *framep;
534df8bae1dSRodney W. Grimes {
535df8bae1dSRodney W. Grimes 	vm_offset_t addr;
536df8bae1dSRodney W. Grimes 	struct execve_args args;
537df8bae1dSRodney W. Grimes 	int options, i, retval[2], error;
538df8bae1dSRodney W. Grimes 	char **pathp, *path, *ucp, **uap, *arg0, *arg1;
539df8bae1dSRodney W. Grimes 
540df8bae1dSRodney W. Grimes 	initproc = p;
541df8bae1dSRodney W. Grimes 
542df8bae1dSRodney W. Grimes 	/*
543df8bae1dSRodney W. Grimes 	 * We need to set the system call frame as if we were entered through
544df8bae1dSRodney W. Grimes 	 * a syscall() so that when we call execve() below, it will be able
545df8bae1dSRodney W. Grimes 	 * to set the entry point (see setregs) when it tries to exec.  The
546df8bae1dSRodney W. Grimes 	 * startup code in "locore.s" has allocated space for the frame and
547df8bae1dSRodney W. Grimes 	 * passed a pointer to that space as main's argument.
548df8bae1dSRodney W. Grimes 	 */
549df8bae1dSRodney W. Grimes 	cpu_set_init_frame(p, framep);
550df8bae1dSRodney W. Grimes 
551df8bae1dSRodney W. Grimes 	/*
552df8bae1dSRodney W. Grimes 	 * Need just enough stack to hold the faked-up "execve()" arguments.
553df8bae1dSRodney W. Grimes 	 */
55426f9a767SRodney W. Grimes 	addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE);
55568940ac1SDavid Greenman 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE) != 0)
556df8bae1dSRodney W. Grimes 		panic("init: couldn't allocate argument space");
557df8bae1dSRodney W. Grimes 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
55826f9a767SRodney W. Grimes 	p->p_vmspace->vm_ssize = 1;
559df8bae1dSRodney W. Grimes 
560df8bae1dSRodney W. Grimes 	for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
561df8bae1dSRodney W. Grimes 		/*
562df8bae1dSRodney W. Grimes 		 * Move out the boot flag argument.
563df8bae1dSRodney W. Grimes 		 */
564df8bae1dSRodney W. Grimes 		options = 0;
565df8bae1dSRodney W. Grimes 		ucp = (char *)USRSTACK;
566df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, 0);		/* trailing zero */
567df8bae1dSRodney W. Grimes 		if (boothowto & RB_SINGLE) {
568df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 's');
569df8bae1dSRodney W. Grimes 			options = 1;
570df8bae1dSRodney W. Grimes 		}
571df8bae1dSRodney W. Grimes #ifdef notyet
572df8bae1dSRodney W. Grimes                 if (boothowto & RB_FASTBOOT) {
573df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 'f');
574df8bae1dSRodney W. Grimes 			options = 1;
575df8bae1dSRodney W. Grimes 		}
576df8bae1dSRodney W. Grimes #endif
57717755ac8SPoul-Henning Kamp 
57817755ac8SPoul-Henning Kamp #ifdef BOOTCDROM
57917755ac8SPoul-Henning Kamp 		(void)subyte(--ucp, 'C');
58017755ac8SPoul-Henning Kamp 		options = 1;
58117755ac8SPoul-Henning Kamp #endif
582df8bae1dSRodney W. Grimes 		if (options == 0)
583df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, '-');
584df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, '-');		/* leading hyphen */
585df8bae1dSRodney W. Grimes 		arg1 = ucp;
586df8bae1dSRodney W. Grimes 
587df8bae1dSRodney W. Grimes 		/*
588df8bae1dSRodney W. Grimes 		 * Move out the file name (also arg 0).
589df8bae1dSRodney W. Grimes 		 */
590df8bae1dSRodney W. Grimes 		for (i = strlen(path) + 1; i >= 0; i--)
591df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, path[i]);
592df8bae1dSRodney W. Grimes 		arg0 = ucp;
593df8bae1dSRodney W. Grimes 
594df8bae1dSRodney W. Grimes 		/*
595df8bae1dSRodney W. Grimes 		 * Move out the arg pointers.
596df8bae1dSRodney W. Grimes 		 */
597df8bae1dSRodney W. Grimes 		uap = (char **)((int)ucp & ~(NBPW-1));
598df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, 0);	/* terminator */
599df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, (int)arg1);
600df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, (int)arg0);
601df8bae1dSRodney W. Grimes 
602df8bae1dSRodney W. Grimes 		/*
603df8bae1dSRodney W. Grimes 		 * Point at the arguments.
604df8bae1dSRodney W. Grimes 		 */
605df8bae1dSRodney W. Grimes 		args.fname = arg0;
60626f9a767SRodney W. Grimes 		args.argv = uap;
60726f9a767SRodney W. Grimes 		args.envv = NULL;
608df8bae1dSRodney W. Grimes 
609df8bae1dSRodney W. Grimes 		/*
610df8bae1dSRodney W. Grimes 		 * Now try to exec the program.  If can't for any reason
611df8bae1dSRodney W. Grimes 		 * other than it doesn't exist, complain.
6122b14f991SJulian Elischer 		 *
6132b14f991SJulian Elischer 		 * Otherwise return to main() which returns to btext
6142b14f991SJulian Elischer 		 * which completes the system startup.
615df8bae1dSRodney W. Grimes 		 */
616b5e8ce9fSBruce Evans 		if ((error = execve(p, &args, &retval[0])) == 0)
617df8bae1dSRodney W. Grimes 			return;
618df8bae1dSRodney W. Grimes 		if (error != ENOENT)
619df8bae1dSRodney W. Grimes 			printf("exec %s: error %d\n", path, error);
620df8bae1dSRodney W. Grimes 	}
621df8bae1dSRodney W. Grimes 	printf("init: not found\n");
622df8bae1dSRodney W. Grimes 	panic("no init");
623df8bae1dSRodney W. Grimes }
624