xref: /freebsd/sys/kern/init_main.c (revision de028f5a4a67b635ea3e45799be822c8daa1ff20)
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
42c3aac50fSPeter Wemm  * $FreeBSD$
43df8bae1dSRodney W. Grimes  */
44df8bae1dSRodney W. Grimes 
4567481196SJohn Birrell #include "opt_init_path.h"
4640244964SRobert Watson #include "opt_mac.h"
474bd49128SPeter Wemm 
48df8bae1dSRodney W. Grimes #include <sys/param.h>
499e209b12SAlfred Perlstein #include <sys/kernel.h>
50f36ba452SJake Burkholder #include <sys/exec.h>
51b3c5c18dSBruce Evans #include <sys/file.h>
52df8bae1dSRodney W. Grimes #include <sys/filedesc.h>
530384fff8SJason Evans #include <sys/ktr.h>
541005a129SJohn Baldwin #include <sys/lock.h>
5540244964SRobert Watson #include <sys/mac.h>
56ac0ad63fSBruce Evans #include <sys/mount.h>
5735e0e5b3SJohn Baldwin #include <sys/mutex.h>
588f19eb88SIan Dowse #include <sys/syscallsubr.h>
59946bb7a2SPoul-Henning Kamp #include <sys/sysctl.h>
60df8bae1dSRodney W. Grimes #include <sys/proc.h>
61df8bae1dSRodney W. Grimes #include <sys/resourcevar.h>
62df8bae1dSRodney W. Grimes #include <sys/systm.h>
6336240ea5SDoug Rabson #include <sys/signalvar.h>
64df8bae1dSRodney W. Grimes #include <sys/vnode.h>
65f3f0ca60SSøren Schmidt #include <sys/sysent.h>
66df8bae1dSRodney W. Grimes #include <sys/reboot.h>
67de028f5aSJeff Roberson #include <sys/sched.h>
681005a129SJohn Baldwin #include <sys/sx.h>
69ad7507e2SSteven Wallace #include <sys/sysproto.h>
70efeaf95aSDavid Greenman #include <sys/vmmeter.h>
7174b2192aSJohn Dyson #include <sys/unistd.h>
7294e9d7c1SPeter Wemm #include <sys/malloc.h>
73db901281SPoul-Henning Kamp #include <sys/conf.h>
74df8bae1dSRodney W. Grimes 
75df8bae1dSRodney W. Grimes #include <machine/cpu.h>
76df8bae1dSRodney W. Grimes 
77df8bae1dSRodney W. Grimes #include <vm/vm.h>
78efeaf95aSDavid Greenman #include <vm/vm_param.h>
79efeaf95aSDavid Greenman #include <vm/pmap.h>
80efeaf95aSDavid Greenman #include <vm/vm_map.h>
81efeaf95aSDavid Greenman #include <sys/user.h>
826faaa756SWolfram Schneider #include <sys/copyright.h>
83df8bae1dSRodney W. Grimes 
8437b087a6SPeter Wemm void mi_startup(void);				/* Should be elsewhere */
85df8bae1dSRodney W. Grimes 
86df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */
87154c04e5SPoul-Henning Kamp static struct session session0;
88154c04e5SPoul-Henning Kamp static struct pgrp pgrp0;
89df8bae1dSRodney W. Grimes struct	proc proc0;
90079b7badSJulian Elischer struct	thread thread0;
914f0db5e0SJulian Elischer struct	kse kse0;
924f0db5e0SJulian Elischer struct	ksegrp ksegrp0;
936626c604SJulian Elischer static struct procsig procsig0;
94154c04e5SPoul-Henning Kamp static struct filedesc0 filedesc0;
95154c04e5SPoul-Henning Kamp static struct plimit limit0;
96154c04e5SPoul-Henning Kamp static struct vmspace vmspace0;
972b14f991SJulian Elischer struct	proc *initproc;
98df8bae1dSRodney W. Grimes 
99dedb7b62SPeter Wemm int cmask = CMASK;
100828c9e13SDavid E. O'Brien extern int fallback_elf_brand;
101df8bae1dSRodney W. Grimes 
1022976b7f1SDavid Greenman struct	vnode *rootvp;
103c463cf1cSBruce Evans int	boothowto = 0;		/* initialized so that it can be patched */
1048d0bf3d6SJordan K. Hubbard SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
1057a08bae6SJohn Baldwin int	bootverbose;
1067a08bae6SJohn Baldwin SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
107946bb7a2SPoul-Henning Kamp 
1082b14f991SJulian Elischer /*
1092b14f991SJulian Elischer  * This ensures that there is at least one entry so that the sysinit_set
1102b14f991SJulian Elischer  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
1112b14f991SJulian Elischer  * executed.
11226f9a767SRodney W. Grimes  */
1132b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
1148a129caeSDavid Greenman 
11594e9d7c1SPeter Wemm /*
11694e9d7c1SPeter Wemm  * The sysinit table itself.  Items are checked off as the are run.
11794e9d7c1SPeter Wemm  * If we want to register new sysinit types, add them to newsysinit.
11894e9d7c1SPeter Wemm  */
119f41325dbSPeter Wemm SET_DECLARE(sysinit_set, struct sysinit);
120f41325dbSPeter Wemm struct sysinit **sysinit, **sysinit_end;
121f41325dbSPeter Wemm struct sysinit **newsysinit, **newsysinit_end;
12294e9d7c1SPeter Wemm 
12394e9d7c1SPeter Wemm /*
12494e9d7c1SPeter Wemm  * Merge a new sysinit set into the current set, reallocating it if
12594e9d7c1SPeter Wemm  * necessary.  This can only be called after malloc is running.
12694e9d7c1SPeter Wemm  */
12794e9d7c1SPeter Wemm void
128f41325dbSPeter Wemm sysinit_add(struct sysinit **set, struct sysinit **set_end)
12994e9d7c1SPeter Wemm {
13094e9d7c1SPeter Wemm 	struct sysinit **newset;
13194e9d7c1SPeter Wemm 	struct sysinit **sipp;
13294e9d7c1SPeter Wemm 	struct sysinit **xipp;
133f41325dbSPeter Wemm 	int count;
13494e9d7c1SPeter Wemm 
135f41325dbSPeter Wemm 	count = set_end - set;
136ddd62546SPeter Wemm 	if (newsysinit)
137f41325dbSPeter Wemm 		count += newsysinit_end - newsysinit;
138ddd62546SPeter Wemm 	else
139f41325dbSPeter Wemm 		count += sysinit_end - sysinit;
14094e9d7c1SPeter Wemm 	newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
14194e9d7c1SPeter Wemm 	if (newset == NULL)
14294e9d7c1SPeter Wemm 		panic("cannot malloc for sysinit");
14394e9d7c1SPeter Wemm 	xipp = newset;
144ddd62546SPeter Wemm 	if (newsysinit)
145f41325dbSPeter Wemm 		for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
146ddd62546SPeter Wemm 			*xipp++ = *sipp;
147ddd62546SPeter Wemm 	else
148f41325dbSPeter Wemm 		for (sipp = sysinit; sipp < sysinit_end; sipp++)
14994e9d7c1SPeter Wemm 			*xipp++ = *sipp;
150f41325dbSPeter Wemm 	for (sipp = set; sipp < set_end; sipp++)
15194e9d7c1SPeter Wemm 		*xipp++ = *sipp;
152ddd62546SPeter Wemm 	if (newsysinit)
153ddd62546SPeter Wemm 		free(newsysinit, M_TEMP);
15494e9d7c1SPeter Wemm 	newsysinit = newset;
155f41325dbSPeter Wemm 	newsysinit_end = newset + count;
15694e9d7c1SPeter Wemm }
15726f9a767SRodney W. Grimes 
158df8bae1dSRodney W. Grimes /*
159df8bae1dSRodney W. Grimes  * System startup; initialize the world, create process 0, mount root
160df8bae1dSRodney W. Grimes  * filesystem, and fork to create init and pagedaemon.  Most of the
161df8bae1dSRodney W. Grimes  * hard work is done in the lower-level initialization routines including
162df8bae1dSRodney W. Grimes  * startup(), which does memory initialization and autoconfiguration.
1632b14f991SJulian Elischer  *
1642b14f991SJulian Elischer  * This allows simple addition of new kernel subsystems that require
1652b14f991SJulian Elischer  * boot time initialization.  It also allows substitution of subsystem
1662b14f991SJulian Elischer  * (for instance, a scheduler, kernel profiler, or VM system) by object
167c5b193bfSPoul-Henning Kamp  * module.  Finally, it allows for optional "kernel threads".
168df8bae1dSRodney W. Grimes  */
16926f9a767SRodney W. Grimes void
17037b087a6SPeter Wemm mi_startup(void)
171df8bae1dSRodney W. Grimes {
1722b14f991SJulian Elischer 
1732b14f991SJulian Elischer 	register struct sysinit **sipp;		/* system initialization*/
1742b14f991SJulian Elischer 	register struct sysinit **xipp;		/* interior loop of sort*/
1752b14f991SJulian Elischer 	register struct sysinit *save;		/* bubble*/
1762b14f991SJulian Elischer 
177f41325dbSPeter Wemm 	if (sysinit == NULL) {
178f41325dbSPeter Wemm 		sysinit = SET_BEGIN(sysinit_set);
179f41325dbSPeter Wemm 		sysinit_end = SET_LIMIT(sysinit_set);
180f41325dbSPeter Wemm 	}
181f41325dbSPeter Wemm 
18294e9d7c1SPeter Wemm restart:
1832b14f991SJulian Elischer 	/*
1842b14f991SJulian Elischer 	 * Perform a bubble sort of the system initialization objects by
1852b14f991SJulian Elischer 	 * their subsystem (primary key) and order (secondary key).
1862b14f991SJulian Elischer 	 */
187f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
188f41325dbSPeter Wemm 		for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
1892b14f991SJulian Elischer 			if ((*sipp)->subsystem < (*xipp)->subsystem ||
1902b14f991SJulian Elischer 			     ((*sipp)->subsystem == (*xipp)->subsystem &&
191af4b2d2dSPeter Wemm 			      (*sipp)->order <= (*xipp)->order))
1922b14f991SJulian Elischer 				continue;	/* skip*/
1932b14f991SJulian Elischer 			save = *sipp;
1942b14f991SJulian Elischer 			*sipp = *xipp;
1952b14f991SJulian Elischer 			*xipp = save;
1962b14f991SJulian Elischer 		}
1972b14f991SJulian Elischer 	}
1982b14f991SJulian Elischer 
1992b14f991SJulian Elischer 	/*
2002b14f991SJulian Elischer 	 * Traverse the (now) ordered list of system initialization tasks.
2012b14f991SJulian Elischer 	 * Perform each task, and continue on to the next task.
2022b14f991SJulian Elischer 	 *
2032b14f991SJulian Elischer 	 * The last item on the list is expected to be the scheduler,
2042b14f991SJulian Elischer 	 * which will not return.
2052b14f991SJulian Elischer 	 */
206f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
20774b2192aSJohn Dyson 
2082b14f991SJulian Elischer 		if ((*sipp)->subsystem == SI_SUB_DUMMY)
2092b14f991SJulian Elischer 			continue;	/* skip dummy task(s)*/
2102b14f991SJulian Elischer 
21194e9d7c1SPeter Wemm 		if ((*sipp)->subsystem == SI_SUB_DONE)
21294e9d7c1SPeter Wemm 			continue;
21394e9d7c1SPeter Wemm 
2149c8b8baaSPeter Wemm 		/* Call function */
2152b14f991SJulian Elischer 		(*((*sipp)->func))((*sipp)->udata);
21694e9d7c1SPeter Wemm 
21794e9d7c1SPeter Wemm 		/* Check off the one we're just done */
21894e9d7c1SPeter Wemm 		(*sipp)->subsystem = SI_SUB_DONE;
21994e9d7c1SPeter Wemm 
22094e9d7c1SPeter Wemm 		/* Check if we've installed more sysinit items via KLD */
22194e9d7c1SPeter Wemm 		if (newsysinit != NULL) {
222f41325dbSPeter Wemm 			if (sysinit != SET_BEGIN(sysinit_set))
22394e9d7c1SPeter Wemm 				free(sysinit, M_TEMP);
22494e9d7c1SPeter Wemm 			sysinit = newsysinit;
225f41325dbSPeter Wemm 			sysinit_end = newsysinit_end;
22694e9d7c1SPeter Wemm 			newsysinit = NULL;
227f41325dbSPeter Wemm 			newsysinit_end = NULL;
22894e9d7c1SPeter Wemm 			goto restart;
22994e9d7c1SPeter Wemm 		}
2302b14f991SJulian Elischer 	}
2312b14f991SJulian Elischer 
232477a642cSPeter Wemm 	panic("Shouldn't get here!");
2332b14f991SJulian Elischer 	/* NOTREACHED*/
2342b14f991SJulian Elischer }
2352b14f991SJulian Elischer 
2362b14f991SJulian Elischer 
2372b14f991SJulian Elischer /*
2382b14f991SJulian Elischer  ***************************************************************************
2392b14f991SJulian Elischer  ****
2402b14f991SJulian Elischer  **** The following SYSINIT's belong elsewhere, but have not yet
2412b14f991SJulian Elischer  **** been moved.
2422b14f991SJulian Elischer  ****
2432b14f991SJulian Elischer  ***************************************************************************
2442b14f991SJulian Elischer  */
2459ef6c28aSBruce Evans static void
24637b087a6SPeter Wemm print_caddr_t(void *data __unused)
2479ef6c28aSBruce Evans {
2489ef6c28aSBruce Evans 	printf("%s", (char *)data);
2499ef6c28aSBruce Evans }
250d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
2517a08bae6SJohn Baldwin SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, version)
2527a08bae6SJohn Baldwin 
2537a08bae6SJohn Baldwin static void
2547a08bae6SJohn Baldwin set_boot_verbose(void *data __unused)
2557a08bae6SJohn Baldwin {
2567a08bae6SJohn Baldwin 
2577a08bae6SJohn Baldwin 	if (boothowto & RB_VERBOSE)
2587a08bae6SJohn Baldwin 		bootverbose++;
2597a08bae6SJohn Baldwin }
2607a08bae6SJohn Baldwin SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL)
2612b14f991SJulian Elischer 
262f36ba452SJake Burkholder struct sysentvec null_sysvec = {
263f36ba452SJake Burkholder 	0,
264f36ba452SJake Burkholder 	NULL,
265f36ba452SJake Burkholder 	0,
266f36ba452SJake Burkholder 	0,
267f36ba452SJake Burkholder 	NULL,
268f36ba452SJake Burkholder 	0,
269f36ba452SJake Burkholder 	NULL,
270f36ba452SJake Burkholder 	NULL,
271f36ba452SJake Burkholder 	NULL,
272f36ba452SJake Burkholder 	NULL,
273f36ba452SJake Burkholder 	NULL,
274f36ba452SJake Burkholder 	NULL,
275f36ba452SJake Burkholder 	NULL,
276f36ba452SJake Burkholder 	"null",
277f36ba452SJake Burkholder 	NULL,
278f36ba452SJake Burkholder 	NULL,
279f36ba452SJake Burkholder 	0,
280f36ba452SJake Burkholder 	PAGE_SIZE,
281f36ba452SJake Burkholder 	VM_MIN_ADDRESS,
282f36ba452SJake Burkholder 	VM_MAXUSER_ADDRESS,
283f36ba452SJake Burkholder 	USRSTACK,
284f36ba452SJake Burkholder 	PS_STRINGS,
285f36ba452SJake Burkholder 	VM_PROT_ALL,
286f36ba452SJake Burkholder 	NULL,
287f36ba452SJake Burkholder 	NULL
288f36ba452SJake Burkholder };
2893ebc1248SPeter Wemm 
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*/
304154c04e5SPoul-Henning Kamp static void
30537b087a6SPeter Wemm proc0_init(void *dummy __unused)
3062b14f991SJulian Elischer {
307df8bae1dSRodney W. Grimes 	register struct proc		*p;
308df8bae1dSRodney W. Grimes 	register struct filedesc0	*fdp;
30992579404SAlexander Langer 	register unsigned i;
310b40ce416SJulian Elischer 	struct thread *td;
311079b7badSJulian Elischer 	struct ksegrp *kg;
312079b7badSJulian Elischer 	struct kse *ke;
313df8bae1dSRodney W. Grimes 
3140cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
315df8bae1dSRodney W. Grimes 	p = &proc0;
316079b7badSJulian Elischer 	td = &thread0;
3174f0db5e0SJulian Elischer 	ke = &kse0;
3184f0db5e0SJulian Elischer 	kg = &ksegrp0;
319df8bae1dSRodney W. Grimes 
320de028f5aSJeff Roberson 	ke->ke_sched = kse0_sched;
321de028f5aSJeff Roberson 	kg->kg_sched = ksegrp0_sched;
322de028f5aSJeff Roberson 	p->p_sched = proc0_sched;
323de028f5aSJeff Roberson 	td->td_sched = thread0_sched;
324de028f5aSJeff Roberson 
325df8bae1dSRodney W. Grimes 	/*
3260384fff8SJason Evans 	 * Initialize magic number.
3270384fff8SJason Evans 	 */
3280384fff8SJason Evans 	p->p_magic = P_MAGIC;
3290384fff8SJason Evans 
3300384fff8SJason Evans 	/*
331079b7badSJulian Elischer 	 * Initialize thread, process and pgrp structures.
332a3bfb996SJeffrey Hsu 	 */
333a3bfb996SJeffrey Hsu 	procinit();
334e602ba25SJulian Elischer 	threadinit();
335a3bfb996SJeffrey Hsu 
336a3bfb996SJeffrey Hsu 	/*
337b1508c72SDavid Greenman 	 * Initialize sleep queue hash table
338b1508c72SDavid Greenman 	 */
339b1508c72SDavid Greenman 	sleepinit();
340b1508c72SDavid Greenman 
341b1508c72SDavid Greenman 	/*
3423075778bSJohn Dyson 	 * additional VM structures
3433075778bSJohn Dyson 	 */
3443075778bSJohn Dyson 	vm_init2();
3453075778bSJohn Dyson 
3463075778bSJohn Dyson 	/*
347df8bae1dSRodney W. Grimes 	 * Create process 0 (the swapper).
348df8bae1dSRodney W. Grimes 	 */
349a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&allproc, p, p_list);
3507b531e60SJohn Baldwin 	LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
3516008862bSJohn Baldwin 	mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
352df8bae1dSRodney W. Grimes 	p->p_pgrp = &pgrp0;
353a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
354a3bfb996SJeffrey Hsu 	LIST_INIT(&pgrp0.pg_members);
355a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
356a3bfb996SJeffrey Hsu 
357df8bae1dSRodney W. Grimes 	pgrp0.pg_session = &session0;
3586008862bSJohn Baldwin 	mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
359df8bae1dSRodney W. Grimes 	session0.s_count = 1;
360df8bae1dSRodney W. Grimes 	session0.s_leader = p;
361df8bae1dSRodney W. Grimes 
3623ebc1248SPeter Wemm 	p->p_sysent = &null_sysvec;
363f3f0ca60SSøren Schmidt 
364e602ba25SJulian Elischer 	/*
365e602ba25SJulian Elischer 	 * proc_linkup was already done in init_i386() or alphainit() etc.
366e602ba25SJulian Elischer 	 * because the earlier code needed to follow td->td_proc. Otherwise
367e602ba25SJulian Elischer 	 * I would have done it here.. maybe this means this should be
368e602ba25SJulian Elischer 	 * done earlier too.
369e602ba25SJulian Elischer 	 */
370f202965eSJohn Baldwin 	p->p_flag = P_SYSTEM;
371f202965eSJohn Baldwin 	p->p_sflag = PS_INMEM;
372e602ba25SJulian Elischer 	p->p_state = PRS_NORMAL;
373e602ba25SJulian Elischer 	td->td_state = TDS_RUNNING;
374e602ba25SJulian Elischer 	kg->kg_nice = NZERO;
3752c100766SJulian Elischer 	kg->kg_pri_class = PRI_TIMESHARE;
3762c100766SJulian Elischer 	kg->kg_user_pri = PUSER;
3772c100766SJulian Elischer 	td->td_priority = PVM;
3782c100766SJulian Elischer 	td->td_base_pri = PUSER;
379e602ba25SJulian Elischer 	td->td_kse = ke; /* XXXKSE */
380e602ba25SJulian Elischer 	ke->ke_oncpu = 0;
381c3b98db0SJulian Elischer 	ke->ke_state = KES_THREAD;
382e602ba25SJulian Elischer 	ke->ke_thread = td;
3832c1011f7SJohn Dyson 	p->p_peers = 0;
3842c1011f7SJohn Dyson 	p->p_leader = p;
385e602ba25SJulian Elischer 
3862c1011f7SJohn Dyson 
387df8bae1dSRodney W. Grimes 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
388df8bae1dSRodney W. Grimes 
3894f559836SJake Burkholder 	callout_init(&p->p_itcallout, 0);
390b40ce416SJulian Elischer 	callout_init(&td->td_slpcallout, 1);
3914f559836SJake Burkholder 
392df8bae1dSRodney W. Grimes 	/* Create credentials. */
393df8bae1dSRodney W. Grimes 	p->p_ucred = crget();
394df8bae1dSRodney W. Grimes 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
395f535380cSDon Lewis 	p->p_ucred->cr_uidinfo = uifind(0);
396b1fc0ec1SRobert Watson 	p->p_ucred->cr_ruidinfo = uifind(0);
39791421ba2SRobert Watson 	p->p_ucred->cr_prison = NULL;	/* Don't jail it. */
39840244964SRobert Watson #ifdef MAC
39940244964SRobert Watson 	mac_create_proc0(p->p_ucred);
40040244964SRobert Watson #endif
4018e2e767bSJohn Baldwin 	td->td_ucred = crhold(p->p_ucred);
40275c13541SPoul-Henning Kamp 
4036626c604SJulian Elischer 	/* Create procsig. */
4046626c604SJulian Elischer 	p->p_procsig = &procsig0;
40575ffaf59SLuoqi Chen 	p->p_procsig->ps_refcnt = 1;
4066626c604SJulian Elischer 
40737b087a6SPeter Wemm 	/* Initialize signal state for process 0. */
40837b087a6SPeter Wemm 	siginit(&proc0);
40937b087a6SPeter Wemm 
410df8bae1dSRodney W. Grimes 	/* Create the file descriptor table. */
411df8bae1dSRodney W. Grimes 	fdp = &filedesc0;
412df8bae1dSRodney W. Grimes 	p->p_fd = &fdp->fd_fd;
4136008862bSJohn Baldwin 	mtx_init(&fdp->fd_fd.fd_mtx, FILEDESC_LOCK_DESC, NULL, MTX_DEF);
414df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_refcnt = 1;
415df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_cmask = cmask;
416df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
417df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
418df8bae1dSRodney W. Grimes 	fdp->fd_fd.fd_nfiles = NDFILE;
419df8bae1dSRodney W. Grimes 
420df8bae1dSRodney W. Grimes 	/* Create the limits structures. */
421df8bae1dSRodney W. Grimes 	p->p_limit = &limit0;
422df8bae1dSRodney W. Grimes 	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
423df8bae1dSRodney W. Grimes 		limit0.pl_rlimit[i].rlim_cur =
424df8bae1dSRodney W. Grimes 		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
425b3c5c18dSBruce Evans 	limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
426b3c5c18dSBruce Evans 	    limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
427b3c5c18dSBruce Evans 	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
428b3c5c18dSBruce Evans 	    limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
429df8bae1dSRodney W. Grimes 	i = ptoa(cnt.v_free_count);
430df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
431df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
432df8bae1dSRodney W. Grimes 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
433df8bae1dSRodney W. Grimes 	limit0.p_refcnt = 1;
4345715307fSJohn Baldwin 	p->p_cpulimit = RLIM_INFINITY;
435df8bae1dSRodney W. Grimes 
436df8bae1dSRodney W. Grimes 	/* Allocate a prototype map so we have something to fork. */
437b1028ad1SLuoqi Chen 	pmap_pinit0(vmspace_pmap(&vmspace0));
438df8bae1dSRodney W. Grimes 	p->p_vmspace = &vmspace0;
439df8bae1dSRodney W. Grimes 	vmspace0.vm_refcnt = 1;
44005ba50f5SJake Burkholder 	vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
44105ba50f5SJake Burkholder 	    p->p_sysent->sv_maxuser);
442b1028ad1SLuoqi Chen 	vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
443df8bae1dSRodney W. Grimes 
44439fb8e6bSJulian Elischer 	/*
445df8bae1dSRodney W. Grimes 	 * We continue to place resource usage info and signal
446df8bae1dSRodney W. Grimes 	 * actions in the user struct so they're pageable.
447df8bae1dSRodney W. Grimes 	 */
448b40ce416SJulian Elischer 	p->p_stats = &p->p_uarea->u_stats;
449b40ce416SJulian Elischer 	p->p_sigacts = &p->p_uarea->u_sigacts;
450df8bae1dSRodney W. Grimes 
451df8bae1dSRodney W. Grimes 	/*
452a3bfb996SJeffrey Hsu 	 * Charge root for one process.
453df8bae1dSRodney W. Grimes 	 */
454b1fc0ec1SRobert Watson 	(void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
45526f9a767SRodney W. Grimes }
4562b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
4572b14f991SJulian Elischer 
4582b14f991SJulian Elischer /* ARGSUSED*/
459154c04e5SPoul-Henning Kamp static void
46037b087a6SPeter Wemm proc0_post(void *dummy __unused)
4612b14f991SJulian Elischer {
46200af9731SPoul-Henning Kamp 	struct timespec ts;
46337b087a6SPeter Wemm 	struct proc *p;
464a6fc8288SPeter Wemm 
4652b14f991SJulian Elischer 	/*
4661b0b259eSBruce Evans 	 * Now we can look at the time, having had a chance to verify the
4671b0b259eSBruce Evans 	 * time from the filesystem.  Pretend that proc0 started now.
4682b14f991SJulian Elischer 	 */
4691005a129SJohn Baldwin 	sx_slock(&allproc_lock);
47037b087a6SPeter Wemm 	LIST_FOREACH(p, &allproc, p_list) {
47137b087a6SPeter Wemm 		microtime(&p->p_stats->p_start);
4721cbb9c3bSPoul-Henning Kamp 		p->p_runtime.sec = 0;
4731cbb9c3bSPoul-Henning Kamp 		p->p_runtime.frac = 0;
47437b087a6SPeter Wemm 	}
4751005a129SJohn Baldwin 	sx_sunlock(&allproc_lock);
476e2256f43SPeter Wemm 	binuptime(PCPU_PTR(switchtime));
4770384fff8SJason Evans 	PCPU_SET(switchticks, ticks);
4782b14f991SJulian Elischer 
479a6fc8288SPeter Wemm 	/*
480a6fc8288SPeter Wemm 	 * Give the ``random'' number generator a thump.
481a6fc8288SPeter Wemm 	 */
48200af9731SPoul-Henning Kamp 	nanotime(&ts);
48300af9731SPoul-Henning Kamp 	srandom(ts.tv_sec ^ ts.tv_nsec);
4842b14f991SJulian Elischer }
4852b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
4862b14f991SJulian Elischer 
487df8bae1dSRodney W. Grimes /*
4882b14f991SJulian Elischer  ***************************************************************************
4892b14f991SJulian Elischer  ****
4902b14f991SJulian Elischer  **** The following SYSINIT's and glue code should be moved to the
4912b14f991SJulian Elischer  **** respective files on a per subsystem basis.
4922b14f991SJulian Elischer  ****
4932b14f991SJulian Elischer  ***************************************************************************
494df8bae1dSRodney W. Grimes  */
495df8bae1dSRodney W. Grimes 
496df8bae1dSRodney W. Grimes 
497df8bae1dSRodney W. Grimes /*
4982b14f991SJulian Elischer  ***************************************************************************
4992b14f991SJulian Elischer  ****
5002b14f991SJulian Elischer  **** The following code probably belongs in another file, like
50137b087a6SPeter Wemm  **** kern/init_init.c.
5022b14f991SJulian Elischer  ****
5032b14f991SJulian Elischer  ***************************************************************************
504df8bae1dSRodney W. Grimes  */
505df8bae1dSRodney W. Grimes 
506df8bae1dSRodney W. Grimes /*
507df8bae1dSRodney W. Grimes  * List of paths to try when searching for "init".
508df8bae1dSRodney W. Grimes  */
5095f967b24SDag-Erling Smørgrav static char init_path[MAXPATHLEN] =
51067481196SJohn Birrell #ifdef	INIT_PATH
51167481196SJohn Birrell     __XSTRING(INIT_PATH);
51267481196SJohn Birrell #else
513e4082284SJohn Birrell     "/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall";
51467481196SJohn Birrell #endif
515af1408e3SLuigi Rizzo SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
516af1408e3SLuigi Rizzo 	"Path used to search the init process");
517df8bae1dSRodney W. Grimes 
518df8bae1dSRodney W. Grimes /*
5195f967b24SDag-Erling Smørgrav  * Start the initial user process; try exec'ing each pathname in init_path.
520df8bae1dSRodney W. Grimes  * The program is invoked with one argument containing the boot flags.
521df8bae1dSRodney W. Grimes  */
522df8bae1dSRodney W. Grimes static void
52337b087a6SPeter Wemm start_init(void *dummy)
524df8bae1dSRodney W. Grimes {
525df8bae1dSRodney W. Grimes 	vm_offset_t addr;
526df8bae1dSRodney W. Grimes 	struct execve_args args;
5275f967b24SDag-Erling Smørgrav 	int options, error;
5285f967b24SDag-Erling Smørgrav 	char *var, *path, *next, *s;
5295f967b24SDag-Erling Smørgrav 	char *ucp, **uap, *arg0, *arg1;
530b40ce416SJulian Elischer 	struct thread *td;
5319c8b8baaSPeter Wemm 	struct proc *p;
532b7116168SPeter Wemm 	int init_does_devfs = 0;
533df8bae1dSRodney W. Grimes 
5349ed346baSBosko Milekic 	mtx_lock(&Giant);
5350384fff8SJason Evans 
5360cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
5370cddd8f0SMatthew Dillon 
538b40ce416SJulian Elischer 	td = curthread;
539b40ce416SJulian Elischer 	p = td->td_proc;
540df8bae1dSRodney W. Grimes 
541563af2ecSMaxime Henrion 	vfs_mountroot();
542fb92273bSPoul-Henning Kamp 
54337b087a6SPeter Wemm 	/* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
54437b087a6SPeter Wemm 	if (VFS_ROOT(TAILQ_FIRST(&mountlist), &rootvnode))
54537b087a6SPeter Wemm 		panic("cannot find root vnode");
546426da3bcSAlfred Perlstein 	FILEDESC_LOCK(p->p_fd);
54737b087a6SPeter Wemm 	p->p_fd->fd_cdir = rootvnode;
54837b087a6SPeter Wemm 	VREF(p->p_fd->fd_cdir);
54937b087a6SPeter Wemm 	p->p_fd->fd_rdir = rootvnode;
550a90ef2aeSIan Dowse 	VREF(p->p_fd->fd_rdir);
551426da3bcSAlfred Perlstein 	FILEDESC_UNLOCK(p->p_fd);
552b40ce416SJulian Elischer 	VOP_UNLOCK(rootvnode, 0, td);
553a87cdf83SRobert Watson #ifdef MAC
554a87cdf83SRobert Watson 	mac_create_root_mount(td->td_ucred, TAILQ_FIRST(&mountlist));
555a87cdf83SRobert Watson #endif
55637b087a6SPeter Wemm 
557b7116168SPeter Wemm 	if (devfs_present) {
558b7116168SPeter Wemm 		/*
559b7116168SPeter Wemm 		 * For disk based systems, we probably cannot do this yet
560b7116168SPeter Wemm 		 * since the fs will be read-only.  But a NFS root
561b7116168SPeter Wemm 		 * might be ok.  It is worth a shot.
562b7116168SPeter Wemm 		 */
5638f19eb88SIan Dowse 		error = kern_mkdir(td, "/dev", UIO_SYSSPACE, 0700);
564b7116168SPeter Wemm 		if (error == EEXIST)
565b7116168SPeter Wemm 			error = 0;
566b7116168SPeter Wemm 		if (error == 0)
5676dbde1feSMaxime Henrion 			error = kernel_vmount(0, "fstype", "devfs",
5686dbde1feSMaxime Henrion 			    "fspath", "/dev", NULL);
569b7116168SPeter Wemm 		if (error != 0)
570b7116168SPeter Wemm 			init_does_devfs = 1;
571b7116168SPeter Wemm 	}
572b7116168SPeter Wemm 
573df8bae1dSRodney W. Grimes 	/*
574df8bae1dSRodney W. Grimes 	 * Need just enough stack to hold the faked-up "execve()" arguments.
575df8bae1dSRodney W. Grimes 	 */
57605ba50f5SJake Burkholder 	addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
5775f967b24SDag-Erling Smørgrav 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
5785f967b24SDag-Erling Smørgrav 			FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
579df8bae1dSRodney W. Grimes 		panic("init: couldn't allocate argument space");
580df8bae1dSRodney W. Grimes 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
58126f9a767SRodney W. Grimes 	p->p_vmspace->vm_ssize = 1;
582df8bae1dSRodney W. Grimes 
5835f967b24SDag-Erling Smørgrav 	if ((var = getenv("init_path")) != NULL) {
584e80fb434SRobert Drehmel 		strlcpy(init_path, var, sizeof(init_path));
585d786139cSMaxime Henrion 		freeenv(var);
5865f967b24SDag-Erling Smørgrav 	}
587d786139cSMaxime Henrion 	if ((var = getenv("kern.fallback_elf_brand")) != NULL) {
588828c9e13SDavid E. O'Brien 		fallback_elf_brand = strtol(var, NULL, 0);
589d786139cSMaxime Henrion 		freeenv(var);
590d786139cSMaxime Henrion 	}
5915f967b24SDag-Erling Smørgrav 
59267481196SJohn Birrell 	for (path = init_path; *path != '\0'; path = next) {
593e4082284SJohn Birrell 		while (*path == ':')
5945f967b24SDag-Erling Smørgrav 			path++;
59567481196SJohn Birrell 		if (*path == '\0')
5965f967b24SDag-Erling Smørgrav 			break;
597e4082284SJohn Birrell 		for (next = path; *next != '\0' && *next != ':'; next++)
5985f967b24SDag-Erling Smørgrav 			/* nothing */ ;
5995f967b24SDag-Erling Smørgrav 		if (bootverbose)
600ba41a07dSDmitrij Tejblum 			printf("start_init: trying %.*s\n", (int)(next - path),
601ba41a07dSDmitrij Tejblum 			    path);
6025f967b24SDag-Erling Smørgrav 
603df8bae1dSRodney W. Grimes 		/*
604df8bae1dSRodney W. Grimes 		 * Move out the boot flag argument.
605df8bae1dSRodney W. Grimes 		 */
606df8bae1dSRodney W. Grimes 		options = 0;
60705ba50f5SJake Burkholder 		ucp = (char *)p->p_sysent->sv_usrstack;
608df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, 0);		/* trailing zero */
609df8bae1dSRodney W. Grimes 		if (boothowto & RB_SINGLE) {
610df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 's');
611df8bae1dSRodney W. Grimes 			options = 1;
612df8bae1dSRodney W. Grimes 		}
613df8bae1dSRodney W. Grimes #ifdef notyet
614df8bae1dSRodney W. Grimes                 if (boothowto & RB_FASTBOOT) {
615df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 'f');
616df8bae1dSRodney W. Grimes 			options = 1;
617df8bae1dSRodney W. Grimes 		}
618df8bae1dSRodney W. Grimes #endif
61917755ac8SPoul-Henning Kamp 
62017755ac8SPoul-Henning Kamp #ifdef BOOTCDROM
62117755ac8SPoul-Henning Kamp 		(void)subyte(--ucp, 'C');
62217755ac8SPoul-Henning Kamp 		options = 1;
62317755ac8SPoul-Henning Kamp #endif
624b7116168SPeter Wemm 		if (init_does_devfs) {
6253f54a085SPoul-Henning Kamp 			(void)subyte(--ucp, 'd');
6263f54a085SPoul-Henning Kamp 			options = 1;
627db901281SPoul-Henning Kamp 		}
628db901281SPoul-Henning Kamp 
629df8bae1dSRodney W. Grimes 		if (options == 0)
630df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, '-');
631df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, '-');		/* leading hyphen */
632df8bae1dSRodney W. Grimes 		arg1 = ucp;
633df8bae1dSRodney W. Grimes 
634df8bae1dSRodney W. Grimes 		/*
635df8bae1dSRodney W. Grimes 		 * Move out the file name (also arg 0).
636df8bae1dSRodney W. Grimes 		 */
6375f967b24SDag-Erling Smørgrav 		(void)subyte(--ucp, 0);
6385f967b24SDag-Erling Smørgrav 		for (s = next - 1; s >= path; s--)
6395f967b24SDag-Erling Smørgrav 			(void)subyte(--ucp, *s);
640df8bae1dSRodney W. Grimes 		arg0 = ucp;
641df8bae1dSRodney W. Grimes 
642df8bae1dSRodney W. Grimes 		/*
643df8bae1dSRodney W. Grimes 		 * Move out the arg pointers.
644df8bae1dSRodney W. Grimes 		 */
645a20d7755SDoug Rabson 		uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
646c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)0);	/* terminator */
647c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
648c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
649df8bae1dSRodney W. Grimes 
650df8bae1dSRodney W. Grimes 		/*
651df8bae1dSRodney W. Grimes 		 * Point at the arguments.
652df8bae1dSRodney W. Grimes 		 */
653df8bae1dSRodney W. Grimes 		args.fname = arg0;
65426f9a767SRodney W. Grimes 		args.argv = uap;
65526f9a767SRodney W. Grimes 		args.envv = NULL;
656df8bae1dSRodney W. Grimes 
657df8bae1dSRodney W. Grimes 		/*
658df8bae1dSRodney W. Grimes 		 * Now try to exec the program.  If can't for any reason
659df8bae1dSRodney W. Grimes 		 * other than it doesn't exist, complain.
6602b14f991SJulian Elischer 		 *
66137b087a6SPeter Wemm 		 * Otherwise, return via fork_trampoline() all the way
6629c8b8baaSPeter Wemm 		 * to user mode as init!
663df8bae1dSRodney W. Grimes 		 */
664b40ce416SJulian Elischer 		if ((error = execve(td, &args)) == 0) {
6659ed346baSBosko Milekic 			mtx_unlock(&Giant);
666df8bae1dSRodney W. Grimes 			return;
667db72809dSJohn Baldwin 		}
668df8bae1dSRodney W. Grimes 		if (error != ENOENT)
669ba41a07dSDmitrij Tejblum 			printf("exec %.*s: error %d\n", (int)(next - path),
670ba41a07dSDmitrij Tejblum 			    path, error);
671df8bae1dSRodney W. Grimes 	}
672580e7e5aSGreg Lehey 	printf("init: not found in path %s\n", init_path);
673df8bae1dSRodney W. Grimes 	panic("no init");
674df8bae1dSRodney W. Grimes }
67537b087a6SPeter Wemm 
67637b087a6SPeter Wemm /*
67737b087a6SPeter Wemm  * Like kthread_create(), but runs in it's own address space.
67837b087a6SPeter Wemm  * We do this early to reserve pid 1.
67937b087a6SPeter Wemm  *
68037b087a6SPeter Wemm  * Note special case - do not make it runnable yet.  Other work
68137b087a6SPeter Wemm  * in progress will change this more.
68237b087a6SPeter Wemm  */
68337b087a6SPeter Wemm static void
68437b087a6SPeter Wemm create_init(const void *udata __unused)
68537b087a6SPeter Wemm {
6865a06cb0cSRobert Watson 	struct ucred *newcred, *oldcred;
68737b087a6SPeter Wemm 	int error;
68837b087a6SPeter Wemm 
689316ec49aSScott Long 	error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
69037b087a6SPeter Wemm 	if (error)
69137b087a6SPeter Wemm 		panic("cannot fork init: %d\n", error);
6925a06cb0cSRobert Watson 	/* divorce init's credentials from the kernel's */
6935a06cb0cSRobert Watson 	newcred = crget();
694f202965eSJohn Baldwin 	PROC_LOCK(initproc);
695f202965eSJohn Baldwin 	initproc->p_flag |= P_SYSTEM;
6965a06cb0cSRobert Watson 	oldcred = initproc->p_ucred;
6975a06cb0cSRobert Watson 	crcopy(newcred, oldcred);
69840244964SRobert Watson #ifdef MAC
69940244964SRobert Watson 	mac_create_proc1(newcred);
70040244964SRobert Watson #endif
7015a06cb0cSRobert Watson 	initproc->p_ucred = newcred;
702f202965eSJohn Baldwin 	PROC_UNLOCK(initproc);
7035a06cb0cSRobert Watson 	crfree(oldcred);
7044d1a4bb7SRobert Watson 	cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
7059ed346baSBosko Milekic 	mtx_lock_spin(&sched_lock);
706f202965eSJohn Baldwin 	initproc->p_sflag |= PS_INMEM;
7079ed346baSBosko Milekic 	mtx_unlock_spin(&sched_lock);
708079b7badSJulian Elischer 	cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
70937b087a6SPeter Wemm }
71037b087a6SPeter Wemm SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
71137b087a6SPeter Wemm 
71237b087a6SPeter Wemm /*
71337b087a6SPeter Wemm  * Make it runnable now.
71437b087a6SPeter Wemm  */
71537b087a6SPeter Wemm static void
71637b087a6SPeter Wemm kick_init(const void *udata __unused)
71737b087a6SPeter Wemm {
718079b7badSJulian Elischer 	struct thread *td;
719f202965eSJohn Baldwin 
720079b7badSJulian Elischer 	td = FIRST_THREAD_IN_PROC(initproc);
7219ed346baSBosko Milekic 	mtx_lock_spin(&sched_lock);
72271fad9fdSJulian Elischer 	TD_SET_CAN_RUN(td);
723e602ba25SJulian Elischer 	setrunqueue(td);	/* XXXKSE */
7249ed346baSBosko Milekic 	mtx_unlock_spin(&sched_lock);
72537b087a6SPeter Wemm }
72637b087a6SPeter Wemm SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)
727