xref: /freebsd/sys/kern/init_main.c (revision 2c255e9df6d870b6e7d19457b2c9fa77c7350755)
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 
4767481196SJohn Birrell #include "opt_init_path.h"
4840244964SRobert Watson #include "opt_mac.h"
494bd49128SPeter Wemm 
50df8bae1dSRodney W. Grimes #include <sys/param.h>
519e209b12SAlfred Perlstein #include <sys/kernel.h>
52f36ba452SJake Burkholder #include <sys/exec.h>
53b3c5c18dSBruce Evans #include <sys/file.h>
54df8bae1dSRodney W. Grimes #include <sys/filedesc.h>
550384fff8SJason Evans #include <sys/ktr.h>
561005a129SJohn Baldwin #include <sys/lock.h>
5740244964SRobert Watson #include <sys/mac.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 
79df8bae1dSRodney W. Grimes #include <vm/vm.h>
80efeaf95aSDavid Greenman #include <vm/vm_param.h>
81efeaf95aSDavid Greenman #include <vm/pmap.h>
82efeaf95aSDavid Greenman #include <vm/vm_map.h>
836faaa756SWolfram Schneider #include <sys/copyright.h>
84df8bae1dSRodney W. Grimes 
8537b087a6SPeter Wemm void mi_startup(void);				/* Should be elsewhere */
86df8bae1dSRodney W. Grimes 
87df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */
88154c04e5SPoul-Henning Kamp static struct session session0;
89154c04e5SPoul-Henning Kamp static struct pgrp pgrp0;
90df8bae1dSRodney W. Grimes struct	proc proc0;
91079b7badSJulian Elischer struct	thread thread0;
924f0db5e0SJulian Elischer struct	ksegrp ksegrp0;
9323734995SJake Burkholder struct	vmspace vmspace0;
942b14f991SJulian Elischer struct	proc *initproc;
95df8bae1dSRodney W. Grimes 
96c463cf1cSBruce Evans int	boothowto = 0;		/* initialized so that it can be patched */
978d0bf3d6SJordan K. Hubbard SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
987a08bae6SJohn Baldwin int	bootverbose;
997a08bae6SJohn Baldwin SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
100946bb7a2SPoul-Henning Kamp 
1012b14f991SJulian Elischer /*
1022b14f991SJulian Elischer  * This ensures that there is at least one entry so that the sysinit_set
1032b14f991SJulian Elischer  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
1042b14f991SJulian Elischer  * executed.
10526f9a767SRodney W. Grimes  */
1062b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
1078a129caeSDavid Greenman 
10894e9d7c1SPeter Wemm /*
10994e9d7c1SPeter Wemm  * The sysinit table itself.  Items are checked off as the are run.
11094e9d7c1SPeter Wemm  * If we want to register new sysinit types, add them to newsysinit.
11194e9d7c1SPeter Wemm  */
112f41325dbSPeter Wemm SET_DECLARE(sysinit_set, struct sysinit);
113f41325dbSPeter Wemm struct sysinit **sysinit, **sysinit_end;
114f41325dbSPeter Wemm struct sysinit **newsysinit, **newsysinit_end;
11594e9d7c1SPeter Wemm 
11694e9d7c1SPeter Wemm /*
11794e9d7c1SPeter Wemm  * Merge a new sysinit set into the current set, reallocating it if
11894e9d7c1SPeter Wemm  * necessary.  This can only be called after malloc is running.
11994e9d7c1SPeter Wemm  */
12094e9d7c1SPeter Wemm void
121f41325dbSPeter Wemm sysinit_add(struct sysinit **set, struct sysinit **set_end)
12294e9d7c1SPeter Wemm {
12394e9d7c1SPeter Wemm 	struct sysinit **newset;
12494e9d7c1SPeter Wemm 	struct sysinit **sipp;
12594e9d7c1SPeter Wemm 	struct sysinit **xipp;
126f41325dbSPeter Wemm 	int count;
12794e9d7c1SPeter Wemm 
128f41325dbSPeter Wemm 	count = set_end - set;
129ddd62546SPeter Wemm 	if (newsysinit)
130f41325dbSPeter Wemm 		count += newsysinit_end - newsysinit;
131ddd62546SPeter Wemm 	else
132f41325dbSPeter Wemm 		count += sysinit_end - sysinit;
13394e9d7c1SPeter Wemm 	newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
13494e9d7c1SPeter Wemm 	if (newset == NULL)
13594e9d7c1SPeter Wemm 		panic("cannot malloc for sysinit");
13694e9d7c1SPeter Wemm 	xipp = newset;
137ddd62546SPeter Wemm 	if (newsysinit)
138f41325dbSPeter Wemm 		for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
139ddd62546SPeter Wemm 			*xipp++ = *sipp;
140ddd62546SPeter Wemm 	else
141f41325dbSPeter Wemm 		for (sipp = sysinit; sipp < sysinit_end; sipp++)
14294e9d7c1SPeter Wemm 			*xipp++ = *sipp;
143f41325dbSPeter Wemm 	for (sipp = set; sipp < set_end; sipp++)
14494e9d7c1SPeter Wemm 		*xipp++ = *sipp;
145ddd62546SPeter Wemm 	if (newsysinit)
146ddd62546SPeter Wemm 		free(newsysinit, M_TEMP);
14794e9d7c1SPeter Wemm 	newsysinit = newset;
148f41325dbSPeter Wemm 	newsysinit_end = newset + count;
14994e9d7c1SPeter Wemm }
15026f9a767SRodney W. Grimes 
151df8bae1dSRodney W. Grimes /*
152df8bae1dSRodney W. Grimes  * System startup; initialize the world, create process 0, mount root
153df8bae1dSRodney W. Grimes  * filesystem, and fork to create init and pagedaemon.  Most of the
154df8bae1dSRodney W. Grimes  * hard work is done in the lower-level initialization routines including
155df8bae1dSRodney W. Grimes  * startup(), which does memory initialization and autoconfiguration.
1562b14f991SJulian Elischer  *
1572b14f991SJulian Elischer  * This allows simple addition of new kernel subsystems that require
1582b14f991SJulian Elischer  * boot time initialization.  It also allows substitution of subsystem
1592b14f991SJulian Elischer  * (for instance, a scheduler, kernel profiler, or VM system) by object
160c5b193bfSPoul-Henning Kamp  * module.  Finally, it allows for optional "kernel threads".
161df8bae1dSRodney W. Grimes  */
16226f9a767SRodney W. Grimes void
16337b087a6SPeter Wemm mi_startup(void)
164df8bae1dSRodney W. Grimes {
1652b14f991SJulian Elischer 
1662b14f991SJulian Elischer 	register struct sysinit **sipp;		/* system initialization*/
1672b14f991SJulian Elischer 	register struct sysinit **xipp;		/* interior loop of sort*/
1682b14f991SJulian Elischer 	register struct sysinit *save;		/* bubble*/
1692b14f991SJulian Elischer 
170f41325dbSPeter Wemm 	if (sysinit == NULL) {
171f41325dbSPeter Wemm 		sysinit = SET_BEGIN(sysinit_set);
172f41325dbSPeter Wemm 		sysinit_end = SET_LIMIT(sysinit_set);
173f41325dbSPeter Wemm 	}
174f41325dbSPeter Wemm 
17594e9d7c1SPeter Wemm restart:
1762b14f991SJulian Elischer 	/*
1772b14f991SJulian Elischer 	 * Perform a bubble sort of the system initialization objects by
1782b14f991SJulian Elischer 	 * their subsystem (primary key) and order (secondary key).
1792b14f991SJulian Elischer 	 */
180f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
181f41325dbSPeter Wemm 		for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
1822b14f991SJulian Elischer 			if ((*sipp)->subsystem < (*xipp)->subsystem ||
1832b14f991SJulian Elischer 			     ((*sipp)->subsystem == (*xipp)->subsystem &&
184af4b2d2dSPeter Wemm 			      (*sipp)->order <= (*xipp)->order))
1852b14f991SJulian Elischer 				continue;	/* skip*/
1862b14f991SJulian Elischer 			save = *sipp;
1872b14f991SJulian Elischer 			*sipp = *xipp;
1882b14f991SJulian Elischer 			*xipp = save;
1892b14f991SJulian Elischer 		}
1902b14f991SJulian Elischer 	}
1912b14f991SJulian Elischer 
1922b14f991SJulian Elischer 	/*
1932b14f991SJulian Elischer 	 * Traverse the (now) ordered list of system initialization tasks.
1942b14f991SJulian Elischer 	 * Perform each task, and continue on to the next task.
1952b14f991SJulian Elischer 	 *
1962b14f991SJulian Elischer 	 * The last item on the list is expected to be the scheduler,
1972b14f991SJulian Elischer 	 * which will not return.
1982b14f991SJulian Elischer 	 */
199f41325dbSPeter Wemm 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
20074b2192aSJohn Dyson 
2012b14f991SJulian Elischer 		if ((*sipp)->subsystem == SI_SUB_DUMMY)
2022b14f991SJulian Elischer 			continue;	/* skip dummy task(s)*/
2032b14f991SJulian Elischer 
20494e9d7c1SPeter Wemm 		if ((*sipp)->subsystem == SI_SUB_DONE)
20594e9d7c1SPeter Wemm 			continue;
20694e9d7c1SPeter Wemm 
2079c8b8baaSPeter Wemm 		/* Call function */
2082b14f991SJulian Elischer 		(*((*sipp)->func))((*sipp)->udata);
20994e9d7c1SPeter Wemm 
21094e9d7c1SPeter Wemm 		/* Check off the one we're just done */
21194e9d7c1SPeter Wemm 		(*sipp)->subsystem = SI_SUB_DONE;
21294e9d7c1SPeter Wemm 
21394e9d7c1SPeter Wemm 		/* Check if we've installed more sysinit items via KLD */
21494e9d7c1SPeter Wemm 		if (newsysinit != NULL) {
215f41325dbSPeter Wemm 			if (sysinit != SET_BEGIN(sysinit_set))
21694e9d7c1SPeter Wemm 				free(sysinit, M_TEMP);
21794e9d7c1SPeter Wemm 			sysinit = newsysinit;
218f41325dbSPeter Wemm 			sysinit_end = newsysinit_end;
21994e9d7c1SPeter Wemm 			newsysinit = NULL;
220f41325dbSPeter Wemm 			newsysinit_end = NULL;
22194e9d7c1SPeter Wemm 			goto restart;
22294e9d7c1SPeter Wemm 		}
2232b14f991SJulian Elischer 	}
2242b14f991SJulian Elischer 
225477a642cSPeter Wemm 	panic("Shouldn't get here!");
2262b14f991SJulian Elischer 	/* NOTREACHED*/
2272b14f991SJulian Elischer }
2282b14f991SJulian Elischer 
2292b14f991SJulian Elischer 
2302b14f991SJulian Elischer /*
2312b14f991SJulian Elischer  ***************************************************************************
2322b14f991SJulian Elischer  ****
2332b14f991SJulian Elischer  **** The following SYSINIT's belong elsewhere, but have not yet
2342b14f991SJulian Elischer  **** been moved.
2352b14f991SJulian Elischer  ****
2362b14f991SJulian Elischer  ***************************************************************************
2372b14f991SJulian Elischer  */
2389ef6c28aSBruce Evans static void
23937b087a6SPeter Wemm print_caddr_t(void *data __unused)
2409ef6c28aSBruce Evans {
2419ef6c28aSBruce Evans 	printf("%s", (char *)data);
2429ef6c28aSBruce Evans }
243d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
2447a08bae6SJohn Baldwin SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, version)
2457a08bae6SJohn Baldwin 
2462cf6bdacSPoul-Henning Kamp #ifdef WITNESS
2472cf6bdacSPoul-Henning Kamp static char wit_warn[] =
2482cf6bdacSPoul-Henning Kamp      "WARNING: WITNESS option enabled, expect reduced performance.\n";
2492cf6bdacSPoul-Henning Kamp SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_SECOND + 1,
2502cf6bdacSPoul-Henning Kamp    print_caddr_t, wit_warn)
2512cf6bdacSPoul-Henning Kamp #endif
2522cf6bdacSPoul-Henning Kamp 
2532cf6bdacSPoul-Henning Kamp #ifdef DIAGNOSTIC
2542cf6bdacSPoul-Henning Kamp static char diag_warn[] =
2552cf6bdacSPoul-Henning Kamp      "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
2562cf6bdacSPoul-Henning Kamp SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_SECOND + 2,
2572cf6bdacSPoul-Henning Kamp     print_caddr_t, diag_warn)
2582cf6bdacSPoul-Henning Kamp #endif
2592cf6bdacSPoul-Henning Kamp 
2607a08bae6SJohn Baldwin static void
2617a08bae6SJohn Baldwin set_boot_verbose(void *data __unused)
2627a08bae6SJohn Baldwin {
2637a08bae6SJohn Baldwin 
2647a08bae6SJohn Baldwin 	if (boothowto & RB_VERBOSE)
2657a08bae6SJohn Baldwin 		bootverbose++;
2667a08bae6SJohn Baldwin }
2677a08bae6SJohn Baldwin SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL)
2682b14f991SJulian Elischer 
269f36ba452SJake Burkholder struct sysentvec null_sysvec = {
270f36ba452SJake Burkholder 	0,
271f36ba452SJake Burkholder 	NULL,
272f36ba452SJake Burkholder 	0,
273f36ba452SJake Burkholder 	0,
274f36ba452SJake Burkholder 	NULL,
275f36ba452SJake Burkholder 	0,
276f36ba452SJake Burkholder 	NULL,
277f36ba452SJake Burkholder 	NULL,
278f36ba452SJake Burkholder 	NULL,
279f36ba452SJake Burkholder 	NULL,
280f36ba452SJake Burkholder 	NULL,
281f36ba452SJake Burkholder 	NULL,
282f36ba452SJake Burkholder 	NULL,
283f36ba452SJake Burkholder 	"null",
284f36ba452SJake Burkholder 	NULL,
285f36ba452SJake Burkholder 	NULL,
286f36ba452SJake Burkholder 	0,
287f36ba452SJake Burkholder 	PAGE_SIZE,
288f36ba452SJake Burkholder 	VM_MIN_ADDRESS,
289f36ba452SJake Burkholder 	VM_MAXUSER_ADDRESS,
290f36ba452SJake Burkholder 	USRSTACK,
291f36ba452SJake Burkholder 	PS_STRINGS,
292f36ba452SJake Burkholder 	VM_PROT_ALL,
293f36ba452SJake Burkholder 	NULL,
294c460ac3aSPeter Wemm 	NULL,
295f36ba452SJake Burkholder 	NULL
296f36ba452SJake Burkholder };
2973ebc1248SPeter Wemm 
2982b14f991SJulian Elischer /*
2992b14f991SJulian Elischer  ***************************************************************************
3002b14f991SJulian Elischer  ****
3010c920c0dSGiorgos Keramidas  **** The two following SYSINIT's are proc0 specific glue code.  I am not
3022b14f991SJulian Elischer  **** convinced that they can not be safely combined, but their order of
3032b14f991SJulian Elischer  **** operation has been maintained as the same as the original init_main.c
3042b14f991SJulian Elischer  **** for right now.
3052b14f991SJulian Elischer  ****
3062b14f991SJulian Elischer  **** These probably belong in init_proc.c or kern_proc.c, since they
3072b14f991SJulian Elischer  **** deal with proc0 (the fork template process).
3082b14f991SJulian Elischer  ****
3092b14f991SJulian Elischer  ***************************************************************************
3102b14f991SJulian Elischer  */
3112b14f991SJulian Elischer /* ARGSUSED*/
312154c04e5SPoul-Henning Kamp static void
31337b087a6SPeter Wemm proc0_init(void *dummy __unused)
3142b14f991SJulian Elischer {
3158ec21e3aSPoul-Henning Kamp 	struct proc *p;
3168ec21e3aSPoul-Henning Kamp 	unsigned i;
317b40ce416SJulian Elischer 	struct thread *td;
318079b7badSJulian Elischer 	struct ksegrp *kg;
319df8bae1dSRodney W. Grimes 
3200cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
321df8bae1dSRodney W. Grimes 	p = &proc0;
322079b7badSJulian Elischer 	td = &thread0;
3234f0db5e0SJulian Elischer 	kg = &ksegrp0;
324df8bae1dSRodney W. Grimes 
325df8bae1dSRodney W. Grimes 	/*
3260384fff8SJason Evans 	 * Initialize magic number.
3270384fff8SJason Evans 	 */
3280384fff8SJason Evans 	p->p_magic = P_MAGIC;
3290384fff8SJason Evans 
3300384fff8SJason Evans 	/*
331ed062c8dSJulian Elischer 	 * Initialize thread, process and ksegrp structures.
332a3bfb996SJeffrey Hsu 	 */
333ed062c8dSJulian Elischer 	procinit();	/* set up proc zone */
334ed062c8dSJulian Elischer 	threadinit();	/* set up thead, upcall and KSEGRP zones */
335a3bfb996SJeffrey Hsu 
336a3bfb996SJeffrey Hsu 	/*
337ed062c8dSJulian Elischer 	 * Initialise scheduler resources.
338ed062c8dSJulian Elischer 	 * Add scheduler specific parts to proc, ksegrp, thread as needed.
339ed062c8dSJulian Elischer 	 */
340ed062c8dSJulian Elischer 	schedinit();	/* scheduler gets its house in order */
341ed062c8dSJulian Elischer 	/*
342b1508c72SDavid Greenman 	 * Initialize sleep queue hash table
343b1508c72SDavid Greenman 	 */
344b1508c72SDavid Greenman 	sleepinit();
345b1508c72SDavid Greenman 
346b1508c72SDavid Greenman 	/*
3473075778bSJohn Dyson 	 * additional VM structures
3483075778bSJohn Dyson 	 */
3493075778bSJohn Dyson 	vm_init2();
3503075778bSJohn Dyson 
3513075778bSJohn Dyson 	/*
352df8bae1dSRodney W. Grimes 	 * Create process 0 (the swapper).
353df8bae1dSRodney W. Grimes 	 */
354a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&allproc, p, p_list);
3557b531e60SJohn Baldwin 	LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
3566008862bSJohn Baldwin 	mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
357df8bae1dSRodney W. Grimes 	p->p_pgrp = &pgrp0;
358a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
359a3bfb996SJeffrey Hsu 	LIST_INIT(&pgrp0.pg_members);
360a3bfb996SJeffrey Hsu 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
361a3bfb996SJeffrey Hsu 
362df8bae1dSRodney W. Grimes 	pgrp0.pg_session = &session0;
3636008862bSJohn Baldwin 	mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
364df8bae1dSRodney W. Grimes 	session0.s_count = 1;
365df8bae1dSRodney W. Grimes 	session0.s_leader = p;
366df8bae1dSRodney W. Grimes 
3673ebc1248SPeter Wemm 	p->p_sysent = &null_sysvec;
368f202965eSJohn Baldwin 	p->p_flag = P_SYSTEM;
369f202965eSJohn Baldwin 	p->p_sflag = PS_INMEM;
370e602ba25SJulian Elischer 	p->p_state = PRS_NORMAL;
371571dcd15SSuleiman Souhlal 	knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL);
3722c255e9dSRobert Watson 	STAILQ_INIT(&p->p_ktr);
373fa885116SJulian Elischer 	p->p_nice = NZERO;
374e602ba25SJulian Elischer 	td->td_state = TDS_RUNNING;
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;
379060563ecSJulian Elischer 	td->td_oncpu = 0;
3802c1011f7SJohn Dyson 	p->p_peers = 0;
3812c1011f7SJohn Dyson 	p->p_leader = p;
382e602ba25SJulian Elischer 
3832c1011f7SJohn Dyson 
384df8bae1dSRodney W. Grimes 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
385df8bae1dSRodney W. Grimes 
386c06eb4e2SSam Leffler 	callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
387c06eb4e2SSam Leffler 	callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
3884f559836SJake Burkholder 
389df8bae1dSRodney W. Grimes 	/* Create credentials. */
390df8bae1dSRodney W. Grimes 	p->p_ucred = crget();
391df8bae1dSRodney W. Grimes 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
392f535380cSDon Lewis 	p->p_ucred->cr_uidinfo = uifind(0);
393b1fc0ec1SRobert Watson 	p->p_ucred->cr_ruidinfo = uifind(0);
39491421ba2SRobert Watson 	p->p_ucred->cr_prison = NULL;	/* Don't jail it. */
39540244964SRobert Watson #ifdef MAC
39640244964SRobert Watson 	mac_create_proc0(p->p_ucred);
39740244964SRobert Watson #endif
3988e2e767bSJohn Baldwin 	td->td_ucred = crhold(p->p_ucred);
39975c13541SPoul-Henning Kamp 
40090af4afaSJohn Baldwin 	/* Create sigacts. */
40190af4afaSJohn Baldwin 	p->p_sigacts = sigacts_alloc();
4026626c604SJulian Elischer 
40337b087a6SPeter Wemm 	/* Initialize signal state for process 0. */
40437b087a6SPeter Wemm 	siginit(&proc0);
40537b087a6SPeter Wemm 
406df8bae1dSRodney W. Grimes 	/* Create the file descriptor table. */
4078ec21e3aSPoul-Henning Kamp 	p->p_fd = fdinit(NULL);
408ad05d580STor Egge 	p->p_fdtol = NULL;
409df8bae1dSRodney W. Grimes 
410df8bae1dSRodney W. Grimes 	/* Create the limits structures. */
41191d5354aSJohn Baldwin 	p->p_limit = lim_alloc();
41291d5354aSJohn Baldwin 	for (i = 0; i < RLIM_NLIMITS; i++)
41391d5354aSJohn Baldwin 		p->p_limit->pl_rlimit[i].rlim_cur =
41491d5354aSJohn Baldwin 		    p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
41591d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
41691d5354aSJohn Baldwin 	    p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
41791d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
41891d5354aSJohn Baldwin 	    p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
419df8bae1dSRodney W. Grimes 	i = ptoa(cnt.v_free_count);
42091d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i;
42191d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
42291d5354aSJohn Baldwin 	p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
4235715307fSJohn Baldwin 	p->p_cpulimit = RLIM_INFINITY;
424df8bae1dSRodney W. Grimes 
4258b059651SDavid Schultz 	p->p_stats = pstats_alloc();
4268b059651SDavid Schultz 
427df8bae1dSRodney W. Grimes 	/* Allocate a prototype map so we have something to fork. */
428b1028ad1SLuoqi Chen 	pmap_pinit0(vmspace_pmap(&vmspace0));
429df8bae1dSRodney W. Grimes 	p->p_vmspace = &vmspace0;
430df8bae1dSRodney W. Grimes 	vmspace0.vm_refcnt = 1;
43105ba50f5SJake Burkholder 	vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
43205ba50f5SJake Burkholder 	    p->p_sysent->sv_maxuser);
433b1028ad1SLuoqi Chen 	vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
434df8bae1dSRodney W. Grimes 
43539fb8e6bSJulian Elischer 	/*
436a3bfb996SJeffrey Hsu 	 * Charge root for one process.
437df8bae1dSRodney W. Grimes 	 */
438b1fc0ec1SRobert Watson 	(void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
43926f9a767SRodney W. Grimes }
4402b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
4412b14f991SJulian Elischer 
4422b14f991SJulian Elischer /* ARGSUSED*/
443154c04e5SPoul-Henning Kamp static void
44437b087a6SPeter Wemm proc0_post(void *dummy __unused)
4452b14f991SJulian Elischer {
44600af9731SPoul-Henning Kamp 	struct timespec ts;
44737b087a6SPeter Wemm 	struct proc *p;
448a6fc8288SPeter Wemm 
4492b14f991SJulian Elischer 	/*
4501b0b259eSBruce Evans 	 * Now we can look at the time, having had a chance to verify the
4511b0b259eSBruce Evans 	 * time from the filesystem.  Pretend that proc0 started now.
4522b14f991SJulian Elischer 	 */
4531005a129SJohn Baldwin 	sx_slock(&allproc_lock);
45437b087a6SPeter Wemm 	LIST_FOREACH(p, &allproc, p_list) {
45587ccef7bSDag-Erling Smørgrav 		microuptime(&p->p_stats->p_start);
45678c85e8dSJohn Baldwin 		p->p_rux.rux_runtime.sec = 0;
45778c85e8dSJohn Baldwin 		p->p_rux.rux_runtime.frac = 0;
45837b087a6SPeter Wemm 	}
4591005a129SJohn Baldwin 	sx_sunlock(&allproc_lock);
460e2256f43SPeter Wemm 	binuptime(PCPU_PTR(switchtime));
4610384fff8SJason Evans 	PCPU_SET(switchticks, ticks);
4622b14f991SJulian Elischer 
463a6fc8288SPeter Wemm 	/*
464a6fc8288SPeter Wemm 	 * Give the ``random'' number generator a thump.
465a6fc8288SPeter Wemm 	 */
46600af9731SPoul-Henning Kamp 	nanotime(&ts);
46700af9731SPoul-Henning Kamp 	srandom(ts.tv_sec ^ ts.tv_nsec);
4682b14f991SJulian Elischer }
4692b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
4702b14f991SJulian Elischer 
471df8bae1dSRodney W. Grimes /*
4722b14f991SJulian Elischer  ***************************************************************************
4732b14f991SJulian Elischer  ****
4742b14f991SJulian Elischer  **** The following SYSINIT's and glue code should be moved to the
4752b14f991SJulian Elischer  **** respective files on a per subsystem basis.
4762b14f991SJulian Elischer  ****
4772b14f991SJulian Elischer  ***************************************************************************
478df8bae1dSRodney W. Grimes  */
479df8bae1dSRodney W. Grimes 
480df8bae1dSRodney W. Grimes 
481df8bae1dSRodney W. Grimes /*
4822b14f991SJulian Elischer  ***************************************************************************
4832b14f991SJulian Elischer  ****
4842b14f991SJulian Elischer  **** The following code probably belongs in another file, like
48537b087a6SPeter Wemm  **** kern/init_init.c.
4862b14f991SJulian Elischer  ****
4872b14f991SJulian Elischer  ***************************************************************************
488df8bae1dSRodney W. Grimes  */
489df8bae1dSRodney W. Grimes 
490df8bae1dSRodney W. Grimes /*
491df8bae1dSRodney W. Grimes  * List of paths to try when searching for "init".
492df8bae1dSRodney W. Grimes  */
4935f967b24SDag-Erling Smørgrav static char init_path[MAXPATHLEN] =
49467481196SJohn Birrell #ifdef	INIT_PATH
49567481196SJohn Birrell     __XSTRING(INIT_PATH);
49667481196SJohn Birrell #else
497f3f4baf0SDag-Erling Smørgrav     "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall";
49867481196SJohn Birrell #endif
499af1408e3SLuigi Rizzo SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
500af1408e3SLuigi Rizzo 	"Path used to search the init process");
501df8bae1dSRodney W. Grimes 
502df8bae1dSRodney W. Grimes /*
503724447acSRalf S. Engelschall  * Shutdown timeout of init(8).
504724447acSRalf S. Engelschall  * Unused within kernel, but used to control init(8), hence do not remove.
505724447acSRalf S. Engelschall  */
506724447acSRalf S. Engelschall #ifndef INIT_SHUTDOWN_TIMEOUT
507724447acSRalf S. Engelschall #define INIT_SHUTDOWN_TIMEOUT 120
508724447acSRalf S. Engelschall #endif
509724447acSRalf S. Engelschall static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT;
510724447acSRalf S. Engelschall SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
511724447acSRalf S. Engelschall 	CTLFLAG_RW, &init_shutdown_timeout, 0, "");
512724447acSRalf S. Engelschall 
513724447acSRalf S. Engelschall /*
5145f967b24SDag-Erling Smørgrav  * Start the initial user process; try exec'ing each pathname in init_path.
515df8bae1dSRodney W. Grimes  * The program is invoked with one argument containing the boot flags.
516df8bae1dSRodney W. Grimes  */
517df8bae1dSRodney W. Grimes static void
51837b087a6SPeter Wemm start_init(void *dummy)
519df8bae1dSRodney W. Grimes {
520df8bae1dSRodney W. Grimes 	vm_offset_t addr;
521df8bae1dSRodney W. Grimes 	struct execve_args args;
5225f967b24SDag-Erling Smørgrav 	int options, error;
5235f967b24SDag-Erling Smørgrav 	char *var, *path, *next, *s;
5245f967b24SDag-Erling Smørgrav 	char *ucp, **uap, *arg0, *arg1;
525b40ce416SJulian Elischer 	struct thread *td;
5269c8b8baaSPeter Wemm 	struct proc *p;
527df8bae1dSRodney W. Grimes 
5289ed346baSBosko Milekic 	mtx_lock(&Giant);
5290384fff8SJason Evans 
5300cddd8f0SMatthew Dillon 	GIANT_REQUIRED;
5310cddd8f0SMatthew Dillon 
532b40ce416SJulian Elischer 	td = curthread;
533b40ce416SJulian Elischer 	p = td->td_proc;
534df8bae1dSRodney W. Grimes 
535563af2ecSMaxime Henrion 	vfs_mountroot();
536fb92273bSPoul-Henning Kamp 
537b7116168SPeter Wemm 	/*
538df8bae1dSRodney W. Grimes 	 * Need just enough stack to hold the faked-up "execve()" arguments.
539df8bae1dSRodney W. Grimes 	 */
54005ba50f5SJake Burkholder 	addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
5415f967b24SDag-Erling Smørgrav 	if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
5425f967b24SDag-Erling Smørgrav 			FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
543df8bae1dSRodney W. Grimes 		panic("init: couldn't allocate argument space");
544df8bae1dSRodney W. Grimes 	p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
54526f9a767SRodney W. Grimes 	p->p_vmspace->vm_ssize = 1;
546df8bae1dSRodney W. Grimes 
5475f967b24SDag-Erling Smørgrav 	if ((var = getenv("init_path")) != NULL) {
548e80fb434SRobert Drehmel 		strlcpy(init_path, var, sizeof(init_path));
549d786139cSMaxime Henrion 		freeenv(var);
5505f967b24SDag-Erling Smørgrav 	}
5515f967b24SDag-Erling Smørgrav 
55267481196SJohn Birrell 	for (path = init_path; *path != '\0'; path = next) {
553e4082284SJohn Birrell 		while (*path == ':')
5545f967b24SDag-Erling Smørgrav 			path++;
55567481196SJohn Birrell 		if (*path == '\0')
5565f967b24SDag-Erling Smørgrav 			break;
557e4082284SJohn Birrell 		for (next = path; *next != '\0' && *next != ':'; next++)
5585f967b24SDag-Erling Smørgrav 			/* nothing */ ;
5595f967b24SDag-Erling Smørgrav 		if (bootverbose)
560ba41a07dSDmitrij Tejblum 			printf("start_init: trying %.*s\n", (int)(next - path),
561ba41a07dSDmitrij Tejblum 			    path);
5625f967b24SDag-Erling Smørgrav 
563df8bae1dSRodney W. Grimes 		/*
564df8bae1dSRodney W. Grimes 		 * Move out the boot flag argument.
565df8bae1dSRodney W. Grimes 		 */
566df8bae1dSRodney W. Grimes 		options = 0;
56705ba50f5SJake Burkholder 		ucp = (char *)p->p_sysent->sv_usrstack;
568df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, 0);		/* trailing zero */
569df8bae1dSRodney W. Grimes 		if (boothowto & RB_SINGLE) {
570df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 's');
571df8bae1dSRodney W. Grimes 			options = 1;
572df8bae1dSRodney W. Grimes 		}
573df8bae1dSRodney W. Grimes #ifdef notyet
574df8bae1dSRodney W. Grimes                 if (boothowto & RB_FASTBOOT) {
575df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, 'f');
576df8bae1dSRodney W. Grimes 			options = 1;
577df8bae1dSRodney W. Grimes 		}
578df8bae1dSRodney W. Grimes #endif
57917755ac8SPoul-Henning Kamp 
58017755ac8SPoul-Henning Kamp #ifdef BOOTCDROM
58117755ac8SPoul-Henning Kamp 		(void)subyte(--ucp, 'C');
58217755ac8SPoul-Henning Kamp 		options = 1;
58317755ac8SPoul-Henning Kamp #endif
584db901281SPoul-Henning Kamp 
585df8bae1dSRodney W. Grimes 		if (options == 0)
586df8bae1dSRodney W. Grimes 			(void)subyte(--ucp, '-');
587df8bae1dSRodney W. Grimes 		(void)subyte(--ucp, '-');		/* leading hyphen */
588df8bae1dSRodney W. Grimes 		arg1 = ucp;
589df8bae1dSRodney W. Grimes 
590df8bae1dSRodney W. Grimes 		/*
591df8bae1dSRodney W. Grimes 		 * Move out the file name (also arg 0).
592df8bae1dSRodney W. Grimes 		 */
5935f967b24SDag-Erling Smørgrav 		(void)subyte(--ucp, 0);
5945f967b24SDag-Erling Smørgrav 		for (s = next - 1; s >= path; s--)
5955f967b24SDag-Erling Smørgrav 			(void)subyte(--ucp, *s);
596df8bae1dSRodney W. Grimes 		arg0 = ucp;
597df8bae1dSRodney W. Grimes 
598df8bae1dSRodney W. Grimes 		/*
599df8bae1dSRodney W. Grimes 		 * Move out the arg pointers.
600df8bae1dSRodney W. Grimes 		 */
601a20d7755SDoug Rabson 		uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
602c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)0);	/* terminator */
603c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
604c2da0fd9SBruce Evans 		(void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
605df8bae1dSRodney W. Grimes 
606df8bae1dSRodney W. Grimes 		/*
607df8bae1dSRodney W. Grimes 		 * Point at the arguments.
608df8bae1dSRodney W. Grimes 		 */
609df8bae1dSRodney W. Grimes 		args.fname = arg0;
61026f9a767SRodney W. Grimes 		args.argv = uap;
61126f9a767SRodney W. Grimes 		args.envv = NULL;
612df8bae1dSRodney W. Grimes 
613df8bae1dSRodney W. Grimes 		/*
614df8bae1dSRodney W. Grimes 		 * Now try to exec the program.  If can't for any reason
615df8bae1dSRodney W. Grimes 		 * other than it doesn't exist, complain.
6162b14f991SJulian Elischer 		 *
61737b087a6SPeter Wemm 		 * Otherwise, return via fork_trampoline() all the way
6189c8b8baaSPeter Wemm 		 * to user mode as init!
619df8bae1dSRodney W. Grimes 		 */
620b40ce416SJulian Elischer 		if ((error = execve(td, &args)) == 0) {
6219ed346baSBosko Milekic 			mtx_unlock(&Giant);
622df8bae1dSRodney W. Grimes 			return;
623db72809dSJohn Baldwin 		}
624df8bae1dSRodney W. Grimes 		if (error != ENOENT)
625ba41a07dSDmitrij Tejblum 			printf("exec %.*s: error %d\n", (int)(next - path),
626ba41a07dSDmitrij Tejblum 			    path, error);
627df8bae1dSRodney W. Grimes 	}
628580e7e5aSGreg Lehey 	printf("init: not found in path %s\n", init_path);
629df8bae1dSRodney W. Grimes 	panic("no init");
630df8bae1dSRodney W. Grimes }
63137b087a6SPeter Wemm 
63237b087a6SPeter Wemm /*
63337b087a6SPeter Wemm  * Like kthread_create(), but runs in it's own address space.
63437b087a6SPeter Wemm  * We do this early to reserve pid 1.
63537b087a6SPeter Wemm  *
63637b087a6SPeter Wemm  * Note special case - do not make it runnable yet.  Other work
63737b087a6SPeter Wemm  * in progress will change this more.
63837b087a6SPeter Wemm  */
63937b087a6SPeter Wemm static void
64037b087a6SPeter Wemm create_init(const void *udata __unused)
64137b087a6SPeter Wemm {
6425a06cb0cSRobert Watson 	struct ucred *newcred, *oldcred;
64337b087a6SPeter Wemm 	int error;
64437b087a6SPeter Wemm 
645316ec49aSScott Long 	error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
64637b087a6SPeter Wemm 	if (error)
64737b087a6SPeter Wemm 		panic("cannot fork init: %d\n", error);
648bafc8f25SRobert Watson 	KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
6495a06cb0cSRobert Watson 	/* divorce init's credentials from the kernel's */
6505a06cb0cSRobert Watson 	newcred = crget();
651f202965eSJohn Baldwin 	PROC_LOCK(initproc);
652f202965eSJohn Baldwin 	initproc->p_flag |= P_SYSTEM;
6535a06cb0cSRobert Watson 	oldcred = initproc->p_ucred;
6545a06cb0cSRobert Watson 	crcopy(newcred, oldcred);
65540244964SRobert Watson #ifdef MAC
65640244964SRobert Watson 	mac_create_proc1(newcred);
65740244964SRobert Watson #endif
6585a06cb0cSRobert Watson 	initproc->p_ucred = newcred;
659f202965eSJohn Baldwin 	PROC_UNLOCK(initproc);
6605a06cb0cSRobert Watson 	crfree(oldcred);
6614d1a4bb7SRobert Watson 	cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
6629ed346baSBosko Milekic 	mtx_lock_spin(&sched_lock);
663f202965eSJohn Baldwin 	initproc->p_sflag |= PS_INMEM;
6649ed346baSBosko Milekic 	mtx_unlock_spin(&sched_lock);
665079b7badSJulian Elischer 	cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
66637b087a6SPeter Wemm }
66737b087a6SPeter Wemm SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
66837b087a6SPeter Wemm 
66937b087a6SPeter Wemm /*
67037b087a6SPeter Wemm  * Make it runnable now.
67137b087a6SPeter Wemm  */
67237b087a6SPeter Wemm static void
67337b087a6SPeter Wemm kick_init(const void *udata __unused)
67437b087a6SPeter Wemm {
675079b7badSJulian Elischer 	struct thread *td;
676f202965eSJohn Baldwin 
677079b7badSJulian Elischer 	td = FIRST_THREAD_IN_PROC(initproc);
6789ed346baSBosko Milekic 	mtx_lock_spin(&sched_lock);
67971fad9fdSJulian Elischer 	TD_SET_CAN_RUN(td);
6802630e4c9SJulian Elischer 	setrunqueue(td, SRQ_BORING);	/* XXXKSE */
6819ed346baSBosko Milekic 	mtx_unlock_spin(&sched_lock);
68237b087a6SPeter Wemm }
68337b087a6SPeter Wemm SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)
684