xref: /freebsd/sys/kern/init_main.c (revision b1508c72f4072875299362ea95cf571d9bf019ef)
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
42b1508c72SDavid Greenman  * $Id: init_main.c,v 1.43 1996/06/14 11:01:25 asami Exp $
43df8bae1dSRodney W. Grimes  */
44df8bae1dSRodney W. Grimes 
454bd49128SPeter Wemm #include "opt_rlimit.h"
464bd49128SPeter Wemm 
47df8bae1dSRodney W. Grimes #include <sys/param.h>
48df8bae1dSRodney W. Grimes #include <sys/filedesc.h>
49df8bae1dSRodney W. Grimes #include <sys/errno.h>
50df8bae1dSRodney W. Grimes #include <sys/exec.h>
51df8bae1dSRodney W. Grimes #include <sys/kernel.h>
52946bb7a2SPoul-Henning Kamp #include <sys/sysctl.h>
53b5e8ce9fSBruce Evans #ifdef GPROF
54b5e8ce9fSBruce Evans #include <sys/gmon.h>
55b5e8ce9fSBruce Evans #endif
56df8bae1dSRodney W. Grimes #include <sys/mount.h>
57df8bae1dSRodney W. Grimes #include <sys/proc.h>
58df8bae1dSRodney W. Grimes #include <sys/resourcevar.h>
59df8bae1dSRodney W. Grimes #include <sys/signalvar.h>
60df8bae1dSRodney W. Grimes #include <sys/systm.h>
61df8bae1dSRodney W. Grimes #include <sys/vnode.h>
62f3f0ca60SSøren Schmidt #include <sys/sysent.h>
63df8bae1dSRodney W. Grimes #include <sys/conf.h>
64df8bae1dSRodney W. Grimes #include <sys/buf.h>
65df8bae1dSRodney W. Grimes #include <sys/clist.h>
663aa12267SBruce Evans #include <sys/msg.h>
67df8bae1dSRodney W. Grimes #include <sys/protosw.h>
68df8bae1dSRodney W. Grimes #include <sys/reboot.h>
693aa12267SBruce Evans #include <sys/sem.h>
703aa12267SBruce Evans #include <sys/shm.h>
71ad7507e2SSteven Wallace #include <sys/sysproto.h>
72efeaf95aSDavid Greenman #include <sys/vmmeter.h>
73df8bae1dSRodney W. Grimes 
74df8bae1dSRodney W. Grimes #include <ufs/ufs/quota.h>
75df8bae1dSRodney W. Grimes 
76df8bae1dSRodney W. Grimes #include <machine/cpu.h>
77df8bae1dSRodney W. Grimes 
78df8bae1dSRodney W. Grimes #include <vm/vm.h>
79efeaf95aSDavid Greenman #include <vm/vm_param.h>
80efeaf95aSDavid Greenman #include <vm/vm_prot.h>
81efeaf95aSDavid Greenman #include <vm/lock.h>
82efeaf95aSDavid Greenman #include <vm/pmap.h>
83efeaf95aSDavid Greenman #include <vm/vm_map.h>
84efeaf95aSDavid Greenman #include <vm/vm_extern.h>
85efeaf95aSDavid Greenman #include <sys/user.h>
86df8bae1dSRodney W. Grimes 
879ef6c28aSBruce Evans extern struct linker_set	sysinit_set;	/* XXX */
889ef6c28aSBruce Evans 
899ef6c28aSBruce Evans extern void __main __P((void));
909ef6c28aSBruce Evans extern void main __P((void *framep));
91df8bae1dSRodney W. Grimes 
92df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */
93154c04e5SPoul-Henning Kamp static struct session session0;
94154c04e5SPoul-Henning Kamp static struct pgrp pgrp0;
95df8bae1dSRodney W. Grimes struct	proc proc0;
96154c04e5SPoul-Henning Kamp static struct pcred cred0;
97154c04e5SPoul-Henning Kamp static struct filedesc0 filedesc0;
98154c04e5SPoul-Henning Kamp static struct plimit limit0;
99154c04e5SPoul-Henning Kamp static struct vmspace vmspace0;
100df8bae1dSRodney W. Grimes struct	proc *curproc = &proc0;
1012b14f991SJulian Elischer struct	proc *initproc;
102df8bae1dSRodney W. Grimes 
103dedb7b62SPeter Wemm int cmask = CMASK;
104df8bae1dSRodney W. Grimes extern	struct user *proc0paddr;
105df8bae1dSRodney W. Grimes 
1062976b7f1SDavid Greenman struct	vnode *rootvp;
107df8bae1dSRodney W. Grimes int	boothowto;
108946bb7a2SPoul-Henning Kamp 
109df8bae1dSRodney W. Grimes struct	timeval boottime;
110946bb7a2SPoul-Henning Kamp SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime,
111946bb7a2SPoul-Henning Kamp 	CTLFLAG_RW, &boottime, timeval, "");
112946bb7a2SPoul-Henning Kamp 
113df8bae1dSRodney W. Grimes struct	timeval runtime;
114df8bae1dSRodney W. Grimes 
1152b14f991SJulian Elischer /*
1162b14f991SJulian Elischer  * Promiscuous argument pass for start_init()
1172b14f991SJulian Elischer  *
1182b14f991SJulian Elischer  * This is a kludge because we use a return from main() rather than a call
1192b14f991SJulian Elischer  * to a new reoutine in locore.s to kick the kernel alive from locore.s.
1202b14f991SJulian Elischer  */
1212b14f991SJulian Elischer static void	*init_framep;
1222b14f991SJulian Elischer 
123df8bae1dSRodney W. Grimes 
12426f9a767SRodney W. Grimes #if __GNUC__ >= 2
12526f9a767SRodney W. Grimes void __main() {}
12626f9a767SRodney W. Grimes #endif
12726f9a767SRodney W. Grimes 
1282b14f991SJulian Elischer 
12926f9a767SRodney W. Grimes /*
1302b14f991SJulian Elischer  * This ensures that there is at least one entry so that the sysinit_set
1312b14f991SJulian Elischer  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
1322b14f991SJulian Elischer  * executed.
13326f9a767SRodney W. Grimes  */
1342b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
1358a129caeSDavid Greenman 
13626f9a767SRodney W. Grimes 
137df8bae1dSRodney W. Grimes /*
138df8bae1dSRodney W. Grimes  * System startup; initialize the world, create process 0, mount root
139df8bae1dSRodney W. Grimes  * filesystem, and fork to create init and pagedaemon.  Most of the
140df8bae1dSRodney W. Grimes  * hard work is done in the lower-level initialization routines including
141df8bae1dSRodney W. Grimes  * startup(), which does memory initialization and autoconfiguration.
1422b14f991SJulian Elischer  *
1432b14f991SJulian Elischer  * This allows simple addition of new kernel subsystems that require
1442b14f991SJulian Elischer  * boot time initialization.  It also allows substitution of subsystem
1452b14f991SJulian Elischer  * (for instance, a scheduler, kernel profiler, or VM system) by object
1462b14f991SJulian Elischer  * module.  Finally, it allows for optional "kernel threads", like an LFS
1472b14f991SJulian Elischer  * cleaner.
148df8bae1dSRodney W. Grimes  */
14926f9a767SRodney W. Grimes void
150df8bae1dSRodney W. Grimes main(framep)
151df8bae1dSRodney W. Grimes 	void *framep;
152df8bae1dSRodney W. Grimes {
1532b14f991SJulian Elischer 
1542b14f991SJulian Elischer 	register struct sysinit **sipp;		/* system initialization*/
1552b14f991SJulian Elischer 	register struct sysinit **xipp;		/* interior loop of sort*/
1562b14f991SJulian Elischer 	register struct sysinit *save;		/* bubble*/
1572b14f991SJulian Elischer 	int			rval[2];	/* SI_TYPE_KTHREAD support*/
1582b14f991SJulian Elischer 
1592b14f991SJulian Elischer 	/*
1602b14f991SJulian Elischer 	 * Save the locore.s frame pointer for start_init().
1612b14f991SJulian Elischer 	 */
1622b14f991SJulian Elischer 	init_framep = framep;
1632b14f991SJulian Elischer 
1642b14f991SJulian Elischer 	/*
1652b14f991SJulian Elischer 	 * Perform a bubble sort of the system initialization objects by
1662b14f991SJulian Elischer 	 * their subsystem (primary key) and order (secondary key).
1672b14f991SJulian Elischer 	 *
1682b14f991SJulian Elischer 	 * Since some things care about execution order, this is the
1692b14f991SJulian Elischer 	 * operation which ensures continued function.
1702b14f991SJulian Elischer 	 */
1712b14f991SJulian Elischer 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
1722b14f991SJulian Elischer 		for( xipp = sipp + 1; *xipp; xipp++) {
1732b14f991SJulian Elischer 			if( (*sipp)->subsystem < (*xipp)->subsystem ||
1742b14f991SJulian Elischer 			    ( (*sipp)->subsystem == (*xipp)->subsystem &&
1752b14f991SJulian Elischer 			      (*sipp)->order < (*xipp)->order))
1762b14f991SJulian Elischer 				continue;	/* skip*/
1772b14f991SJulian Elischer 			save = *sipp;
1782b14f991SJulian Elischer 			*sipp = *xipp;
1792b14f991SJulian Elischer 			*xipp = save;
1802b14f991SJulian Elischer 		}
1812b14f991SJulian Elischer 	}
1822b14f991SJulian Elischer 
1832b14f991SJulian Elischer 	/*
1842b14f991SJulian Elischer 	 * Traverse the (now) ordered list of system initialization tasks.
1852b14f991SJulian Elischer 	 * Perform each task, and continue on to the next task.
1862b14f991SJulian Elischer 	 *
1872b14f991SJulian Elischer 	 * The last item on the list is expected to be the scheduler,
1882b14f991SJulian Elischer 	 * which will not return.
1892b14f991SJulian Elischer 	 */
1902b14f991SJulian Elischer 	for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
1912b14f991SJulian Elischer 		if( (*sipp)->subsystem == SI_SUB_DUMMY)
1922b14f991SJulian Elischer 			continue;	/* skip dummy task(s)*/
1932b14f991SJulian Elischer 
1942b14f991SJulian Elischer 		switch( (*sipp)->type) {
1952b14f991SJulian Elischer 		case SI_TYPE_DEFAULT:
1962b14f991SJulian Elischer 			/* no special processing*/
1972b14f991SJulian Elischer 			(*((*sipp)->func))( (*sipp)->udata);
1982b14f991SJulian Elischer 			break;
1992b14f991SJulian Elischer 
2002b14f991SJulian Elischer 		case SI_TYPE_KTHREAD:
2012b14f991SJulian Elischer 			/* kernel thread*/
2022b14f991SJulian Elischer 			if (fork(&proc0, NULL, rval))
2032b14f991SJulian Elischer 				panic("fork kernel process");
2042b14f991SJulian Elischer 			if (rval[1]) {
2052b14f991SJulian Elischer 				(*((*sipp)->func))( (*sipp)->udata);
2062b14f991SJulian Elischer 				/*
2072b14f991SJulian Elischer 				 * The call to start "init" returns
2082b14f991SJulian Elischer 				 * here after the scheduler has been
2092b14f991SJulian Elischer 				 * started, and returns to the caller
2102b14f991SJulian Elischer 				 * in i386/i386/locore.s.  This is a
2112b14f991SJulian Elischer 				 * necessary part of initialization
2122b14f991SJulian Elischer 				 * and is rather non-obvious.
2132b14f991SJulian Elischer 				 *
2142b14f991SJulian Elischer 				 * No other "kernel threads" should
2152b14f991SJulian Elischer 				 * return here.  Call panic() instead.
2162b14f991SJulian Elischer 				 */
2172b14f991SJulian Elischer 				return;
2182b14f991SJulian Elischer 			}
2192b14f991SJulian Elischer 			break;
2202b14f991SJulian Elischer 
2212b14f991SJulian Elischer 		default:
2222b14f991SJulian Elischer 			panic( "init_main: unrecognized init type");
2232b14f991SJulian Elischer 		}
2242b14f991SJulian Elischer 	}
2252b14f991SJulian Elischer 
2262b14f991SJulian Elischer 	/* NOTREACHED*/
2272b14f991SJulian Elischer }
2282b14f991SJulian Elischer 
2292b14f991SJulian Elischer 
2302b14f991SJulian Elischer /*
2312b14f991SJulian Elischer  * Start a kernel process.  This is called after a fork() call in
2322b14f991SJulian Elischer  * main() in the file kern/init_main.c.
2332b14f991SJulian Elischer  *
2342b14f991SJulian Elischer  * This function is used to start "internal" daemons.
2352b14f991SJulian Elischer  */
2362b14f991SJulian Elischer /* ARGSUSED*/
2372b14f991SJulian Elischer void
2382b14f991SJulian Elischer kproc_start(udata)
239d841aaa7SBruce Evans 	void *udata;
2402b14f991SJulian Elischer {
241d841aaa7SBruce Evans 	struct kproc_desc	*kp = udata;
2422b14f991SJulian Elischer 	struct proc		*p = curproc;
2432b14f991SJulian Elischer 
2442b14f991SJulian Elischer 	/* save a global descriptor, if desired*/
2452b14f991SJulian Elischer 	if( kp->global_procpp != NULL)
2462b14f991SJulian Elischer 		*kp->global_procpp	= p;
2472b14f991SJulian Elischer 
2482b14f991SJulian Elischer 	/* this is a non-swapped system process*/
2492b14f991SJulian Elischer 	p->p_flag |= P_INMEM | P_SYSTEM;
2502b14f991SJulian Elischer 
2512b14f991SJulian Elischer 	/* set up arg0 for 'ps', et al*/
2522b14f991SJulian Elischer 	strcpy( p->p_comm, kp->arg0);
2532b14f991SJulian Elischer 
2542b14f991SJulian Elischer 	/* call the processes' main()...*/
2552b14f991SJulian Elischer 	(*kp->func)();
2562b14f991SJulian Elischer 
2572b14f991SJulian Elischer 	/* NOTREACHED */
2582b14f991SJulian Elischer 	panic("kproc_start: %s", kp->arg0);
2592b14f991SJulian Elischer }
2602b14f991SJulian Elischer 
2612b14f991SJulian Elischer 
2622b14f991SJulian Elischer /*
2632b14f991SJulian Elischer  ***************************************************************************
2642b14f991SJulian Elischer  ****
2652b14f991SJulian Elischer  **** The following SYSINIT's belong elsewhere, but have not yet
2662b14f991SJulian Elischer  **** been moved.
2672b14f991SJulian Elischer  ****
2682b14f991SJulian Elischer  ***************************************************************************
2692b14f991SJulian Elischer  */
2702b14f991SJulian Elischer #ifdef OMIT
2712b14f991SJulian Elischer /*
2722b14f991SJulian Elischer  * Handled by vfs_mountroot (bad idea) at this time... should be
2732b14f991SJulian Elischer  * done the same as 4.4Lite2.
2742b14f991SJulian Elischer  */
2752b14f991SJulian Elischer SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
2762b14f991SJulian Elischer #endif	/* OMIT*/
2772b14f991SJulian Elischer 
2782b14f991SJulian Elischer /*
2792b14f991SJulian Elischer  * Should get its own file...
2802b14f991SJulian Elischer  */
2812b14f991SJulian Elischer #ifdef HPFPLIB
2822b14f991SJulian Elischer char	copyright[] =
2832b14f991SJulian 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";
2842b14f991SJulian Elischer #else
2852b14f991SJulian Elischer char	copyright[] =
286ad63a118SSatoshi Asami #ifdef PC98
287ad63a118SSatoshi Asami "Copyright (c) 1994-1996  FreeBSD(98) porting team.\n"
288ad63a118SSatoshi Asami "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\n"
289ad63a118SSatoshi Asami "Copyright (c) 1992  A.Kojima F.Ukai M.Ishii (KMC).\n"
290ad63a118SSatoshi Asami "\tAll rights reserved.\n\n";
291ad63a118SSatoshi Asami #else
2922b14f991SJulian Elischer "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.  All rights reserved.\n\n";
2932b14f991SJulian Elischer #endif
294ad63a118SSatoshi Asami #endif
2954590fd3aSDavid Greenman static void print_caddr_t __P((void *data));
2969ef6c28aSBruce Evans static void
2979ef6c28aSBruce Evans print_caddr_t(data)
2984590fd3aSDavid Greenman 	void *data;
2999ef6c28aSBruce Evans {
3009ef6c28aSBruce Evans 	printf("%s", (char *)data);
3019ef6c28aSBruce Evans }
302d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
3032b14f991SJulian Elischer 
3042b14f991SJulian Elischer 
3052b14f991SJulian Elischer /*
3062b14f991SJulian Elischer  ***************************************************************************
3072b14f991SJulian Elischer  ****
3082b14f991SJulian Elischer  **** The two following SYSINT's are proc0 specific glue code.  I am not
3092b14f991SJulian Elischer  **** convinced that they can not be safely combined, but their order of
3102b14f991SJulian Elischer  **** operation has been maintained as the same as the original init_main.c
3112b14f991SJulian Elischer  **** for right now.
3122b14f991SJulian Elischer  ****
3132b14f991SJulian Elischer  **** These probably belong in init_proc.c or kern_proc.c, since they
3142b14f991SJulian Elischer  **** deal with proc0 (the fork template process).
3152b14f991SJulian Elischer  ****
3162b14f991SJulian Elischer  ***************************************************************************
3172b14f991SJulian Elischer  */
3182b14f991SJulian Elischer /* ARGSUSED*/
319154c04e5SPoul-Henning Kamp static void proc0_init __P((void *dummy));
320154c04e5SPoul-Henning Kamp static void
321d841aaa7SBruce Evans proc0_init(dummy)
322d841aaa7SBruce Evans 	void *dummy;
3232b14f991SJulian Elischer {
324df8bae1dSRodney W. Grimes 	register struct proc		*p;
325df8bae1dSRodney W. Grimes 	register struct filedesc0	*fdp;
326df8bae1dSRodney W. Grimes 	register int i;
327df8bae1dSRodney W. Grimes 
328df8bae1dSRodney W. Grimes 	/*
329df8bae1dSRodney W. Grimes 	 * Initialize the current process pointer (curproc) before
330df8bae1dSRodney W. Grimes 	 * any possible traps/probes to simplify trap processing.
331df8bae1dSRodney W. Grimes 	 */
332df8bae1dSRodney W. Grimes 	p = &proc0;
3332b14f991SJulian Elischer 	curproc = p;			/* XXX redundant*/
334df8bae1dSRodney W. Grimes 
335df8bae1dSRodney W. Grimes 	/*
336a3bfb996SJeffrey Hsu 	 * Initialize process and pgrp structures.
337a3bfb996SJeffrey Hsu 	 */
338a3bfb996SJeffrey Hsu 	procinit();
339a3bfb996SJeffrey Hsu 
340a3bfb996SJeffrey Hsu 	/*
341b1508c72SDavid Greenman 	 * Initialize sleep queue hash table
342b1508c72SDavid Greenman 	 */
343b1508c72SDavid Greenman 	sleepinit();
344b1508c72SDavid Greenman 
345b1508c72SDavid Greenman 	/*
346df8bae1dSRodney W. Grimes 	 * Create process 0 (the swapper).
347df8bae1dSRodney W. Grimes 	 */
348a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&allproc, p, p_list);
349df8bae1dSRodney W. Grimes 	p->p_pgrp = &pgrp0;
350a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
351a3bfb996SJeffrey Hsu 	LIST_INIT(&pgrp0.pg_members);
352a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
353a3bfb996SJeffrey Hsu 
354df8bae1dSRodney W. Grimes 	pgrp0.pg_session = &session0;
355df8bae1dSRodney W. Grimes 	session0.s_count = 1;
356df8bae1dSRodney W. Grimes 	session0.s_leader = p;
357df8bae1dSRodney W. Grimes 
358f3f0ca60SSøren Schmidt 	p->p_sysent = &aout_sysvec;
359f3f0ca60SSøren Schmidt 
360df8bae1dSRodney W. Grimes 	p->p_flag = P_INMEM | P_SYSTEM;
361df8bae1dSRodney W. Grimes 	p->p_stat = SRUN;
362df8bae1dSRodney W. Grimes 	p->p_nice = NZERO;
3637216391eSDavid Greenman 	p->p_rtprio.type = RTP_PRIO_NORMAL;
3647216391eSDavid Greenman 	p->p_rtprio.prio = 0;
365f992f480SDavid Greenman 
366df8bae1dSRodney W. Grimes 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
367df8bae1dSRodney W. Grimes 
368df8bae1dSRodney W. Grimes 	/* Create credentials. */
369df8bae1dSRodney W. Grimes 	cred0.p_refcnt = 1;
370df8bae1dSRodney W. Grimes 	p->p_cred = &cred0;
371df8bae1dSRodney W. Grimes 	p->p_ucred = crget();
372df8bae1dSRodney W. Grimes 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
373df8bae1dSRodney W. Grimes 
374df8bae1dSRodney W. Grimes 	/* Create the file descriptor table. */
375df8bae1dSRodney W. Grimes 	fdp = &filedesc0;
376df8bae1dSRodney W. Grimes 	p->p_fd = &fdp->fd_fd;
377df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_refcnt = 1;
378df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_cmask = cmask;
379df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
380df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
381df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_nfiles = NDFILE;
382df8bae1dSRodney W. Grimes 
383df8bae1dSRodney W. Grimes 	/* Create the limits structures. */
384df8bae1dSRodney W. Grimes 	p->p_limit = &limit0;
385df8bae1dSRodney W. Grimes 	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
386df8bae1dSRodney W. Grimes 		limit0.pl_rlimit[i].rlim_cur =
387df8bae1dSRodney W. Grimes 		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
388df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
389df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
390df8bae1dSRodney W. Grimes 	i = ptoa(cnt.v_free_count);
391df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
392df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
393df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
394df8bae1dSRodney W. Grimes 	limit0.p_refcnt = 1;
395df8bae1dSRodney W. Grimes 
396df8bae1dSRodney W. Grimes 	/* Allocate a prototype map so we have something to fork. */
397df8bae1dSRodney W. Grimes 	p->p_vmspace = &vmspace0;
398df8bae1dSRodney W. Grimes 	vmspace0.vm_refcnt = 1;
399df8bae1dSRodney W. Grimes 	pmap_pinit(&vmspace0.vm_pmap);
40026f9a767SRodney W. Grimes 	vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
40147dcd2e5SJohn Dyson 	    trunc_page(VM_MAXUSER_ADDRESS), TRUE);
402df8bae1dSRodney W. Grimes 	vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
403df8bae1dSRodney W. Grimes 	p->p_addr = proc0paddr;				/* XXX */
404df8bae1dSRodney W. Grimes 
4052b14f991SJulian Elischer #define INCOMPAT_LITES2
4062b14f991SJulian Elischer #ifdef INCOMPAT_LITES2
407df8bae1dSRodney W. Grimes 	/*
4082384fde5SDavid Greenman 	 * proc0 needs to have a coherent frame base, too.
4092384fde5SDavid Greenman 	 * This probably makes the identical call for the init proc
4102384fde5SDavid Greenman 	 * that happens later unnecessary since it should inherit
4112384fde5SDavid Greenman 	 * it during the fork.
4122384fde5SDavid Greenman 	 */
4132b14f991SJulian Elischer 	cpu_set_init_frame(p, init_framep);			/* XXX! */
4142b14f991SJulian Elischer #endif	/* INCOMPAT_LITES2*/
4152384fde5SDavid Greenman 
4162384fde5SDavid Greenman 	/*
417df8bae1dSRodney W. Grimes 	 * We continue to place resource usage info and signal
418df8bae1dSRodney W. Grimes 	 * actions in the user struct so they're pageable.
419df8bae1dSRodney W. Grimes 	 */
420df8bae1dSRodney W. Grimes 	p->p_stats = &p->p_addr->u_stats;
421df8bae1dSRodney W. Grimes 	p->p_sigacts = &p->p_addr->u_sigacts;
422df8bae1dSRodney W. Grimes 
423df8bae1dSRodney W. Grimes 	/*
424a3bfb996SJeffrey Hsu 	 * Charge root for one process.
425df8bae1dSRodney W. Grimes 	 */
426df8bae1dSRodney W. Grimes 	(void)chgproccnt(0, 1);
42726f9a767SRodney W. Grimes }
4282b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
4292b14f991SJulian Elischer 
4302b14f991SJulian Elischer /* ARGSUSED*/
431154c04e5SPoul-Henning Kamp static void proc0_post __P((void *dummy));
432154c04e5SPoul-Henning Kamp static void
433d841aaa7SBruce Evans proc0_post(dummy)
434d841aaa7SBruce Evans 	void *dummy;
4352b14f991SJulian Elischer {
4362b14f991SJulian Elischer 	/*
4372b14f991SJulian Elischer 	 * Now can look at time, having had a chance to verify the time
4382b14f991SJulian Elischer 	 * from the file system.  Reset p->p_rtime as it may have been
4392b14f991SJulian Elischer 	 * munched in mi_switch() after the time got set.
4402b14f991SJulian Elischer 	 */
4412b14f991SJulian Elischer 	proc0.p_stats->p_start = runtime = mono_time = boottime = time;
4422b14f991SJulian Elischer 	proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0;
4432b14f991SJulian Elischer 
4442b14f991SJulian Elischer 	/* Initialize signal state for process 0. */
4452b14f991SJulian Elischer 	siginit(&proc0);
4462b14f991SJulian Elischer }
4472b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
4482b14f991SJulian Elischer 
4492b14f991SJulian Elischer 
4502b14f991SJulian Elischer 
451df8bae1dSRodney W. Grimes 
452df8bae1dSRodney W. Grimes /*
4532b14f991SJulian Elischer  ***************************************************************************
4542b14f991SJulian Elischer  ****
4552b14f991SJulian Elischer  **** The following SYSINIT's and glue code should be moved to the
4562b14f991SJulian Elischer  **** respective files on a per subsystem basis.
4572b14f991SJulian Elischer  ****
4582b14f991SJulian Elischer  ***************************************************************************
459df8bae1dSRodney W. Grimes  */
4602b14f991SJulian Elischer /* ARGSUSED*/
461154c04e5SPoul-Henning Kamp static void sched_setup __P((void *dummy));
462154c04e5SPoul-Henning Kamp static void
463d841aaa7SBruce Evans sched_setup(dummy)
464d841aaa7SBruce Evans 	void *dummy;
4652b14f991SJulian Elischer {
466df8bae1dSRodney W. Grimes 	/* Kick off timeout driven events by calling first time. */
467df8bae1dSRodney W. Grimes 	roundrobin(NULL);
468df8bae1dSRodney W. Grimes 	schedcpu(NULL);
4692b14f991SJulian Elischer }
4702b14f991SJulian Elischer SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL)
471df8bae1dSRodney W. Grimes 
4722b14f991SJulian Elischer /* ARGSUSED*/
473154c04e5SPoul-Henning Kamp static void xxx_vfs_mountroot __P((void *dummy));
474154c04e5SPoul-Henning Kamp static void
475d841aaa7SBruce Evans xxx_vfs_mountroot(dummy)
476d841aaa7SBruce Evans 	void *dummy;
4772b14f991SJulian Elischer {
478df8bae1dSRodney W. Grimes 	/* Mount the root file system. */
4794590fd3aSDavid Greenman 	if ((*mountroot)(mountrootvfsops))
480df8bae1dSRodney W. Grimes 		panic("cannot mount root");
4812b14f991SJulian Elischer }
4822b14f991SJulian Elischer SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL)
4832b14f991SJulian Elischer 
4842b14f991SJulian Elischer /* ARGSUSED*/
485154c04e5SPoul-Henning Kamp static void xxx_vfs_root_fdtab __P((void *dummy));
486154c04e5SPoul-Henning Kamp static void
487d841aaa7SBruce Evans xxx_vfs_root_fdtab(dummy)
488d841aaa7SBruce Evans 	void *dummy;
4892b14f991SJulian Elischer {
4902b14f991SJulian Elischer 	register struct filedesc0	*fdp = &filedesc0;
491df8bae1dSRodney W. Grimes 
492df8bae1dSRodney W. Grimes 	/* Get the vnode for '/'.  Set fdp->fd_fd.fd_cdir to reference it. */
493628641f8SDavid Greenman 	if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
494df8bae1dSRodney W. Grimes 		panic("cannot find root vnode");
495df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_cdir = rootvnode;
496df8bae1dSRodney W. Grimes 	VREF(fdp->fd_fd.fd_cdir);
497df8bae1dSRodney W. Grimes 	VOP_UNLOCK(rootvnode);
498df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_rdir = NULL;
4992b14f991SJulian Elischer }
5002b14f991SJulian Elischer SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
5012b14f991SJulian Elischer 
502df8bae1dSRodney W. Grimes 
503df8bae1dSRodney W. Grimes /*
5042b14f991SJulian Elischer  ***************************************************************************
5052b14f991SJulian Elischer  ****
5062b14f991SJulian Elischer  **** The following code probably belongs in another file, like
5072b14f991SJulian Elischer  **** kern/init_init.c.  It is here for two reasons only:
5082b14f991SJulian Elischer  ****
5092b14f991SJulian Elischer  ****	1)	This code returns to startup the system; this is
5102b14f991SJulian Elischer  ****		abnormal for a kernel thread.
5112b14f991SJulian Elischer  ****	2)	This code promiscuously uses init_frame
5122b14f991SJulian Elischer  ****
5132b14f991SJulian Elischer  ***************************************************************************
514df8bae1dSRodney W. Grimes  */
515df8bae1dSRodney W. Grimes 
516d841aaa7SBruce Evans static void kthread_init __P((void *dummy));
5172b14f991SJulian Elischer SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
5182b14f991SJulian Elischer 
5192b14f991SJulian Elischer 
5202b14f991SJulian Elischer static void start_init __P((struct proc *p, void *framep));
5212b14f991SJulian Elischer 
5222b14f991SJulian Elischer /* ARGSUSED*/
5232b14f991SJulian Elischer static void
524d841aaa7SBruce Evans kthread_init(dummy)
525d841aaa7SBruce Evans 	void *dummy;
5262b14f991SJulian Elischer {
527df8bae1dSRodney W. Grimes 
528df8bae1dSRodney W. Grimes 	/* Create process 1 (init(8)). */
5292b14f991SJulian Elischer 	start_init(curproc, init_framep);
5302b14f991SJulian Elischer 
5312b14f991SJulian Elischer 	/*
5322b14f991SJulian Elischer 	 * This is the only kernel thread allowed to return yo the
5332b14f991SJulian Elischer 	 * caller!!!
5342b14f991SJulian Elischer 	 */
535df8bae1dSRodney W. Grimes 	return;
536df8bae1dSRodney W. Grimes }
537df8bae1dSRodney W. Grimes 
538df8bae1dSRodney W. Grimes 
539df8bae1dSRodney W. Grimes /*
540df8bae1dSRodney W. Grimes  * List of paths to try when searching for "init".
541df8bae1dSRodney W. Grimes  */
542df8bae1dSRodney W. Grimes static char *initpaths[] = {
543df8bae1dSRodney W. Grimes 	"/sbin/init",
544df8bae1dSRodney W. Grimes 	"/sbin/oinit",
545df8bae1dSRodney W. Grimes 	"/sbin/init.bak",
5462257b745SPoul-Henning Kamp 	"/stand/sysinstall",
547df8bae1dSRodney W. Grimes 	NULL,
548df8bae1dSRodney W. Grimes };
549df8bae1dSRodney W. Grimes 
550df8bae1dSRodney W. Grimes /*
551df8bae1dSRodney W. Grimes  * Start the initial user process; try exec'ing each pathname in "initpaths".
552df8bae1dSRodney W. Grimes  * The program is invoked with one argument containing the boot flags.
553df8bae1dSRodney W. Grimes  */
554df8bae1dSRodney W. Grimes static void
555df8bae1dSRodney W. Grimes start_init(p, framep)
556df8bae1dSRodney W. Grimes 	struct proc *p;
557df8bae1dSRodney W. Grimes 	void *framep;
558df8bae1dSRodney W. Grimes {
559df8bae1dSRodney W. Grimes 	vm_offset_t addr;
560df8bae1dSRodney W. Grimes 	struct execve_args args;
561df8bae1dSRodney W. Grimes 	int options, i, retval[2], error;
562df8bae1dSRodney W. Grimes 	char **pathp, *path, *ucp, **uap, *arg0, *arg1;
563df8bae1dSRodney W. Grimes 
564df8bae1dSRodney W. Grimes 	initproc = p;
565df8bae1dSRodney W. Grimes 
566df8bae1dSRodney W. Grimes 	/*
567df8bae1dSRodney W. Grimes 	 * We need to set the system call frame as if we were entered through
568df8bae1dSRodney W. Grimes 	 * a syscall() so that when we call execve() below, it will be able
569df8bae1dSRodney W. Grimes 	 * to set the entry point (see setregs) when it tries to exec.  The
570df8bae1dSRodney W. Grimes 	 * startup code in "locore.s" has allocated space for the frame and
571df8bae1dSRodney W. Grimes 	 * passed a pointer to that space as main's argument.
572df8bae1dSRodney W. Grimes 	 */
573df8bae1dSRodney W. Grimes 	cpu_set_init_frame(p, framep);
574df8bae1dSRodney W. Grimes 
575df8bae1dSRodney W. Grimes 	/*
576df8bae1dSRodney W. Grimes 	 * Need just enough stack to hold the faked-up "execve()" arguments.
577df8bae1dSRodney W. Grimes 	 */
57826f9a767SRodney W. Grimes 	addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE);
579bd7e5f99SJohn Dyson 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
580df8bae1dSRodney W. Grimes 		panic("init: couldn't allocate argument space");
581df8bae1dSRodney W. Grimes 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
58226f9a767SRodney W. Grimes 	p->p_vmspace->vm_ssize = 1;
583df8bae1dSRodney W. Grimes 
584df8bae1dSRodney W. Grimes 	for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
585df8bae1dSRodney W. Grimes 		/*
586df8bae1dSRodney W. Grimes 		 * Move out the boot flag argument.
587df8bae1dSRodney W. Grimes 		 */
588df8bae1dSRodney W. Grimes 		options = 0;
589df8bae1dSRodney W. Grimes 		ucp = (char *)USRSTACK;
590df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, 0);		/* trailing zero */
591df8bae1dSRodney W. Grimes 		if (boothowto & RB_SINGLE) {
592df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 's');
593df8bae1dSRodney W. Grimes 			options = 1;
594df8bae1dSRodney W. Grimes 		}
595df8bae1dSRodney W. Grimes #ifdef notyet
596df8bae1dSRodney W. Grimes                 if (boothowto & RB_FASTBOOT) {
597df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 'f');
598df8bae1dSRodney W. Grimes 			options = 1;
599df8bae1dSRodney W. Grimes 		}
600df8bae1dSRodney W. Grimes #endif
60117755ac8SPoul-Henning Kamp 
60217755ac8SPoul-Henning Kamp #ifdef BOOTCDROM
60317755ac8SPoul-Henning Kamp 		(void)subyte(--ucp, 'C');
60417755ac8SPoul-Henning Kamp 		options = 1;
60517755ac8SPoul-Henning Kamp #endif
606df8bae1dSRodney W. Grimes 		if (options == 0)
607df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, '-');
608df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, '-');		/* leading hyphen */
609df8bae1dSRodney W. Grimes 		arg1 = ucp;
610df8bae1dSRodney W. Grimes 
611df8bae1dSRodney W. Grimes 		/*
612df8bae1dSRodney W. Grimes 		 * Move out the file name (also arg 0).
613df8bae1dSRodney W. Grimes 		 */
614df8bae1dSRodney W. Grimes 		for (i = strlen(path) + 1; i >= 0; i--)
615df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, path[i]);
616df8bae1dSRodney W. Grimes 		arg0 = ucp;
617df8bae1dSRodney W. Grimes 
618df8bae1dSRodney W. Grimes 		/*
619df8bae1dSRodney W. Grimes 		 * Move out the arg pointers.
620df8bae1dSRodney W. Grimes 		 */
621df8bae1dSRodney W. Grimes 		uap = (char **)((int)ucp & ~(NBPW-1));
622df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, 0);	/* terminator */
623df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, (int)arg1);
624df8bae1dSRodney W. Grimes 		(void)suword((caddr_t)--uap, (int)arg0);
625df8bae1dSRodney W. Grimes 
626df8bae1dSRodney W. Grimes 		/*
627df8bae1dSRodney W. Grimes 		 * Point at the arguments.
628df8bae1dSRodney W. Grimes 		 */
629df8bae1dSRodney W. Grimes 		args.fname = arg0;
63026f9a767SRodney W. Grimes 		args.argv = uap;
63126f9a767SRodney W. Grimes 		args.envv = NULL;
632df8bae1dSRodney W. Grimes 
633df8bae1dSRodney W. Grimes 		/*
634df8bae1dSRodney W. Grimes 		 * Now try to exec the program.  If can't for any reason
635df8bae1dSRodney W. Grimes 		 * other than it doesn't exist, complain.
6362b14f991SJulian Elischer 		 *
6372b14f991SJulian Elischer 		 * Otherwise return to main() which returns to btext
6382b14f991SJulian Elischer 		 * which completes the system startup.
639df8bae1dSRodney W. Grimes 		 */
640b5e8ce9fSBruce Evans 		if ((error = execve(p, &args, &retval[0])) == 0)
641df8bae1dSRodney W. Grimes 			return;
642df8bae1dSRodney W. Grimes 		if (error != ENOENT)
643df8bae1dSRodney W. Grimes 			printf("exec %s: error %d\n", path, error);
644df8bae1dSRodney W. Grimes 	}
645df8bae1dSRodney W. Grimes 	printf("init: not found\n");
646df8bae1dSRodney W. Grimes 	panic("no init");
647df8bae1dSRodney W. Grimes }
648