xref: /freebsd/sys/kern/init_main.c (revision 1c4bcd050a4f7163d68f608db860aef5fad81d6c)
19454b2d8SWarner Losh /*-
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
42df8bae1dSRodney W. Grimes  */
43df8bae1dSRodney W. Grimes 
44677b542eSDavid E. O'Brien #include <sys/cdefs.h>
45677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$");
46677b542eSDavid E. O'Brien 
4777fe4438SBenno Rice #include "opt_ddb.h"
4867481196SJohn Birrell #include "opt_init_path.h"
4940244964SRobert Watson #include "opt_mac.h"
504bd49128SPeter Wemm 
51df8bae1dSRodney W. Grimes #include <sys/param.h>
529e209b12SAlfred Perlstein #include <sys/kernel.h>
53f36ba452SJake Burkholder #include <sys/exec.h>
54b3c5c18dSBruce Evans #include <sys/file.h>
55df8bae1dSRodney W. Grimes #include <sys/filedesc.h>
560384fff8SJason Evans #include <sys/ktr.h>
571005a129SJohn Baldwin #include <sys/lock.h>
58ac0ad63fSBruce Evans #include <sys/mount.h>
5935e0e5b3SJohn Baldwin #include <sys/mutex.h>
608f19eb88SIan Dowse #include <sys/syscallsubr.h>
61946bb7a2SPoul-Henning Kamp #include <sys/sysctl.h>
62df8bae1dSRodney W. Grimes #include <sys/proc.h>
63df8bae1dSRodney W. Grimes #include <sys/resourcevar.h>
64df8bae1dSRodney W. Grimes #include <sys/systm.h>
6536240ea5SDoug Rabson #include <sys/signalvar.h>
66df8bae1dSRodney W. Grimes #include <sys/vnode.h>
67f3f0ca60SSøren Schmidt #include <sys/sysent.h>
68df8bae1dSRodney W. Grimes #include <sys/reboot.h>
69de028f5aSJeff Roberson #include <sys/sched.h>
701005a129SJohn Baldwin #include <sys/sx.h>
71ad7507e2SSteven Wallace #include <sys/sysproto.h>
72efeaf95aSDavid Greenman #include <sys/vmmeter.h>
7374b2192aSJohn Dyson #include <sys/unistd.h>
7494e9d7c1SPeter Wemm #include <sys/malloc.h>
75db901281SPoul-Henning Kamp #include <sys/conf.h>
76df8bae1dSRodney W. Grimes 
77df8bae1dSRodney W. Grimes #include <machine/cpu.h>
78df8bae1dSRodney W. Grimes 
793683665bSRobert Watson #include <security/audit/audit.h>
80aed55708SRobert Watson #include <security/mac/mac_framework.h>
813683665bSRobert Watson 
82df8bae1dSRodney W. Grimes #include <vm/vm.h>
83efeaf95aSDavid Greenman #include <vm/vm_param.h>
84efeaf95aSDavid Greenman #include <vm/pmap.h>
85efeaf95aSDavid Greenman #include <vm/vm_map.h>
866faaa756SWolfram Schneider #include <sys/copyright.h>
87df8bae1dSRodney W. Grimes 
8826ab616fSBenno Rice #include <ddb/ddb.h>
8926ab616fSBenno Rice #include <ddb/db_sym.h>
9026ab616fSBenno Rice 
9137b087a6SPeter Wemm void mi_startup(void);				/* Should be elsewhere */
92df8bae1dSRodney W. Grimes 
93df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */
94154c04e5SPoul-Henning Kamp static struct session session0;
95154c04e5SPoul-Henning Kamp static struct pgrp pgrp0;
96df8bae1dSRodney W. Grimes struct	proc proc0;
974649e92bSJohn Baldwin struct	thread thread0 __aligned(16);
9823734995SJake Burkholder struct	vmspace vmspace0;
992b14f991SJulian Elischer struct	proc *initproc;
100df8bae1dSRodney W. Grimes 
101c463cf1cSBruce Evans int	boothowto = 0;		/* initialized so that it can be patched */
1028d0bf3d6SJordan K. Hubbard SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
1037a08bae6SJohn Baldwin int	bootverbose;
1047a08bae6SJohn Baldwin SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
105946bb7a2SPoul-Henning Kamp 
1062b14f991SJulian Elischer /*
1072b14f991SJulian Elischer  * This ensures that there is at least one entry so that the sysinit_set
1082b14f991SJulian Elischer  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
1092b14f991SJulian Elischer  * executed.
11026f9a767SRodney W. Grimes  */
1112b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
1128a129caeSDavid Greenman 
11394e9d7c1SPeter Wemm /*
11494e9d7c1SPeter Wemm  * The sysinit table itself.  Items are checked off as the are run.
11594e9d7c1SPeter Wemm  * If we want to register new sysinit types, add them to newsysinit.
11694e9d7c1SPeter Wemm  */
117f41325dbSPeter Wemm SET_DECLARE(sysinit_set, struct sysinit);
118f41325dbSPeter Wemm struct sysinit **sysinit, **sysinit_end;
119f41325dbSPeter Wemm struct sysinit **newsysinit, **newsysinit_end;
12094e9d7c1SPeter Wemm 
12194e9d7c1SPeter Wemm /*
12294e9d7c1SPeter Wemm  * Merge a new sysinit set into the current set, reallocating it if
12394e9d7c1SPeter Wemm  * necessary.  This can only be called after malloc is running.
12494e9d7c1SPeter Wemm  */
12594e9d7c1SPeter Wemm void
126f41325dbSPeter Wemm sysinit_add(struct sysinit **set, struct sysinit **set_end)
12794e9d7c1SPeter Wemm {
12894e9d7c1SPeter Wemm 	struct sysinit **newset;
12994e9d7c1SPeter Wemm 	struct sysinit **sipp;
13094e9d7c1SPeter Wemm 	struct sysinit **xipp;
131f41325dbSPeter Wemm 	int count;
13294e9d7c1SPeter Wemm 
133f41325dbSPeter Wemm 	count = set_end - set;
134ddd62546SPeter Wemm 	if (newsysinit)
135f41325dbSPeter Wemm 		count += newsysinit_end - newsysinit;
136ddd62546SPeter Wemm 	else
137f41325dbSPeter Wemm 		count += sysinit_end - sysinit;
13894e9d7c1SPeter Wemm 	newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
13994e9d7c1SPeter Wemm 	if (newset == NULL)
14094e9d7c1SPeter Wemm 		panic("cannot malloc for sysinit");
14194e9d7c1SPeter Wemm 	xipp = newset;
142ddd62546SPeter Wemm 	if (newsysinit)
143f41325dbSPeter Wemm 		for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
144ddd62546SPeter Wemm 			*xipp++ = *sipp;
145ddd62546SPeter Wemm 	else
146f41325dbSPeter Wemm 		for (sipp = sysinit; sipp < sysinit_end; sipp++)
14794e9d7c1SPeter Wemm 			*xipp++ = *sipp;
148f41325dbSPeter Wemm 	for (sipp = set; sipp < set_end; sipp++)
14994e9d7c1SPeter Wemm 		*xipp++ = *sipp;
150ddd62546SPeter Wemm 	if (newsysinit)
151ddd62546SPeter Wemm 		free(newsysinit, M_TEMP);
15294e9d7c1SPeter Wemm 	newsysinit = newset;
153f41325dbSPeter Wemm 	newsysinit_end = newset + count;
15494e9d7c1SPeter Wemm }
15526f9a767SRodney W. Grimes 
156df8bae1dSRodney W. Grimes /*
157df8bae1dSRodney W. Grimes  * System startup; initialize the world, create process 0, mount root
158df8bae1dSRodney W. Grimes  * filesystem, and fork to create init and pagedaemon.  Most of the
159df8bae1dSRodney W. Grimes  * hard work is done in the lower-level initialization routines including
160df8bae1dSRodney W. Grimes  * startup(), which does memory initialization and autoconfiguration.
1612b14f991SJulian Elischer  *
1622b14f991SJulian Elischer  * This allows simple addition of new kernel subsystems that require
1632b14f991SJulian Elischer  * boot time initialization.  It also allows substitution of subsystem
1642b14f991SJulian Elischer  * (for instance, a scheduler, kernel profiler, or VM system) by object
165c5b193bfSPoul-Henning Kamp  * module.  Finally, it allows for optional "kernel threads".
166df8bae1dSRodney W. Grimes  */
16726f9a767SRodney W. Grimes void
16837b087a6SPeter Wemm mi_startup(void)
169df8bae1dSRodney W. Grimes {
1702b14f991SJulian Elischer 
1712b14f991SJulian Elischer 	register struct sysinit **sipp;		/* system initialization*/
1722b14f991SJulian Elischer 	register struct sysinit **xipp;		/* interior loop of sort*/
1732b14f991SJulian Elischer 	register struct sysinit *save;		/* bubble*/
1742b14f991SJulian Elischer 
17526ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
17626ab616fSBenno Rice 	int last;
17726ab616fSBenno Rice 	int verbose;
17826ab616fSBenno Rice #endif
17926ab616fSBenno Rice 
180f41325dbSPeter Wemm 	if (sysinit == NULL) {
181f41325dbSPeter Wemm 		sysinit = SET_BEGIN(sysinit_set);
182f41325dbSPeter Wemm 		sysinit_end = SET_LIMIT(sysinit_set);
183f41325dbSPeter Wemm 	}
184f41325dbSPeter Wemm 
18594e9d7c1SPeter Wemm restart:
1862b14f991SJulian Elischer 	/*
1872b14f991SJulian Elischer 	 * Perform a bubble sort of the system initialization objects by
1882b14f991SJulian Elischer 	 * their subsystem (primary key) and order (secondary key).
1892b14f991SJulian Elischer 	 */
190f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
191f41325dbSPeter Wemm 		for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
1922b14f991SJulian Elischer 			if ((*sipp)->subsystem < (*xipp)->subsystem ||
1932b14f991SJulian Elischer 			     ((*sipp)->subsystem == (*xipp)->subsystem &&
194af4b2d2dSPeter Wemm 			      (*sipp)->order <= (*xipp)->order))
1952b14f991SJulian Elischer 				continue;	/* skip*/
1962b14f991SJulian Elischer 			save = *sipp;
1972b14f991SJulian Elischer 			*sipp = *xipp;
1982b14f991SJulian Elischer 			*xipp = save;
1992b14f991SJulian Elischer 		}
2002b14f991SJulian Elischer 	}
2012b14f991SJulian Elischer 
20226ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
20326ab616fSBenno Rice 	last = SI_SUB_COPYRIGHT;
20426ab616fSBenno Rice 	verbose = 0;
20526ab616fSBenno Rice #if !defined(DDB)
20626ab616fSBenno Rice 	printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n");
20726ab616fSBenno Rice #endif
20826ab616fSBenno Rice #endif
20926ab616fSBenno Rice 
2102b14f991SJulian Elischer 	/*
2112b14f991SJulian Elischer 	 * Traverse the (now) ordered list of system initialization tasks.
2122b14f991SJulian Elischer 	 * Perform each task, and continue on to the next task.
2132b14f991SJulian Elischer 	 *
2142b14f991SJulian Elischer 	 * The last item on the list is expected to be the scheduler,
2152b14f991SJulian Elischer 	 * which will not return.
2162b14f991SJulian Elischer 	 */
217f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
21874b2192aSJohn Dyson 
2192b14f991SJulian Elischer 		if ((*sipp)->subsystem == SI_SUB_DUMMY)
2202b14f991SJulian Elischer 			continue;	/* skip dummy task(s)*/
2212b14f991SJulian Elischer 
22294e9d7c1SPeter Wemm 		if ((*sipp)->subsystem == SI_SUB_DONE)
22394e9d7c1SPeter Wemm 			continue;
22494e9d7c1SPeter Wemm 
22526ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
22626ab616fSBenno Rice 		if ((*sipp)->subsystem > last) {
22726ab616fSBenno Rice 			verbose = 1;
22826ab616fSBenno Rice 			last = (*sipp)->subsystem;
22926ab616fSBenno Rice 			printf("subsystem %x\n", last);
23026ab616fSBenno Rice 		}
23126ab616fSBenno Rice 		if (verbose) {
23226ab616fSBenno Rice #if defined(DDB)
23326ab616fSBenno Rice 			const char *name;
23426ab616fSBenno Rice 			c_db_sym_t sym;
23526ab616fSBenno Rice 			db_expr_t  offset;
23626ab616fSBenno Rice 
23726ab616fSBenno Rice 			sym = db_search_symbol((vm_offset_t)(*sipp)->func,
23826ab616fSBenno Rice 			    DB_STGY_PROC, &offset);
23926ab616fSBenno Rice 			db_symbol_values(sym, &name, NULL);
24026ab616fSBenno Rice 			if (name != NULL)
24126ab616fSBenno Rice 				printf("   %s(%p)... ", name, (*sipp)->udata);
24226ab616fSBenno Rice 			else
24326ab616fSBenno Rice #endif
24426ab616fSBenno Rice 				printf("   %p(%p)... ", (*sipp)->func,
24526ab616fSBenno Rice 				    (*sipp)->udata);
24626ab616fSBenno Rice 		}
24726ab616fSBenno Rice #endif
24826ab616fSBenno Rice 
2499c8b8baaSPeter Wemm 		/* Call function */
2502b14f991SJulian Elischer 		(*((*sipp)->func))((*sipp)->udata);
25194e9d7c1SPeter Wemm 
25226ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
25326ab616fSBenno Rice 		if (verbose)
25426ab616fSBenno Rice 			printf("done.\n");
25526ab616fSBenno Rice #endif
25626ab616fSBenno Rice 
25794e9d7c1SPeter Wemm 		/* Check off the one we're just done */
25894e9d7c1SPeter Wemm 		(*sipp)->subsystem = SI_SUB_DONE;
25994e9d7c1SPeter Wemm 
26094e9d7c1SPeter Wemm 		/* Check if we've installed more sysinit items via KLD */
26194e9d7c1SPeter Wemm 		if (newsysinit != NULL) {
262f41325dbSPeter Wemm 			if (sysinit != SET_BEGIN(sysinit_set))
26394e9d7c1SPeter Wemm 				free(sysinit, M_TEMP);
26494e9d7c1SPeter Wemm 			sysinit = newsysinit;
265f41325dbSPeter Wemm 			sysinit_end = newsysinit_end;
26694e9d7c1SPeter Wemm 			newsysinit = NULL;
267f41325dbSPeter Wemm 			newsysinit_end = NULL;
26894e9d7c1SPeter Wemm 			goto restart;
26994e9d7c1SPeter Wemm 		}
2702b14f991SJulian Elischer 	}
2712b14f991SJulian Elischer 
272477a642cSPeter Wemm 	panic("Shouldn't get here!");
2732b14f991SJulian Elischer 	/* NOTREACHED*/
2742b14f991SJulian Elischer }
2752b14f991SJulian Elischer 
2762b14f991SJulian Elischer 
2772b14f991SJulian Elischer /*
2782b14f991SJulian Elischer  ***************************************************************************
2792b14f991SJulian Elischer  ****
2802b14f991SJulian Elischer  **** The following SYSINIT's belong elsewhere, but have not yet
2812b14f991SJulian Elischer  **** been moved.
2822b14f991SJulian Elischer  ****
2832b14f991SJulian Elischer  ***************************************************************************
2842b14f991SJulian Elischer  */
2859ef6c28aSBruce Evans static void
28637b087a6SPeter Wemm print_caddr_t(void *data __unused)
2879ef6c28aSBruce Evans {
2889ef6c28aSBruce Evans 	printf("%s", (char *)data);
2899ef6c28aSBruce Evans }
290d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
2915add74b4SRobert Watson SYSINIT(trademark, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, trademark)
2925add74b4SRobert Watson SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_THIRD, print_caddr_t, version)
2937a08bae6SJohn Baldwin 
2942cf6bdacSPoul-Henning Kamp #ifdef WITNESS
2952cf6bdacSPoul-Henning Kamp static char wit_warn[] =
2962cf6bdacSPoul-Henning Kamp      "WARNING: WITNESS option enabled, expect reduced performance.\n";
2975add74b4SRobert Watson SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
2982cf6bdacSPoul-Henning Kamp    print_caddr_t, wit_warn)
2992cf6bdacSPoul-Henning Kamp #endif
3002cf6bdacSPoul-Henning Kamp 
3012cf6bdacSPoul-Henning Kamp #ifdef DIAGNOSTIC
3022cf6bdacSPoul-Henning Kamp static char diag_warn[] =
3032cf6bdacSPoul-Henning Kamp      "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
30488b85279SRobert Watson SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2,
3052cf6bdacSPoul-Henning Kamp     print_caddr_t, diag_warn)
3062cf6bdacSPoul-Henning Kamp #endif
3072cf6bdacSPoul-Henning Kamp 
3087a08bae6SJohn Baldwin static void
3097a08bae6SJohn Baldwin set_boot_verbose(void *data __unused)
3107a08bae6SJohn Baldwin {
3117a08bae6SJohn Baldwin 
3127a08bae6SJohn Baldwin 	if (boothowto & RB_VERBOSE)
3137a08bae6SJohn Baldwin 		bootverbose++;
3147a08bae6SJohn Baldwin }
3157a08bae6SJohn Baldwin SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL)
3162b14f991SJulian Elischer 
317f36ba452SJake Burkholder struct sysentvec null_sysvec = {
318f36ba452SJake Burkholder 	0,
319f36ba452SJake Burkholder 	NULL,
320f36ba452SJake Burkholder 	0,
321f36ba452SJake Burkholder 	0,
322f36ba452SJake Burkholder 	NULL,
323f36ba452SJake Burkholder 	0,
324f36ba452SJake Burkholder 	NULL,
325f36ba452SJake Burkholder 	NULL,
326f36ba452SJake Burkholder 	NULL,
327f36ba452SJake Burkholder 	NULL,
328f36ba452SJake Burkholder 	NULL,
329f36ba452SJake Burkholder 	NULL,
330f36ba452SJake Burkholder 	NULL,
331f36ba452SJake Burkholder 	"null",
332f36ba452SJake Burkholder 	NULL,
333f36ba452SJake Burkholder 	NULL,
334f36ba452SJake Burkholder 	0,
335f36ba452SJake Burkholder 	PAGE_SIZE,
336f36ba452SJake Burkholder 	VM_MIN_ADDRESS,
337f36ba452SJake Burkholder 	VM_MAXUSER_ADDRESS,
338f36ba452SJake Burkholder 	USRSTACK,
339f36ba452SJake Burkholder 	PS_STRINGS,
340f36ba452SJake Burkholder 	VM_PROT_ALL,
341f36ba452SJake Burkholder 	NULL,
342c460ac3aSPeter Wemm 	NULL,
343f36ba452SJake Burkholder 	NULL
344f36ba452SJake Burkholder };
3453ebc1248SPeter Wemm 
3462b14f991SJulian Elischer /*
3472b14f991SJulian Elischer  ***************************************************************************
3482b14f991SJulian Elischer  ****
3490c920c0dSGiorgos Keramidas  **** The two following SYSINIT's are proc0 specific glue code.  I am not
3502b14f991SJulian Elischer  **** convinced that they can not be safely combined, but their order of
3512b14f991SJulian Elischer  **** operation has been maintained as the same as the original init_main.c
3522b14f991SJulian Elischer  **** for right now.
3532b14f991SJulian Elischer  ****
3542b14f991SJulian Elischer  **** These probably belong in init_proc.c or kern_proc.c, since they
3552b14f991SJulian Elischer  **** deal with proc0 (the fork template process).
3562b14f991SJulian Elischer  ****
3572b14f991SJulian Elischer  ***************************************************************************
3582b14f991SJulian Elischer  */
3592b14f991SJulian Elischer /* ARGSUSED*/
360154c04e5SPoul-Henning Kamp static void
36137b087a6SPeter Wemm proc0_init(void *dummy __unused)
3622b14f991SJulian Elischer {
3638ec21e3aSPoul-Henning Kamp 	struct proc *p;
3648ec21e3aSPoul-Henning Kamp 	unsigned i;
365b40ce416SJulian Elischer 	struct thread *td;
366df8bae1dSRodney W. Grimes 
3670cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
368df8bae1dSRodney W. Grimes 	p = &proc0;
369079b7badSJulian Elischer 	td = &thread0;
370df8bae1dSRodney W. Grimes 
371df8bae1dSRodney W. Grimes 	/*
3720384fff8SJason Evans 	 * Initialize magic number.
3730384fff8SJason Evans 	 */
3740384fff8SJason Evans 	p->p_magic = P_MAGIC;
3750384fff8SJason Evans 
3768460a577SJohn Birrell 	/*
3778460a577SJohn Birrell 	 * Initialize thread and process structures.
3788460a577SJohn Birrell 	 */
3798460a577SJohn Birrell 	procinit();	/* set up proc zone */
3808460a577SJohn Birrell 	threadinit();	/* set up UMA zones */
3818460a577SJohn Birrell 
3828460a577SJohn Birrell 	/*
3838460a577SJohn Birrell 	 * Initialise scheduler resources.
3848460a577SJohn Birrell 	 * Add scheduler specific parts to proc, thread as needed.
3858460a577SJohn Birrell 	 */
386ed062c8dSJulian Elischer 	schedinit();	/* scheduler gets its house in order */
387ed062c8dSJulian Elischer 	/*
388b1508c72SDavid Greenman 	 * Initialize sleep queue hash table
389b1508c72SDavid Greenman 	 */
390b1508c72SDavid Greenman 	sleepinit();
391b1508c72SDavid Greenman 
392b1508c72SDavid Greenman 	/*
3933075778bSJohn Dyson 	 * additional VM structures
3943075778bSJohn Dyson 	 */
3953075778bSJohn Dyson 	vm_init2();
3963075778bSJohn Dyson 
3973075778bSJohn Dyson 	/*
398df8bae1dSRodney W. Grimes 	 * Create process 0 (the swapper).
399df8bae1dSRodney W. Grimes 	 */
400a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&allproc, p, p_list);
4017b531e60SJohn Baldwin 	LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
4026008862bSJohn Baldwin 	mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
403df8bae1dSRodney W. Grimes 	p->p_pgrp = &pgrp0;
404a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
405a3bfb996SJeffrey Hsu 	LIST_INIT(&pgrp0.pg_members);
406a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
407a3bfb996SJeffrey Hsu 
408df8bae1dSRodney W. Grimes 	pgrp0.pg_session = &session0;
4096008862bSJohn Baldwin 	mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
410df8bae1dSRodney W. Grimes 	session0.s_count = 1;
411df8bae1dSRodney W. Grimes 	session0.s_leader = p;
412df8bae1dSRodney W. Grimes 
4133ebc1248SPeter Wemm 	p->p_sysent = &null_sysvec;
414f202965eSJohn Baldwin 	p->p_flag = P_SYSTEM;
415f202965eSJohn Baldwin 	p->p_sflag = PS_INMEM;
416e602ba25SJulian Elischer 	p->p_state = PRS_NORMAL;
417571dcd15SSuleiman Souhlal 	knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL);
4182c255e9dSRobert Watson 	STAILQ_INIT(&p->p_ktr);
419fa885116SJulian Elischer 	p->p_nice = NZERO;
420e602ba25SJulian Elischer 	td->td_state = TDS_RUNNING;
4218460a577SJohn Birrell 	td->td_pri_class = PRI_TIMESHARE;
4228460a577SJohn Birrell 	td->td_user_pri = PUSER;
42360d48235SDavid Xu 	td->td_base_user_pri = PUSER;
4242c100766SJulian Elischer 	td->td_priority = PVM;
4252c100766SJulian Elischer 	td->td_base_pri = PUSER;
426060563ecSJulian Elischer 	td->td_oncpu = 0;
4272c1011f7SJohn Dyson 	p->p_peers = 0;
4282c1011f7SJohn Dyson 	p->p_leader = p;
429e602ba25SJulian Elischer 
4302c1011f7SJohn Dyson 
431df8bae1dSRodney W. Grimes 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
432df8bae1dSRodney W. Grimes 
433c06eb4e2SSam Leffler 	callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
4341c4bcd05SJeff Roberson 	callout_init_mtx(&p->p_limco, &p->p_mtx, 0);
435c06eb4e2SSam Leffler 	callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
4364f559836SJake Burkholder 
437df8bae1dSRodney W. Grimes 	/* Create credentials. */
438df8bae1dSRodney W. Grimes 	p->p_ucred = crget();
439df8bae1dSRodney W. Grimes 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
440f535380cSDon Lewis 	p->p_ucred->cr_uidinfo = uifind(0);
441b1fc0ec1SRobert Watson 	p->p_ucred->cr_ruidinfo = uifind(0);
44291421ba2SRobert Watson 	p->p_ucred->cr_prison = NULL;	/* Don't jail it. */
4433683665bSRobert Watson #ifdef AUDIT
4443683665bSRobert Watson 	audit_proc_alloc(p);
4453683665bSRobert Watson 	audit_proc_kproc0(p);
4463683665bSRobert Watson #endif
44740244964SRobert Watson #ifdef MAC
44840244964SRobert Watson 	mac_create_proc0(p->p_ucred);
44940244964SRobert Watson #endif
4508e2e767bSJohn Baldwin 	td->td_ucred = crhold(p->p_ucred);
45175c13541SPoul-Henning Kamp 
45290af4afaSJohn Baldwin 	/* Create sigacts. */
45390af4afaSJohn Baldwin 	p->p_sigacts = sigacts_alloc();
4546626c604SJulian Elischer 
45537b087a6SPeter Wemm 	/* Initialize signal state for process 0. */
45637b087a6SPeter Wemm 	siginit(&proc0);
45737b087a6SPeter Wemm 
458df8bae1dSRodney W. Grimes 	/* Create the file descriptor table. */
4598ec21e3aSPoul-Henning Kamp 	p->p_fd = fdinit(NULL);
460ad05d580STor Egge 	p->p_fdtol = NULL;
461df8bae1dSRodney W. Grimes 
462df8bae1dSRodney W. Grimes 	/* Create the limits structures. */
46391d5354aSJohn Baldwin 	p->p_limit = lim_alloc();
46491d5354aSJohn Baldwin 	for (i = 0; i < RLIM_NLIMITS; i++)
46591d5354aSJohn Baldwin 		p->p_limit->pl_rlimit[i].rlim_cur =
46691d5354aSJohn Baldwin 		    p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
46791d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
46891d5354aSJohn Baldwin 	    p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
46991d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
47091d5354aSJohn Baldwin 	    p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
4712feb50bfSAttilio Rao 	i = ptoa(cnt.v_free_count);
47291d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i;
47391d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
47491d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
4755715307fSJohn Baldwin 	p->p_cpulimit = RLIM_INFINITY;
476df8bae1dSRodney W. Grimes 
4778b059651SDavid Schultz 	p->p_stats = pstats_alloc();
4788b059651SDavid Schultz 
479df8bae1dSRodney W. Grimes 	/* Allocate a prototype map so we have something to fork. */
480b1028ad1SLuoqi Chen 	pmap_pinit0(vmspace_pmap(&vmspace0));
481df8bae1dSRodney W. Grimes 	p->p_vmspace = &vmspace0;
482df8bae1dSRodney W. Grimes 	vmspace0.vm_refcnt = 1;
48305ba50f5SJake Burkholder 	vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
48405ba50f5SJake Burkholder 	    p->p_sysent->sv_maxuser);
485b1028ad1SLuoqi Chen 	vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
486df8bae1dSRodney W. Grimes 
48739fb8e6bSJulian Elischer 	/*
488a3bfb996SJeffrey Hsu 	 * Charge root for one process.
489df8bae1dSRodney W. Grimes 	 */
490b1fc0ec1SRobert Watson 	(void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
49126f9a767SRodney W. Grimes }
4922b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
4932b14f991SJulian Elischer 
4942b14f991SJulian Elischer /* ARGSUSED*/
495154c04e5SPoul-Henning Kamp static void
49637b087a6SPeter Wemm proc0_post(void *dummy __unused)
4972b14f991SJulian Elischer {
49800af9731SPoul-Henning Kamp 	struct timespec ts;
49937b087a6SPeter Wemm 	struct proc *p;
500a6fc8288SPeter Wemm 
5012b14f991SJulian Elischer 	/*
5021b0b259eSBruce Evans 	 * Now we can look at the time, having had a chance to verify the
5031b0b259eSBruce Evans 	 * time from the filesystem.  Pretend that proc0 started now.
5042b14f991SJulian Elischer 	 */
5051005a129SJohn Baldwin 	sx_slock(&allproc_lock);
5064f506694SXin LI 	FOREACH_PROC_IN_SYSTEM(p) {
50787ccef7bSDag-Erling Smørgrav 		microuptime(&p->p_stats->p_start);
5085b1a8eb3SPoul-Henning Kamp 		p->p_rux.rux_runtime = 0;
50937b087a6SPeter Wemm 	}
5101005a129SJohn Baldwin 	sx_sunlock(&allproc_lock);
5115b1a8eb3SPoul-Henning Kamp 	PCPU_SET(switchtime, cpu_ticks());
5120384fff8SJason Evans 	PCPU_SET(switchticks, ticks);
5132b14f991SJulian Elischer 
514a6fc8288SPeter Wemm 	/*
515a6fc8288SPeter Wemm 	 * Give the ``random'' number generator a thump.
516a6fc8288SPeter Wemm 	 */
51700af9731SPoul-Henning Kamp 	nanotime(&ts);
51800af9731SPoul-Henning Kamp 	srandom(ts.tv_sec ^ ts.tv_nsec);
5192b14f991SJulian Elischer }
5202b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
5212b14f991SJulian Elischer 
522df8bae1dSRodney W. Grimes /*
5232b14f991SJulian Elischer  ***************************************************************************
5242b14f991SJulian Elischer  ****
5252b14f991SJulian Elischer  **** The following SYSINIT's and glue code should be moved to the
5262b14f991SJulian Elischer  **** respective files on a per subsystem basis.
5272b14f991SJulian Elischer  ****
5282b14f991SJulian Elischer  ***************************************************************************
529df8bae1dSRodney W. Grimes  */
530df8bae1dSRodney W. Grimes 
531df8bae1dSRodney W. Grimes 
532df8bae1dSRodney W. Grimes /*
5332b14f991SJulian Elischer  ***************************************************************************
5342b14f991SJulian Elischer  ****
5352b14f991SJulian Elischer  **** The following code probably belongs in another file, like
53637b087a6SPeter Wemm  **** kern/init_init.c.
5372b14f991SJulian Elischer  ****
5382b14f991SJulian Elischer  ***************************************************************************
539df8bae1dSRodney W. Grimes  */
540df8bae1dSRodney W. Grimes 
541df8bae1dSRodney W. Grimes /*
542df8bae1dSRodney W. Grimes  * List of paths to try when searching for "init".
543df8bae1dSRodney W. Grimes  */
5445f967b24SDag-Erling Smørgrav static char init_path[MAXPATHLEN] =
54567481196SJohn Birrell #ifdef	INIT_PATH
54667481196SJohn Birrell     __XSTRING(INIT_PATH);
54767481196SJohn Birrell #else
548f3f4baf0SDag-Erling Smørgrav     "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall";
54967481196SJohn Birrell #endif
550af1408e3SLuigi Rizzo SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
551af1408e3SLuigi Rizzo 	"Path used to search the init process");
552df8bae1dSRodney W. Grimes 
553df8bae1dSRodney W. Grimes /*
554724447acSRalf S. Engelschall  * Shutdown timeout of init(8).
555724447acSRalf S. Engelschall  * Unused within kernel, but used to control init(8), hence do not remove.
556724447acSRalf S. Engelschall  */
557724447acSRalf S. Engelschall #ifndef INIT_SHUTDOWN_TIMEOUT
558724447acSRalf S. Engelschall #define INIT_SHUTDOWN_TIMEOUT 120
559724447acSRalf S. Engelschall #endif
560724447acSRalf S. Engelschall static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT;
561724447acSRalf S. Engelschall SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
562724447acSRalf S. Engelschall 	CTLFLAG_RW, &init_shutdown_timeout, 0, "");
563724447acSRalf S. Engelschall 
564724447acSRalf S. Engelschall /*
5655f967b24SDag-Erling Smørgrav  * Start the initial user process; try exec'ing each pathname in init_path.
566df8bae1dSRodney W. Grimes  * The program is invoked with one argument containing the boot flags.
567df8bae1dSRodney W. Grimes  */
568df8bae1dSRodney W. Grimes static void
56937b087a6SPeter Wemm start_init(void *dummy)
570df8bae1dSRodney W. Grimes {
571df8bae1dSRodney W. Grimes 	vm_offset_t addr;
572df8bae1dSRodney W. Grimes 	struct execve_args args;
5735f967b24SDag-Erling Smørgrav 	int options, error;
5745f967b24SDag-Erling Smørgrav 	char *var, *path, *next, *s;
5755f967b24SDag-Erling Smørgrav 	char *ucp, **uap, *arg0, *arg1;
576b40ce416SJulian Elischer 	struct thread *td;
5779c8b8baaSPeter Wemm 	struct proc *p;
578df8bae1dSRodney W. Grimes 
5799ed346baSBosko Milekic 	mtx_lock(&Giant);
5800384fff8SJason Evans 
5810cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
5820cddd8f0SMatthew Dillon 
583b40ce416SJulian Elischer 	td = curthread;
584b40ce416SJulian Elischer 	p = td->td_proc;
585df8bae1dSRodney W. Grimes 
586563af2ecSMaxime Henrion 	vfs_mountroot();
587fb92273bSPoul-Henning Kamp 
588b7116168SPeter Wemm 	/*
589df8bae1dSRodney W. Grimes 	 * Need just enough stack to hold the faked-up "execve()" arguments.
590df8bae1dSRodney W. Grimes 	 */
59105ba50f5SJake Burkholder 	addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
5925f967b24SDag-Erling Smørgrav 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
5935f967b24SDag-Erling Smørgrav 			FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
594df8bae1dSRodney W. Grimes 		panic("init: couldn't allocate argument space");
595df8bae1dSRodney W. Grimes 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
59626f9a767SRodney W. Grimes 	p->p_vmspace->vm_ssize = 1;
597df8bae1dSRodney W. Grimes 
5985f967b24SDag-Erling Smørgrav 	if ((var = getenv("init_path")) != NULL) {
599e80fb434SRobert Drehmel 		strlcpy(init_path, var, sizeof(init_path));
600d786139cSMaxime Henrion 		freeenv(var);
6015f967b24SDag-Erling Smørgrav 	}
6025f967b24SDag-Erling Smørgrav 
60367481196SJohn Birrell 	for (path = init_path; *path != '\0'; path = next) {
604e4082284SJohn Birrell 		while (*path == ':')
6055f967b24SDag-Erling Smørgrav 			path++;
60667481196SJohn Birrell 		if (*path == '\0')
6075f967b24SDag-Erling Smørgrav 			break;
608e4082284SJohn Birrell 		for (next = path; *next != '\0' && *next != ':'; next++)
6095f967b24SDag-Erling Smørgrav 			/* nothing */ ;
6105f967b24SDag-Erling Smørgrav 		if (bootverbose)
611ba41a07dSDmitrij Tejblum 			printf("start_init: trying %.*s\n", (int)(next - path),
612ba41a07dSDmitrij Tejblum 			    path);
6135f967b24SDag-Erling Smørgrav 
614df8bae1dSRodney W. Grimes 		/*
615df8bae1dSRodney W. Grimes 		 * Move out the boot flag argument.
616df8bae1dSRodney W. Grimes 		 */
617df8bae1dSRodney W. Grimes 		options = 0;
61805ba50f5SJake Burkholder 		ucp = (char *)p->p_sysent->sv_usrstack;
619df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, 0);		/* trailing zero */
620df8bae1dSRodney W. Grimes 		if (boothowto & RB_SINGLE) {
621df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 's');
622df8bae1dSRodney W. Grimes 			options = 1;
623df8bae1dSRodney W. Grimes 		}
624df8bae1dSRodney W. Grimes #ifdef notyet
625df8bae1dSRodney W. Grimes                 if (boothowto & RB_FASTBOOT) {
626df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 'f');
627df8bae1dSRodney W. Grimes 			options = 1;
628df8bae1dSRodney W. Grimes 		}
629df8bae1dSRodney W. Grimes #endif
63017755ac8SPoul-Henning Kamp 
63117755ac8SPoul-Henning Kamp #ifdef BOOTCDROM
63217755ac8SPoul-Henning Kamp 		(void)subyte(--ucp, 'C');
63317755ac8SPoul-Henning Kamp 		options = 1;
63417755ac8SPoul-Henning Kamp #endif
635db901281SPoul-Henning Kamp 
636df8bae1dSRodney W. Grimes 		if (options == 0)
637df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, '-');
638df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, '-');		/* leading hyphen */
639df8bae1dSRodney W. Grimes 		arg1 = ucp;
640df8bae1dSRodney W. Grimes 
641df8bae1dSRodney W. Grimes 		/*
642df8bae1dSRodney W. Grimes 		 * Move out the file name (also arg 0).
643df8bae1dSRodney W. Grimes 		 */
6445f967b24SDag-Erling Smørgrav 		(void)subyte(--ucp, 0);
6455f967b24SDag-Erling Smørgrav 		for (s = next - 1; s >= path; s--)
6465f967b24SDag-Erling Smørgrav 			(void)subyte(--ucp, *s);
647df8bae1dSRodney W. Grimes 		arg0 = ucp;
648df8bae1dSRodney W. Grimes 
649df8bae1dSRodney W. Grimes 		/*
650df8bae1dSRodney W. Grimes 		 * Move out the arg pointers.
651df8bae1dSRodney W. Grimes 		 */
652a20d7755SDoug Rabson 		uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
653c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)0);	/* terminator */
654c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
655c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
656df8bae1dSRodney W. Grimes 
657df8bae1dSRodney W. Grimes 		/*
658df8bae1dSRodney W. Grimes 		 * Point at the arguments.
659df8bae1dSRodney W. Grimes 		 */
660df8bae1dSRodney W. Grimes 		args.fname = arg0;
66126f9a767SRodney W. Grimes 		args.argv = uap;
66226f9a767SRodney W. Grimes 		args.envv = NULL;
663df8bae1dSRodney W. Grimes 
664df8bae1dSRodney W. Grimes 		/*
665df8bae1dSRodney W. Grimes 		 * Now try to exec the program.  If can't for any reason
666df8bae1dSRodney W. Grimes 		 * other than it doesn't exist, complain.
6672b14f991SJulian Elischer 		 *
66837b087a6SPeter Wemm 		 * Otherwise, return via fork_trampoline() all the way
6699c8b8baaSPeter Wemm 		 * to user mode as init!
670df8bae1dSRodney W. Grimes 		 */
671b40ce416SJulian Elischer 		if ((error = execve(td, &args)) == 0) {
6729ed346baSBosko Milekic 			mtx_unlock(&Giant);
673df8bae1dSRodney W. Grimes 			return;
674db72809dSJohn Baldwin 		}
675df8bae1dSRodney W. Grimes 		if (error != ENOENT)
676ba41a07dSDmitrij Tejblum 			printf("exec %.*s: error %d\n", (int)(next - path),
677ba41a07dSDmitrij Tejblum 			    path, error);
678df8bae1dSRodney W. Grimes 	}
679580e7e5aSGreg Lehey 	printf("init: not found in path %s\n", init_path);
680df8bae1dSRodney W. Grimes 	panic("no init");
681df8bae1dSRodney W. Grimes }
68237b087a6SPeter Wemm 
68337b087a6SPeter Wemm /*
68437b087a6SPeter Wemm  * Like kthread_create(), but runs in it's own address space.
68537b087a6SPeter Wemm  * We do this early to reserve pid 1.
68637b087a6SPeter Wemm  *
68737b087a6SPeter Wemm  * Note special case - do not make it runnable yet.  Other work
68837b087a6SPeter Wemm  * in progress will change this more.
68937b087a6SPeter Wemm  */
69037b087a6SPeter Wemm static void
69137b087a6SPeter Wemm create_init(const void *udata __unused)
69237b087a6SPeter Wemm {
6935a06cb0cSRobert Watson 	struct ucred *newcred, *oldcred;
69437b087a6SPeter Wemm 	int error;
69537b087a6SPeter Wemm 
696316ec49aSScott Long 	error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
69737b087a6SPeter Wemm 	if (error)
69837b087a6SPeter Wemm 		panic("cannot fork init: %d\n", error);
699bafc8f25SRobert Watson 	KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
7005a06cb0cSRobert Watson 	/* divorce init's credentials from the kernel's */
7015a06cb0cSRobert Watson 	newcred = crget();
702f202965eSJohn Baldwin 	PROC_LOCK(initproc);
703f202965eSJohn Baldwin 	initproc->p_flag |= P_SYSTEM;
7045a06cb0cSRobert Watson 	oldcred = initproc->p_ucred;
7055a06cb0cSRobert Watson 	crcopy(newcred, oldcred);
70640244964SRobert Watson #ifdef MAC
70740244964SRobert Watson 	mac_create_proc1(newcred);
70840244964SRobert Watson #endif
7093683665bSRobert Watson #ifdef AUDIT
7103683665bSRobert Watson 	audit_proc_init(initproc);
7113683665bSRobert Watson #endif
7125a06cb0cSRobert Watson 	initproc->p_ucred = newcred;
713f202965eSJohn Baldwin 	PROC_UNLOCK(initproc);
7145a06cb0cSRobert Watson 	crfree(oldcred);
7154d1a4bb7SRobert Watson 	cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
7169ed346baSBosko Milekic 	mtx_lock_spin(&sched_lock);
717f202965eSJohn Baldwin 	initproc->p_sflag |= PS_INMEM;
7189ed346baSBosko Milekic 	mtx_unlock_spin(&sched_lock);
719079b7badSJulian Elischer 	cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
72037b087a6SPeter Wemm }
72137b087a6SPeter Wemm SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
72237b087a6SPeter Wemm 
72337b087a6SPeter Wemm /*
72437b087a6SPeter Wemm  * Make it runnable now.
72537b087a6SPeter Wemm  */
72637b087a6SPeter Wemm static void
72737b087a6SPeter Wemm kick_init(const void *udata __unused)
72837b087a6SPeter Wemm {
729079b7badSJulian Elischer 	struct thread *td;
730f202965eSJohn Baldwin 
731079b7badSJulian Elischer 	td = FIRST_THREAD_IN_PROC(initproc);
7329ed346baSBosko Milekic 	mtx_lock_spin(&sched_lock);
73371fad9fdSJulian Elischer 	TD_SET_CAN_RUN(td);
734f0393f06SJeff Roberson 	sched_add(td, SRQ_BORING);
7359ed346baSBosko Milekic 	mtx_unlock_spin(&sched_lock);
73637b087a6SPeter Wemm }
73737b087a6SPeter Wemm SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)
738