xref: /freebsd/sys/kern/init_main.c (revision bc093719ca478fe10b938cef32c30b528042cbcd)
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>
76d7f687fcSJeff Roberson #include <sys/cpuset.h>
77df8bae1dSRodney W. Grimes 
78df8bae1dSRodney W. Grimes #include <machine/cpu.h>
79df8bae1dSRodney W. Grimes 
803683665bSRobert Watson #include <security/audit/audit.h>
81aed55708SRobert Watson #include <security/mac/mac_framework.h>
823683665bSRobert Watson 
83df8bae1dSRodney W. Grimes #include <vm/vm.h>
84efeaf95aSDavid Greenman #include <vm/vm_param.h>
85efeaf95aSDavid Greenman #include <vm/pmap.h>
86efeaf95aSDavid Greenman #include <vm/vm_map.h>
876faaa756SWolfram Schneider #include <sys/copyright.h>
88df8bae1dSRodney W. Grimes 
8926ab616fSBenno Rice #include <ddb/ddb.h>
9026ab616fSBenno Rice #include <ddb/db_sym.h>
9126ab616fSBenno Rice 
9237b087a6SPeter Wemm void mi_startup(void);				/* Should be elsewhere */
93df8bae1dSRodney W. Grimes 
94df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */
95154c04e5SPoul-Henning Kamp static struct session session0;
96154c04e5SPoul-Henning Kamp static struct pgrp pgrp0;
97df8bae1dSRodney W. Grimes struct	proc proc0;
984649e92bSJohn Baldwin struct	thread thread0 __aligned(16);
9923734995SJake Burkholder struct	vmspace vmspace0;
1002b14f991SJulian Elischer struct	proc *initproc;
101df8bae1dSRodney W. Grimes 
102c463cf1cSBruce Evans int	boothowto = 0;		/* initialized so that it can be patched */
1038d0bf3d6SJordan K. Hubbard SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
1047a08bae6SJohn Baldwin int	bootverbose;
1057a08bae6SJohn Baldwin SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
106946bb7a2SPoul-Henning Kamp 
1072b14f991SJulian Elischer /*
1082b14f991SJulian Elischer  * This ensures that there is at least one entry so that the sysinit_set
1092b14f991SJulian Elischer  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
1102b14f991SJulian Elischer  * executed.
11126f9a767SRodney W. Grimes  */
112237fdd78SRobert Watson SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL);
1138a129caeSDavid Greenman 
11494e9d7c1SPeter Wemm /*
11594e9d7c1SPeter Wemm  * The sysinit table itself.  Items are checked off as the are run.
11694e9d7c1SPeter Wemm  * If we want to register new sysinit types, add them to newsysinit.
11794e9d7c1SPeter Wemm  */
118f41325dbSPeter Wemm SET_DECLARE(sysinit_set, struct sysinit);
119f41325dbSPeter Wemm struct sysinit **sysinit, **sysinit_end;
120f41325dbSPeter Wemm struct sysinit **newsysinit, **newsysinit_end;
12194e9d7c1SPeter Wemm 
12294e9d7c1SPeter Wemm /*
12394e9d7c1SPeter Wemm  * Merge a new sysinit set into the current set, reallocating it if
12494e9d7c1SPeter Wemm  * necessary.  This can only be called after malloc is running.
12594e9d7c1SPeter Wemm  */
12694e9d7c1SPeter Wemm void
127f41325dbSPeter Wemm sysinit_add(struct sysinit **set, struct sysinit **set_end)
12894e9d7c1SPeter Wemm {
12994e9d7c1SPeter Wemm 	struct sysinit **newset;
13094e9d7c1SPeter Wemm 	struct sysinit **sipp;
13194e9d7c1SPeter Wemm 	struct sysinit **xipp;
132f41325dbSPeter Wemm 	int count;
13394e9d7c1SPeter Wemm 
134f41325dbSPeter Wemm 	count = set_end - set;
135ddd62546SPeter Wemm 	if (newsysinit)
136f41325dbSPeter Wemm 		count += newsysinit_end - newsysinit;
137ddd62546SPeter Wemm 	else
138f41325dbSPeter Wemm 		count += sysinit_end - sysinit;
13994e9d7c1SPeter Wemm 	newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
14094e9d7c1SPeter Wemm 	if (newset == NULL)
14194e9d7c1SPeter Wemm 		panic("cannot malloc for sysinit");
14294e9d7c1SPeter Wemm 	xipp = newset;
143ddd62546SPeter Wemm 	if (newsysinit)
144f41325dbSPeter Wemm 		for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
145ddd62546SPeter Wemm 			*xipp++ = *sipp;
146ddd62546SPeter Wemm 	else
147f41325dbSPeter Wemm 		for (sipp = sysinit; sipp < sysinit_end; sipp++)
14894e9d7c1SPeter Wemm 			*xipp++ = *sipp;
149f41325dbSPeter Wemm 	for (sipp = set; sipp < set_end; sipp++)
15094e9d7c1SPeter Wemm 		*xipp++ = *sipp;
151ddd62546SPeter Wemm 	if (newsysinit)
152ddd62546SPeter Wemm 		free(newsysinit, M_TEMP);
15394e9d7c1SPeter Wemm 	newsysinit = newset;
154f41325dbSPeter Wemm 	newsysinit_end = newset + count;
15594e9d7c1SPeter Wemm }
15626f9a767SRodney W. Grimes 
157df8bae1dSRodney W. Grimes /*
158df8bae1dSRodney W. Grimes  * System startup; initialize the world, create process 0, mount root
159df8bae1dSRodney W. Grimes  * filesystem, and fork to create init and pagedaemon.  Most of the
160df8bae1dSRodney W. Grimes  * hard work is done in the lower-level initialization routines including
161df8bae1dSRodney W. Grimes  * startup(), which does memory initialization and autoconfiguration.
1622b14f991SJulian Elischer  *
1632b14f991SJulian Elischer  * This allows simple addition of new kernel subsystems that require
1642b14f991SJulian Elischer  * boot time initialization.  It also allows substitution of subsystem
1652b14f991SJulian Elischer  * (for instance, a scheduler, kernel profiler, or VM system) by object
166c5b193bfSPoul-Henning Kamp  * module.  Finally, it allows for optional "kernel threads".
167df8bae1dSRodney W. Grimes  */
16826f9a767SRodney W. Grimes void
16937b087a6SPeter Wemm mi_startup(void)
170df8bae1dSRodney W. Grimes {
1712b14f991SJulian Elischer 
1722b14f991SJulian Elischer 	register struct sysinit **sipp;		/* system initialization*/
1732b14f991SJulian Elischer 	register struct sysinit **xipp;		/* interior loop of sort*/
1742b14f991SJulian Elischer 	register struct sysinit *save;		/* bubble*/
1752b14f991SJulian Elischer 
17626ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
17726ab616fSBenno Rice 	int last;
17826ab616fSBenno Rice 	int verbose;
17926ab616fSBenno Rice #endif
18026ab616fSBenno Rice 
181f41325dbSPeter Wemm 	if (sysinit == NULL) {
182f41325dbSPeter Wemm 		sysinit = SET_BEGIN(sysinit_set);
183f41325dbSPeter Wemm 		sysinit_end = SET_LIMIT(sysinit_set);
184f41325dbSPeter Wemm 	}
185f41325dbSPeter Wemm 
18694e9d7c1SPeter Wemm restart:
1872b14f991SJulian Elischer 	/*
1882b14f991SJulian Elischer 	 * Perform a bubble sort of the system initialization objects by
1892b14f991SJulian Elischer 	 * their subsystem (primary key) and order (secondary key).
1902b14f991SJulian Elischer 	 */
191f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
192f41325dbSPeter Wemm 		for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
1932b14f991SJulian Elischer 			if ((*sipp)->subsystem < (*xipp)->subsystem ||
1942b14f991SJulian Elischer 			     ((*sipp)->subsystem == (*xipp)->subsystem &&
195af4b2d2dSPeter Wemm 			      (*sipp)->order <= (*xipp)->order))
1962b14f991SJulian Elischer 				continue;	/* skip*/
1972b14f991SJulian Elischer 			save = *sipp;
1982b14f991SJulian Elischer 			*sipp = *xipp;
1992b14f991SJulian Elischer 			*xipp = save;
2002b14f991SJulian Elischer 		}
2012b14f991SJulian Elischer 	}
2022b14f991SJulian Elischer 
20326ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
20426ab616fSBenno Rice 	last = SI_SUB_COPYRIGHT;
20526ab616fSBenno Rice 	verbose = 0;
20626ab616fSBenno Rice #if !defined(DDB)
20726ab616fSBenno Rice 	printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n");
20826ab616fSBenno Rice #endif
20926ab616fSBenno Rice #endif
21026ab616fSBenno Rice 
2112b14f991SJulian Elischer 	/*
2122b14f991SJulian Elischer 	 * Traverse the (now) ordered list of system initialization tasks.
2132b14f991SJulian Elischer 	 * Perform each task, and continue on to the next task.
2142b14f991SJulian Elischer 	 *
2152b14f991SJulian Elischer 	 * The last item on the list is expected to be the scheduler,
2162b14f991SJulian Elischer 	 * which will not return.
2172b14f991SJulian Elischer 	 */
218f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
21974b2192aSJohn Dyson 
2202b14f991SJulian Elischer 		if ((*sipp)->subsystem == SI_SUB_DUMMY)
2212b14f991SJulian Elischer 			continue;	/* skip dummy task(s)*/
2222b14f991SJulian Elischer 
22394e9d7c1SPeter Wemm 		if ((*sipp)->subsystem == SI_SUB_DONE)
22494e9d7c1SPeter Wemm 			continue;
22594e9d7c1SPeter Wemm 
22626ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
22726ab616fSBenno Rice 		if ((*sipp)->subsystem > last) {
22826ab616fSBenno Rice 			verbose = 1;
22926ab616fSBenno Rice 			last = (*sipp)->subsystem;
23026ab616fSBenno Rice 			printf("subsystem %x\n", last);
23126ab616fSBenno Rice 		}
23226ab616fSBenno Rice 		if (verbose) {
23326ab616fSBenno Rice #if defined(DDB)
23426ab616fSBenno Rice 			const char *name;
23526ab616fSBenno Rice 			c_db_sym_t sym;
23626ab616fSBenno Rice 			db_expr_t  offset;
23726ab616fSBenno Rice 
23826ab616fSBenno Rice 			sym = db_search_symbol((vm_offset_t)(*sipp)->func,
23926ab616fSBenno Rice 			    DB_STGY_PROC, &offset);
24026ab616fSBenno Rice 			db_symbol_values(sym, &name, NULL);
24126ab616fSBenno Rice 			if (name != NULL)
24226ab616fSBenno Rice 				printf("   %s(%p)... ", name, (*sipp)->udata);
24326ab616fSBenno Rice 			else
24426ab616fSBenno Rice #endif
24526ab616fSBenno Rice 				printf("   %p(%p)... ", (*sipp)->func,
24626ab616fSBenno Rice 				    (*sipp)->udata);
24726ab616fSBenno Rice 		}
24826ab616fSBenno Rice #endif
24926ab616fSBenno Rice 
2509c8b8baaSPeter Wemm 		/* Call function */
2512b14f991SJulian Elischer 		(*((*sipp)->func))((*sipp)->udata);
25294e9d7c1SPeter Wemm 
25326ab616fSBenno Rice #if defined(VERBOSE_SYSINIT)
25426ab616fSBenno Rice 		if (verbose)
25526ab616fSBenno Rice 			printf("done.\n");
25626ab616fSBenno Rice #endif
25726ab616fSBenno Rice 
25894e9d7c1SPeter Wemm 		/* Check off the one we're just done */
25994e9d7c1SPeter Wemm 		(*sipp)->subsystem = SI_SUB_DONE;
26094e9d7c1SPeter Wemm 
26194e9d7c1SPeter Wemm 		/* Check if we've installed more sysinit items via KLD */
26294e9d7c1SPeter Wemm 		if (newsysinit != NULL) {
263f41325dbSPeter Wemm 			if (sysinit != SET_BEGIN(sysinit_set))
26494e9d7c1SPeter Wemm 				free(sysinit, M_TEMP);
26594e9d7c1SPeter Wemm 			sysinit = newsysinit;
266f41325dbSPeter Wemm 			sysinit_end = newsysinit_end;
26794e9d7c1SPeter Wemm 			newsysinit = NULL;
268f41325dbSPeter Wemm 			newsysinit_end = NULL;
26994e9d7c1SPeter Wemm 			goto restart;
27094e9d7c1SPeter Wemm 		}
2712b14f991SJulian Elischer 	}
2722b14f991SJulian Elischer 
273477a642cSPeter Wemm 	panic("Shouldn't get here!");
2742b14f991SJulian Elischer 	/* NOTREACHED*/
2752b14f991SJulian Elischer }
2762b14f991SJulian Elischer 
2772b14f991SJulian Elischer 
2782b14f991SJulian Elischer /*
2792b14f991SJulian Elischer  ***************************************************************************
2802b14f991SJulian Elischer  ****
2812b14f991SJulian Elischer  **** The following SYSINIT's belong elsewhere, but have not yet
2822b14f991SJulian Elischer  **** been moved.
2832b14f991SJulian Elischer  ****
2842b14f991SJulian Elischer  ***************************************************************************
2852b14f991SJulian Elischer  */
2869ef6c28aSBruce Evans static void
28737b087a6SPeter Wemm print_caddr_t(void *data __unused)
2889ef6c28aSBruce Evans {
2899ef6c28aSBruce Evans 	printf("%s", (char *)data);
2909ef6c28aSBruce Evans }
291237fdd78SRobert Watson SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t,
292237fdd78SRobert Watson     copyright);
293237fdd78SRobert Watson SYSINIT(trademark, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t,
294237fdd78SRobert Watson     trademark);
295237fdd78SRobert Watson SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_THIRD, print_caddr_t, version);
2967a08bae6SJohn Baldwin 
2972cf6bdacSPoul-Henning Kamp #ifdef WITNESS
2982cf6bdacSPoul-Henning Kamp static char wit_warn[] =
2992cf6bdacSPoul-Henning Kamp      "WARNING: WITNESS option enabled, expect reduced performance.\n";
3005add74b4SRobert Watson SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
301237fdd78SRobert Watson    print_caddr_t, wit_warn);
3027acfb0afSPoul-Henning Kamp SYSINIT(witwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 1,
303237fdd78SRobert Watson    print_caddr_t, wit_warn);
3042cf6bdacSPoul-Henning Kamp #endif
3052cf6bdacSPoul-Henning Kamp 
3062cf6bdacSPoul-Henning Kamp #ifdef DIAGNOSTIC
3072cf6bdacSPoul-Henning Kamp static char diag_warn[] =
3082cf6bdacSPoul-Henning Kamp      "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
30988b85279SRobert Watson SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2,
310237fdd78SRobert Watson     print_caddr_t, diag_warn);
3117acfb0afSPoul-Henning Kamp SYSINIT(diagwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 2,
312237fdd78SRobert Watson     print_caddr_t, diag_warn);
3132cf6bdacSPoul-Henning Kamp #endif
3142cf6bdacSPoul-Henning Kamp 
3157a08bae6SJohn Baldwin static void
3167a08bae6SJohn Baldwin set_boot_verbose(void *data __unused)
3177a08bae6SJohn Baldwin {
3187a08bae6SJohn Baldwin 
3197a08bae6SJohn Baldwin 	if (boothowto & RB_VERBOSE)
3207a08bae6SJohn Baldwin 		bootverbose++;
3217a08bae6SJohn Baldwin }
322237fdd78SRobert Watson SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL);
3232b14f991SJulian Elischer 
324f36ba452SJake Burkholder struct sysentvec null_sysvec = {
325f36ba452SJake Burkholder 	0,
326f36ba452SJake Burkholder 	NULL,
327f36ba452SJake Burkholder 	0,
328f36ba452SJake Burkholder 	0,
329f36ba452SJake Burkholder 	NULL,
330f36ba452SJake Burkholder 	0,
331f36ba452SJake Burkholder 	NULL,
332f36ba452SJake Burkholder 	NULL,
333f36ba452SJake Burkholder 	NULL,
334f36ba452SJake Burkholder 	NULL,
335f36ba452SJake Burkholder 	NULL,
336f36ba452SJake Burkholder 	NULL,
337f36ba452SJake Burkholder 	NULL,
338f36ba452SJake Burkholder 	"null",
339f36ba452SJake Burkholder 	NULL,
340f36ba452SJake Burkholder 	NULL,
341f36ba452SJake Burkholder 	0,
342f36ba452SJake Burkholder 	PAGE_SIZE,
343f36ba452SJake Burkholder 	VM_MIN_ADDRESS,
344f36ba452SJake Burkholder 	VM_MAXUSER_ADDRESS,
345f36ba452SJake Burkholder 	USRSTACK,
346f36ba452SJake Burkholder 	PS_STRINGS,
347f36ba452SJake Burkholder 	VM_PROT_ALL,
348f36ba452SJake Burkholder 	NULL,
349c460ac3aSPeter Wemm 	NULL,
350f36ba452SJake Burkholder 	NULL
351f36ba452SJake Burkholder };
3523ebc1248SPeter Wemm 
3532b14f991SJulian Elischer /*
3542b14f991SJulian Elischer  ***************************************************************************
3552b14f991SJulian Elischer  ****
3560c920c0dSGiorgos Keramidas  **** The two following SYSINIT's are proc0 specific glue code.  I am not
3572b14f991SJulian Elischer  **** convinced that they can not be safely combined, but their order of
3582b14f991SJulian Elischer  **** operation has been maintained as the same as the original init_main.c
3592b14f991SJulian Elischer  **** for right now.
3602b14f991SJulian Elischer  ****
3612b14f991SJulian Elischer  **** These probably belong in init_proc.c or kern_proc.c, since they
3622b14f991SJulian Elischer  **** deal with proc0 (the fork template process).
3632b14f991SJulian Elischer  ****
3642b14f991SJulian Elischer  ***************************************************************************
3652b14f991SJulian Elischer  */
3662b14f991SJulian Elischer /* ARGSUSED*/
367154c04e5SPoul-Henning Kamp static void
36837b087a6SPeter Wemm proc0_init(void *dummy __unused)
3692b14f991SJulian Elischer {
3708ec21e3aSPoul-Henning Kamp 	struct proc *p;
3718ec21e3aSPoul-Henning Kamp 	unsigned i;
372b40ce416SJulian Elischer 	struct thread *td;
373df8bae1dSRodney W. Grimes 
3740cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
375df8bae1dSRodney W. Grimes 	p = &proc0;
376079b7badSJulian Elischer 	td = &thread0;
377df8bae1dSRodney W. Grimes 
378df8bae1dSRodney W. Grimes 	/*
379f231de47SKonstantin Belousov 	 * Initialize magic number and osrel.
3800384fff8SJason Evans 	 */
3810384fff8SJason Evans 	p->p_magic = P_MAGIC;
382f231de47SKonstantin Belousov 	p->p_osrel = osreldate;
3830384fff8SJason Evans 
3848460a577SJohn Birrell 	/*
3858460a577SJohn Birrell 	 * Initialize thread and process structures.
3868460a577SJohn Birrell 	 */
3878460a577SJohn Birrell 	procinit();	/* set up proc zone */
3888460a577SJohn Birrell 	threadinit();	/* set up UMA zones */
3898460a577SJohn Birrell 
3908460a577SJohn Birrell 	/*
3918460a577SJohn Birrell 	 * Initialise scheduler resources.
3928460a577SJohn Birrell 	 * Add scheduler specific parts to proc, thread as needed.
3938460a577SJohn Birrell 	 */
394ed062c8dSJulian Elischer 	schedinit();	/* scheduler gets its house in order */
395ed062c8dSJulian Elischer 	/*
396b1508c72SDavid Greenman 	 * Initialize sleep queue hash table
397b1508c72SDavid Greenman 	 */
398b1508c72SDavid Greenman 	sleepinit();
399b1508c72SDavid Greenman 
400b1508c72SDavid Greenman 	/*
4013075778bSJohn Dyson 	 * additional VM structures
4023075778bSJohn Dyson 	 */
4033075778bSJohn Dyson 	vm_init2();
4043075778bSJohn Dyson 
4053075778bSJohn Dyson 	/*
406df8bae1dSRodney W. Grimes 	 * Create process 0 (the swapper).
407df8bae1dSRodney W. Grimes 	 */
408a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&allproc, p, p_list);
4097b531e60SJohn Baldwin 	LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
4106008862bSJohn Baldwin 	mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
411df8bae1dSRodney W. Grimes 	p->p_pgrp = &pgrp0;
412a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
413a3bfb996SJeffrey Hsu 	LIST_INIT(&pgrp0.pg_members);
414a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
415a3bfb996SJeffrey Hsu 
416df8bae1dSRodney W. Grimes 	pgrp0.pg_session = &session0;
4176008862bSJohn Baldwin 	mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
418bc093719SEd Schouten 	refcount_init(&session0.s_count, 1);
419df8bae1dSRodney W. Grimes 	session0.s_leader = p;
420df8bae1dSRodney W. Grimes 
4213ebc1248SPeter Wemm 	p->p_sysent = &null_sysvec;
422b61ce5b0SJeff Roberson 	p->p_flag = P_SYSTEM | P_INMEM;
423e602ba25SJulian Elischer 	p->p_state = PRS_NORMAL;
424571dcd15SSuleiman Souhlal 	knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL);
4252c255e9dSRobert Watson 	STAILQ_INIT(&p->p_ktr);
426fa885116SJulian Elischer 	p->p_nice = NZERO;
4276829a5c5SJulian Elischer 	td->td_tid = PID_MAX + 1;
428e602ba25SJulian Elischer 	td->td_state = TDS_RUNNING;
4298460a577SJohn Birrell 	td->td_pri_class = PRI_TIMESHARE;
4308460a577SJohn Birrell 	td->td_user_pri = PUSER;
43160d48235SDavid Xu 	td->td_base_user_pri = PUSER;
4322c100766SJulian Elischer 	td->td_priority = PVM;
4332c100766SJulian Elischer 	td->td_base_pri = PUSER;
434060563ecSJulian Elischer 	td->td_oncpu = 0;
4357ab24ea3SJulian Elischer 	td->td_flags = TDF_INMEM|TDP_KTHREAD;
436d7f687fcSJeff Roberson 	td->td_cpuset = cpuset_thread0();
4372c1011f7SJohn Dyson 	p->p_peers = 0;
4382c1011f7SJohn Dyson 	p->p_leader = p;
439e602ba25SJulian Elischer 
4402c1011f7SJohn Dyson 
4417ab24ea3SJulian Elischer 	strncpy(p->p_comm, "kernel", sizeof (p->p_comm));
4427ab24ea3SJulian Elischer 	strncpy(td->td_name, "swapper", sizeof (td->td_name));
443df8bae1dSRodney W. Grimes 
444c06eb4e2SSam Leffler 	callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
4451c4bcd05SJeff Roberson 	callout_init_mtx(&p->p_limco, &p->p_mtx, 0);
446c06eb4e2SSam Leffler 	callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
4474f559836SJake Burkholder 
448df8bae1dSRodney W. Grimes 	/* Create credentials. */
449df8bae1dSRodney W. Grimes 	p->p_ucred = crget();
450df8bae1dSRodney W. Grimes 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
451f535380cSDon Lewis 	p->p_ucred->cr_uidinfo = uifind(0);
452b1fc0ec1SRobert Watson 	p->p_ucred->cr_ruidinfo = uifind(0);
45391421ba2SRobert Watson 	p->p_ucred->cr_prison = NULL;	/* Don't jail it. */
4543683665bSRobert Watson #ifdef AUDIT
455faef5371SRobert Watson 	audit_cred_kproc0(p->p_ucred);
4563683665bSRobert Watson #endif
45740244964SRobert Watson #ifdef MAC
45830d239bcSRobert Watson 	mac_proc_create_swapper(p->p_ucred);
45940244964SRobert Watson #endif
4608e2e767bSJohn Baldwin 	td->td_ucred = crhold(p->p_ucred);
46175c13541SPoul-Henning Kamp 
46290af4afaSJohn Baldwin 	/* Create sigacts. */
46390af4afaSJohn Baldwin 	p->p_sigacts = sigacts_alloc();
4646626c604SJulian Elischer 
46537b087a6SPeter Wemm 	/* Initialize signal state for process 0. */
46637b087a6SPeter Wemm 	siginit(&proc0);
46737b087a6SPeter Wemm 
468df8bae1dSRodney W. Grimes 	/* Create the file descriptor table. */
4698ec21e3aSPoul-Henning Kamp 	p->p_fd = fdinit(NULL);
470ad05d580STor Egge 	p->p_fdtol = NULL;
471df8bae1dSRodney W. Grimes 
472df8bae1dSRodney W. Grimes 	/* Create the limits structures. */
47391d5354aSJohn Baldwin 	p->p_limit = lim_alloc();
47491d5354aSJohn Baldwin 	for (i = 0; i < RLIM_NLIMITS; i++)
47591d5354aSJohn Baldwin 		p->p_limit->pl_rlimit[i].rlim_cur =
47691d5354aSJohn Baldwin 		    p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
47791d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
47891d5354aSJohn Baldwin 	    p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
47991d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
48091d5354aSJohn Baldwin 	    p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
4812feb50bfSAttilio Rao 	i = ptoa(cnt.v_free_count);
48291d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i;
48391d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
48491d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
4855715307fSJohn Baldwin 	p->p_cpulimit = RLIM_INFINITY;
486df8bae1dSRodney W. Grimes 
4878b059651SDavid Schultz 	p->p_stats = pstats_alloc();
4888b059651SDavid Schultz 
489df8bae1dSRodney W. Grimes 	/* Allocate a prototype map so we have something to fork. */
490b1028ad1SLuoqi Chen 	pmap_pinit0(vmspace_pmap(&vmspace0));
491df8bae1dSRodney W. Grimes 	p->p_vmspace = &vmspace0;
492df8bae1dSRodney W. Grimes 	vmspace0.vm_refcnt = 1;
49305ba50f5SJake Burkholder 	vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
49405ba50f5SJake Burkholder 	    p->p_sysent->sv_maxuser);
495b1028ad1SLuoqi Chen 	vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
4967c7454feSRandall Stewart 
4977c7454feSRandall Stewart 	/*-
4987c7454feSRandall Stewart 	 * call the init and ctor for the new thread and proc
4997c7454feSRandall Stewart 	 * we wait to do this until all other structures
5007c7454feSRandall Stewart 	 * are fairly sane.
5017c7454feSRandall Stewart 	 */
5027c7454feSRandall Stewart 	EVENTHANDLER_INVOKE(process_init, p);
5037c7454feSRandall Stewart 	EVENTHANDLER_INVOKE(thread_init, td);
5047c7454feSRandall Stewart 	EVENTHANDLER_INVOKE(process_ctor, p);
5057c7454feSRandall Stewart 	EVENTHANDLER_INVOKE(thread_ctor, td);
506df8bae1dSRodney W. Grimes 
50739fb8e6bSJulian Elischer 	/*
508a3bfb996SJeffrey Hsu 	 * Charge root for one process.
509df8bae1dSRodney W. Grimes 	 */
510b1fc0ec1SRobert Watson 	(void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
51126f9a767SRodney W. Grimes }
512237fdd78SRobert Watson SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL);
5132b14f991SJulian Elischer 
5142b14f991SJulian Elischer /* ARGSUSED*/
515154c04e5SPoul-Henning Kamp static void
51637b087a6SPeter Wemm proc0_post(void *dummy __unused)
5172b14f991SJulian Elischer {
51800af9731SPoul-Henning Kamp 	struct timespec ts;
51937b087a6SPeter Wemm 	struct proc *p;
520a140976eSAttilio Rao 	struct rusage ru;
521d92909c1SRobert Watson 	struct thread *td;
522a6fc8288SPeter Wemm 
5232b14f991SJulian Elischer 	/*
5241b0b259eSBruce Evans 	 * Now we can look at the time, having had a chance to verify the
5251b0b259eSBruce Evans 	 * time from the filesystem.  Pretend that proc0 started now.
5262b14f991SJulian Elischer 	 */
5271005a129SJohn Baldwin 	sx_slock(&allproc_lock);
5284f506694SXin LI 	FOREACH_PROC_IN_SYSTEM(p) {
52987ccef7bSDag-Erling Smørgrav 		microuptime(&p->p_stats->p_start);
530bdf08be4SAttilio Rao 		PROC_SLOCK(p);
531a140976eSAttilio Rao 		rufetch(p, &ru);	/* Clears thread stats */
532bdf08be4SAttilio Rao 		PROC_SUNLOCK(p);
5335b1a8eb3SPoul-Henning Kamp 		p->p_rux.rux_runtime = 0;
534a140976eSAttilio Rao 		p->p_rux.rux_uticks = 0;
535a140976eSAttilio Rao 		p->p_rux.rux_sticks = 0;
536a140976eSAttilio Rao 		p->p_rux.rux_iticks = 0;
537d92909c1SRobert Watson 		FOREACH_THREAD_IN_PROC(p, td) {
538d92909c1SRobert Watson 			td->td_runtime = 0;
539d92909c1SRobert Watson 		}
54037b087a6SPeter Wemm 	}
5411005a129SJohn Baldwin 	sx_sunlock(&allproc_lock);
5425b1a8eb3SPoul-Henning Kamp 	PCPU_SET(switchtime, cpu_ticks());
5430384fff8SJason Evans 	PCPU_SET(switchticks, ticks);
5442b14f991SJulian Elischer 
545a6fc8288SPeter Wemm 	/*
546a6fc8288SPeter Wemm 	 * Give the ``random'' number generator a thump.
547a6fc8288SPeter Wemm 	 */
54800af9731SPoul-Henning Kamp 	nanotime(&ts);
54900af9731SPoul-Henning Kamp 	srandom(ts.tv_sec ^ ts.tv_nsec);
5502b14f991SJulian Elischer }
551237fdd78SRobert Watson SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL);
5522b14f991SJulian Elischer 
553df8bae1dSRodney W. Grimes /*
5542b14f991SJulian Elischer  ***************************************************************************
5552b14f991SJulian Elischer  ****
5562b14f991SJulian Elischer  **** The following SYSINIT's and glue code should be moved to the
5572b14f991SJulian Elischer  **** respective files on a per subsystem basis.
5582b14f991SJulian Elischer  ****
5592b14f991SJulian Elischer  ***************************************************************************
560df8bae1dSRodney W. Grimes  */
561df8bae1dSRodney W. Grimes 
562df8bae1dSRodney W. Grimes 
563df8bae1dSRodney W. Grimes /*
5642b14f991SJulian Elischer  ***************************************************************************
5652b14f991SJulian Elischer  ****
5662b14f991SJulian Elischer  **** The following code probably belongs in another file, like
56737b087a6SPeter Wemm  **** kern/init_init.c.
5682b14f991SJulian Elischer  ****
5692b14f991SJulian Elischer  ***************************************************************************
570df8bae1dSRodney W. Grimes  */
571df8bae1dSRodney W. Grimes 
572df8bae1dSRodney W. Grimes /*
573df8bae1dSRodney W. Grimes  * List of paths to try when searching for "init".
574df8bae1dSRodney W. Grimes  */
5755f967b24SDag-Erling Smørgrav static char init_path[MAXPATHLEN] =
57667481196SJohn Birrell #ifdef	INIT_PATH
57767481196SJohn Birrell     __XSTRING(INIT_PATH);
57867481196SJohn Birrell #else
579f3f4baf0SDag-Erling Smørgrav     "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall";
58067481196SJohn Birrell #endif
581af1408e3SLuigi Rizzo SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
582af1408e3SLuigi Rizzo 	"Path used to search the init process");
583df8bae1dSRodney W. Grimes 
584df8bae1dSRodney W. Grimes /*
585724447acSRalf S. Engelschall  * Shutdown timeout of init(8).
586724447acSRalf S. Engelschall  * Unused within kernel, but used to control init(8), hence do not remove.
587724447acSRalf S. Engelschall  */
588724447acSRalf S. Engelschall #ifndef INIT_SHUTDOWN_TIMEOUT
589724447acSRalf S. Engelschall #define INIT_SHUTDOWN_TIMEOUT 120
590724447acSRalf S. Engelschall #endif
591724447acSRalf S. Engelschall static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT;
592724447acSRalf S. Engelschall SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
593724447acSRalf S. Engelschall 	CTLFLAG_RW, &init_shutdown_timeout, 0, "");
594724447acSRalf S. Engelschall 
595e77d7f71SKip Macy int scheduler_running = 0;
596e77d7f71SKip Macy 
597724447acSRalf S. Engelschall /*
5985f967b24SDag-Erling Smørgrav  * Start the initial user process; try exec'ing each pathname in init_path.
599df8bae1dSRodney W. Grimes  * The program is invoked with one argument containing the boot flags.
600df8bae1dSRodney W. Grimes  */
601df8bae1dSRodney W. Grimes static void
60237b087a6SPeter Wemm start_init(void *dummy)
603df8bae1dSRodney W. Grimes {
604df8bae1dSRodney W. Grimes 	vm_offset_t addr;
605df8bae1dSRodney W. Grimes 	struct execve_args args;
6065f967b24SDag-Erling Smørgrav 	int options, error;
6075f967b24SDag-Erling Smørgrav 	char *var, *path, *next, *s;
6085f967b24SDag-Erling Smørgrav 	char *ucp, **uap, *arg0, *arg1;
609b40ce416SJulian Elischer 	struct thread *td;
6109c8b8baaSPeter Wemm 	struct proc *p;
611df8bae1dSRodney W. Grimes 
612e77d7f71SKip Macy 	scheduler_running = 1;
6139ed346baSBosko Milekic 	mtx_lock(&Giant);
6140384fff8SJason Evans 
6150cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
6160cddd8f0SMatthew Dillon 
617b40ce416SJulian Elischer 	td = curthread;
618b40ce416SJulian Elischer 	p = td->td_proc;
619df8bae1dSRodney W. Grimes 
620563af2ecSMaxime Henrion 	vfs_mountroot();
621fb92273bSPoul-Henning Kamp 
622b7116168SPeter Wemm 	/*
623df8bae1dSRodney W. Grimes 	 * Need just enough stack to hold the faked-up "execve()" arguments.
624df8bae1dSRodney W. Grimes 	 */
62505ba50f5SJake Burkholder 	addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
6265f967b24SDag-Erling Smørgrav 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
6275f967b24SDag-Erling Smørgrav 			FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
628df8bae1dSRodney W. Grimes 		panic("init: couldn't allocate argument space");
629df8bae1dSRodney W. Grimes 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
63026f9a767SRodney W. Grimes 	p->p_vmspace->vm_ssize = 1;
631df8bae1dSRodney W. Grimes 
6325f967b24SDag-Erling Smørgrav 	if ((var = getenv("init_path")) != NULL) {
633e80fb434SRobert Drehmel 		strlcpy(init_path, var, sizeof(init_path));
634d786139cSMaxime Henrion 		freeenv(var);
6355f967b24SDag-Erling Smørgrav 	}
6365f967b24SDag-Erling Smørgrav 
63767481196SJohn Birrell 	for (path = init_path; *path != '\0'; path = next) {
638e4082284SJohn Birrell 		while (*path == ':')
6395f967b24SDag-Erling Smørgrav 			path++;
64067481196SJohn Birrell 		if (*path == '\0')
6415f967b24SDag-Erling Smørgrav 			break;
642e4082284SJohn Birrell 		for (next = path; *next != '\0' && *next != ':'; next++)
6435f967b24SDag-Erling Smørgrav 			/* nothing */ ;
6445f967b24SDag-Erling Smørgrav 		if (bootverbose)
645ba41a07dSDmitrij Tejblum 			printf("start_init: trying %.*s\n", (int)(next - path),
646ba41a07dSDmitrij Tejblum 			    path);
6475f967b24SDag-Erling Smørgrav 
648df8bae1dSRodney W. Grimes 		/*
649df8bae1dSRodney W. Grimes 		 * Move out the boot flag argument.
650df8bae1dSRodney W. Grimes 		 */
651df8bae1dSRodney W. Grimes 		options = 0;
65205ba50f5SJake Burkholder 		ucp = (char *)p->p_sysent->sv_usrstack;
653df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, 0);		/* trailing zero */
654df8bae1dSRodney W. Grimes 		if (boothowto & RB_SINGLE) {
655df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 's');
656df8bae1dSRodney W. Grimes 			options = 1;
657df8bae1dSRodney W. Grimes 		}
658df8bae1dSRodney W. Grimes #ifdef notyet
659df8bae1dSRodney W. Grimes                 if (boothowto & RB_FASTBOOT) {
660df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 'f');
661df8bae1dSRodney W. Grimes 			options = 1;
662df8bae1dSRodney W. Grimes 		}
663df8bae1dSRodney W. Grimes #endif
66417755ac8SPoul-Henning Kamp 
66517755ac8SPoul-Henning Kamp #ifdef BOOTCDROM
66617755ac8SPoul-Henning Kamp 		(void)subyte(--ucp, 'C');
66717755ac8SPoul-Henning Kamp 		options = 1;
66817755ac8SPoul-Henning Kamp #endif
669db901281SPoul-Henning Kamp 
670df8bae1dSRodney W. Grimes 		if (options == 0)
671df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, '-');
672df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, '-');		/* leading hyphen */
673df8bae1dSRodney W. Grimes 		arg1 = ucp;
674df8bae1dSRodney W. Grimes 
675df8bae1dSRodney W. Grimes 		/*
676df8bae1dSRodney W. Grimes 		 * Move out the file name (also arg 0).
677df8bae1dSRodney W. Grimes 		 */
6785f967b24SDag-Erling Smørgrav 		(void)subyte(--ucp, 0);
6795f967b24SDag-Erling Smørgrav 		for (s = next - 1; s >= path; s--)
6805f967b24SDag-Erling Smørgrav 			(void)subyte(--ucp, *s);
681df8bae1dSRodney W. Grimes 		arg0 = ucp;
682df8bae1dSRodney W. Grimes 
683df8bae1dSRodney W. Grimes 		/*
684df8bae1dSRodney W. Grimes 		 * Move out the arg pointers.
685df8bae1dSRodney W. Grimes 		 */
686a20d7755SDoug Rabson 		uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
687c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)0);	/* terminator */
688c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
689c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
690df8bae1dSRodney W. Grimes 
691df8bae1dSRodney W. Grimes 		/*
692df8bae1dSRodney W. Grimes 		 * Point at the arguments.
693df8bae1dSRodney W. Grimes 		 */
694df8bae1dSRodney W. Grimes 		args.fname = arg0;
69526f9a767SRodney W. Grimes 		args.argv = uap;
69626f9a767SRodney W. Grimes 		args.envv = NULL;
697df8bae1dSRodney W. Grimes 
698df8bae1dSRodney W. Grimes 		/*
699df8bae1dSRodney W. Grimes 		 * Now try to exec the program.  If can't for any reason
700df8bae1dSRodney W. Grimes 		 * other than it doesn't exist, complain.
7012b14f991SJulian Elischer 		 *
70237b087a6SPeter Wemm 		 * Otherwise, return via fork_trampoline() all the way
7039c8b8baaSPeter Wemm 		 * to user mode as init!
704df8bae1dSRodney W. Grimes 		 */
705b40ce416SJulian Elischer 		if ((error = execve(td, &args)) == 0) {
7069ed346baSBosko Milekic 			mtx_unlock(&Giant);
707df8bae1dSRodney W. Grimes 			return;
708db72809dSJohn Baldwin 		}
709df8bae1dSRodney W. Grimes 		if (error != ENOENT)
710ba41a07dSDmitrij Tejblum 			printf("exec %.*s: error %d\n", (int)(next - path),
711ba41a07dSDmitrij Tejblum 			    path, error);
712df8bae1dSRodney W. Grimes 	}
713580e7e5aSGreg Lehey 	printf("init: not found in path %s\n", init_path);
714df8bae1dSRodney W. Grimes 	panic("no init");
715df8bae1dSRodney W. Grimes }
71637b087a6SPeter Wemm 
71737b087a6SPeter Wemm /*
7183745c395SJulian Elischer  * Like kproc_create(), but runs in it's own address space.
71937b087a6SPeter Wemm  * We do this early to reserve pid 1.
72037b087a6SPeter Wemm  *
72137b087a6SPeter Wemm  * Note special case - do not make it runnable yet.  Other work
72237b087a6SPeter Wemm  * in progress will change this more.
72337b087a6SPeter Wemm  */
72437b087a6SPeter Wemm static void
72537b087a6SPeter Wemm create_init(const void *udata __unused)
72637b087a6SPeter Wemm {
7275a06cb0cSRobert Watson 	struct ucred *newcred, *oldcred;
72837b087a6SPeter Wemm 	int error;
72937b087a6SPeter Wemm 
730316ec49aSScott Long 	error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
73137b087a6SPeter Wemm 	if (error)
73237b087a6SPeter Wemm 		panic("cannot fork init: %d\n", error);
733bafc8f25SRobert Watson 	KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
7345a06cb0cSRobert Watson 	/* divorce init's credentials from the kernel's */
7355a06cb0cSRobert Watson 	newcred = crget();
736f202965eSJohn Baldwin 	PROC_LOCK(initproc);
737b61ce5b0SJeff Roberson 	initproc->p_flag |= P_SYSTEM | P_INMEM;
7385a06cb0cSRobert Watson 	oldcred = initproc->p_ucred;
7395a06cb0cSRobert Watson 	crcopy(newcred, oldcred);
74040244964SRobert Watson #ifdef MAC
74130d239bcSRobert Watson 	mac_proc_create_init(newcred);
74240244964SRobert Watson #endif
7433683665bSRobert Watson #ifdef AUDIT
744faef5371SRobert Watson 	audit_cred_proc1(newcred);
7453683665bSRobert Watson #endif
7465a06cb0cSRobert Watson 	initproc->p_ucred = newcred;
747f202965eSJohn Baldwin 	PROC_UNLOCK(initproc);
7485a06cb0cSRobert Watson 	crfree(oldcred);
7494d1a4bb7SRobert Watson 	cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
750079b7badSJulian Elischer 	cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
75137b087a6SPeter Wemm }
752237fdd78SRobert Watson SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL);
75337b087a6SPeter Wemm 
75437b087a6SPeter Wemm /*
75537b087a6SPeter Wemm  * Make it runnable now.
75637b087a6SPeter Wemm  */
75737b087a6SPeter Wemm static void
75837b087a6SPeter Wemm kick_init(const void *udata __unused)
75937b087a6SPeter Wemm {
760079b7badSJulian Elischer 	struct thread *td;
761f202965eSJohn Baldwin 
762079b7badSJulian Elischer 	td = FIRST_THREAD_IN_PROC(initproc);
763982d11f8SJeff Roberson 	thread_lock(td);
76471fad9fdSJulian Elischer 	TD_SET_CAN_RUN(td);
765f0393f06SJeff Roberson 	sched_add(td, SRQ_BORING);
766982d11f8SJeff Roberson 	thread_unlock(td);
76737b087a6SPeter Wemm }
768237fdd78SRobert Watson SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL);
769