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; 972a3b1065SOlivier Houchard struct thread thread0 __aligned(8); 988460a577SJohn Birrell #ifdef KSE 994f0db5e0SJulian Elischer struct ksegrp ksegrp0; 1008460a577SJohn Birrell #endif 10123734995SJake Burkholder struct vmspace vmspace0; 1022b14f991SJulian Elischer struct proc *initproc; 103df8bae1dSRodney W. Grimes 104c463cf1cSBruce Evans int boothowto = 0; /* initialized so that it can be patched */ 1058d0bf3d6SJordan K. Hubbard SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, ""); 1067a08bae6SJohn Baldwin int bootverbose; 1077a08bae6SJohn Baldwin SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, ""); 108946bb7a2SPoul-Henning Kamp 1092b14f991SJulian Elischer /* 1102b14f991SJulian Elischer * This ensures that there is at least one entry so that the sysinit_set 1112b14f991SJulian Elischer * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never 1122b14f991SJulian Elischer * executed. 11326f9a767SRodney W. Grimes */ 1142b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL) 1158a129caeSDavid Greenman 11694e9d7c1SPeter Wemm /* 11794e9d7c1SPeter Wemm * The sysinit table itself. Items are checked off as the are run. 11894e9d7c1SPeter Wemm * If we want to register new sysinit types, add them to newsysinit. 11994e9d7c1SPeter Wemm */ 120f41325dbSPeter Wemm SET_DECLARE(sysinit_set, struct sysinit); 121f41325dbSPeter Wemm struct sysinit **sysinit, **sysinit_end; 122f41325dbSPeter Wemm struct sysinit **newsysinit, **newsysinit_end; 12394e9d7c1SPeter Wemm 12494e9d7c1SPeter Wemm /* 12594e9d7c1SPeter Wemm * Merge a new sysinit set into the current set, reallocating it if 12694e9d7c1SPeter Wemm * necessary. This can only be called after malloc is running. 12794e9d7c1SPeter Wemm */ 12894e9d7c1SPeter Wemm void 129f41325dbSPeter Wemm sysinit_add(struct sysinit **set, struct sysinit **set_end) 13094e9d7c1SPeter Wemm { 13194e9d7c1SPeter Wemm struct sysinit **newset; 13294e9d7c1SPeter Wemm struct sysinit **sipp; 13394e9d7c1SPeter Wemm struct sysinit **xipp; 134f41325dbSPeter Wemm int count; 13594e9d7c1SPeter Wemm 136f41325dbSPeter Wemm count = set_end - set; 137ddd62546SPeter Wemm if (newsysinit) 138f41325dbSPeter Wemm count += newsysinit_end - newsysinit; 139ddd62546SPeter Wemm else 140f41325dbSPeter Wemm count += sysinit_end - sysinit; 14194e9d7c1SPeter Wemm newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT); 14294e9d7c1SPeter Wemm if (newset == NULL) 14394e9d7c1SPeter Wemm panic("cannot malloc for sysinit"); 14494e9d7c1SPeter Wemm xipp = newset; 145ddd62546SPeter Wemm if (newsysinit) 146f41325dbSPeter Wemm for (sipp = newsysinit; sipp < newsysinit_end; sipp++) 147ddd62546SPeter Wemm *xipp++ = *sipp; 148ddd62546SPeter Wemm else 149f41325dbSPeter Wemm for (sipp = sysinit; sipp < sysinit_end; sipp++) 15094e9d7c1SPeter Wemm *xipp++ = *sipp; 151f41325dbSPeter Wemm for (sipp = set; sipp < set_end; sipp++) 15294e9d7c1SPeter Wemm *xipp++ = *sipp; 153ddd62546SPeter Wemm if (newsysinit) 154ddd62546SPeter Wemm free(newsysinit, M_TEMP); 15594e9d7c1SPeter Wemm newsysinit = newset; 156f41325dbSPeter Wemm newsysinit_end = newset + count; 15794e9d7c1SPeter Wemm } 15826f9a767SRodney W. Grimes 159df8bae1dSRodney W. Grimes /* 160df8bae1dSRodney W. Grimes * System startup; initialize the world, create process 0, mount root 161df8bae1dSRodney W. Grimes * filesystem, and fork to create init and pagedaemon. Most of the 162df8bae1dSRodney W. Grimes * hard work is done in the lower-level initialization routines including 163df8bae1dSRodney W. Grimes * startup(), which does memory initialization and autoconfiguration. 1642b14f991SJulian Elischer * 1652b14f991SJulian Elischer * This allows simple addition of new kernel subsystems that require 1662b14f991SJulian Elischer * boot time initialization. It also allows substitution of subsystem 1672b14f991SJulian Elischer * (for instance, a scheduler, kernel profiler, or VM system) by object 168c5b193bfSPoul-Henning Kamp * module. Finally, it allows for optional "kernel threads". 169df8bae1dSRodney W. Grimes */ 17026f9a767SRodney W. Grimes void 17137b087a6SPeter Wemm mi_startup(void) 172df8bae1dSRodney W. Grimes { 1732b14f991SJulian Elischer 1742b14f991SJulian Elischer register struct sysinit **sipp; /* system initialization*/ 1752b14f991SJulian Elischer register struct sysinit **xipp; /* interior loop of sort*/ 1762b14f991SJulian Elischer register struct sysinit *save; /* bubble*/ 1772b14f991SJulian Elischer 17826ab616fSBenno Rice #if defined(VERBOSE_SYSINIT) 17926ab616fSBenno Rice int last; 18026ab616fSBenno Rice int verbose; 18126ab616fSBenno Rice #endif 18226ab616fSBenno Rice 183f41325dbSPeter Wemm if (sysinit == NULL) { 184f41325dbSPeter Wemm sysinit = SET_BEGIN(sysinit_set); 185f41325dbSPeter Wemm sysinit_end = SET_LIMIT(sysinit_set); 186f41325dbSPeter Wemm } 187f41325dbSPeter Wemm 18894e9d7c1SPeter Wemm restart: 1892b14f991SJulian Elischer /* 1902b14f991SJulian Elischer * Perform a bubble sort of the system initialization objects by 1912b14f991SJulian Elischer * their subsystem (primary key) and order (secondary key). 1922b14f991SJulian Elischer */ 193f41325dbSPeter Wemm for (sipp = sysinit; sipp < sysinit_end; sipp++) { 194f41325dbSPeter Wemm for (xipp = sipp + 1; xipp < sysinit_end; xipp++) { 1952b14f991SJulian Elischer if ((*sipp)->subsystem < (*xipp)->subsystem || 1962b14f991SJulian Elischer ((*sipp)->subsystem == (*xipp)->subsystem && 197af4b2d2dSPeter Wemm (*sipp)->order <= (*xipp)->order)) 1982b14f991SJulian Elischer continue; /* skip*/ 1992b14f991SJulian Elischer save = *sipp; 2002b14f991SJulian Elischer *sipp = *xipp; 2012b14f991SJulian Elischer *xipp = save; 2022b14f991SJulian Elischer } 2032b14f991SJulian Elischer } 2042b14f991SJulian Elischer 20526ab616fSBenno Rice #if defined(VERBOSE_SYSINIT) 20626ab616fSBenno Rice last = SI_SUB_COPYRIGHT; 20726ab616fSBenno Rice verbose = 0; 20826ab616fSBenno Rice #if !defined(DDB) 20926ab616fSBenno Rice printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n"); 21026ab616fSBenno Rice #endif 21126ab616fSBenno Rice #endif 21226ab616fSBenno Rice 2132b14f991SJulian Elischer /* 2142b14f991SJulian Elischer * Traverse the (now) ordered list of system initialization tasks. 2152b14f991SJulian Elischer * Perform each task, and continue on to the next task. 2162b14f991SJulian Elischer * 2172b14f991SJulian Elischer * The last item on the list is expected to be the scheduler, 2182b14f991SJulian Elischer * which will not return. 2192b14f991SJulian Elischer */ 220f41325dbSPeter Wemm for (sipp = sysinit; sipp < sysinit_end; sipp++) { 22174b2192aSJohn Dyson 2222b14f991SJulian Elischer if ((*sipp)->subsystem == SI_SUB_DUMMY) 2232b14f991SJulian Elischer continue; /* skip dummy task(s)*/ 2242b14f991SJulian Elischer 22594e9d7c1SPeter Wemm if ((*sipp)->subsystem == SI_SUB_DONE) 22694e9d7c1SPeter Wemm continue; 22794e9d7c1SPeter Wemm 22826ab616fSBenno Rice #if defined(VERBOSE_SYSINIT) 22926ab616fSBenno Rice if ((*sipp)->subsystem > last) { 23026ab616fSBenno Rice verbose = 1; 23126ab616fSBenno Rice last = (*sipp)->subsystem; 23226ab616fSBenno Rice printf("subsystem %x\n", last); 23326ab616fSBenno Rice } 23426ab616fSBenno Rice if (verbose) { 23526ab616fSBenno Rice #if defined(DDB) 23626ab616fSBenno Rice const char *name; 23726ab616fSBenno Rice c_db_sym_t sym; 23826ab616fSBenno Rice db_expr_t offset; 23926ab616fSBenno Rice 24026ab616fSBenno Rice sym = db_search_symbol((vm_offset_t)(*sipp)->func, 24126ab616fSBenno Rice DB_STGY_PROC, &offset); 24226ab616fSBenno Rice db_symbol_values(sym, &name, NULL); 24326ab616fSBenno Rice if (name != NULL) 24426ab616fSBenno Rice printf(" %s(%p)... ", name, (*sipp)->udata); 24526ab616fSBenno Rice else 24626ab616fSBenno Rice #endif 24726ab616fSBenno Rice printf(" %p(%p)... ", (*sipp)->func, 24826ab616fSBenno Rice (*sipp)->udata); 24926ab616fSBenno Rice } 25026ab616fSBenno Rice #endif 25126ab616fSBenno Rice 2529c8b8baaSPeter Wemm /* Call function */ 2532b14f991SJulian Elischer (*((*sipp)->func))((*sipp)->udata); 25494e9d7c1SPeter Wemm 25526ab616fSBenno Rice #if defined(VERBOSE_SYSINIT) 25626ab616fSBenno Rice if (verbose) 25726ab616fSBenno Rice printf("done.\n"); 25826ab616fSBenno Rice #endif 25926ab616fSBenno Rice 26094e9d7c1SPeter Wemm /* Check off the one we're just done */ 26194e9d7c1SPeter Wemm (*sipp)->subsystem = SI_SUB_DONE; 26294e9d7c1SPeter Wemm 26394e9d7c1SPeter Wemm /* Check if we've installed more sysinit items via KLD */ 26494e9d7c1SPeter Wemm if (newsysinit != NULL) { 265f41325dbSPeter Wemm if (sysinit != SET_BEGIN(sysinit_set)) 26694e9d7c1SPeter Wemm free(sysinit, M_TEMP); 26794e9d7c1SPeter Wemm sysinit = newsysinit; 268f41325dbSPeter Wemm sysinit_end = newsysinit_end; 26994e9d7c1SPeter Wemm newsysinit = NULL; 270f41325dbSPeter Wemm newsysinit_end = NULL; 27194e9d7c1SPeter Wemm goto restart; 27294e9d7c1SPeter Wemm } 2732b14f991SJulian Elischer } 2742b14f991SJulian Elischer 275477a642cSPeter Wemm panic("Shouldn't get here!"); 2762b14f991SJulian Elischer /* NOTREACHED*/ 2772b14f991SJulian Elischer } 2782b14f991SJulian Elischer 2792b14f991SJulian Elischer 2802b14f991SJulian Elischer /* 2812b14f991SJulian Elischer *************************************************************************** 2822b14f991SJulian Elischer **** 2832b14f991SJulian Elischer **** The following SYSINIT's belong elsewhere, but have not yet 2842b14f991SJulian Elischer **** been moved. 2852b14f991SJulian Elischer **** 2862b14f991SJulian Elischer *************************************************************************** 2872b14f991SJulian Elischer */ 2889ef6c28aSBruce Evans static void 28937b087a6SPeter Wemm print_caddr_t(void *data __unused) 2909ef6c28aSBruce Evans { 2919ef6c28aSBruce Evans printf("%s", (char *)data); 2929ef6c28aSBruce Evans } 293d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) 2945add74b4SRobert Watson SYSINIT(trademark, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, trademark) 2955add74b4SRobert 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, 3012cf6bdacSPoul-Henning Kamp print_caddr_t, wit_warn) 3022cf6bdacSPoul-Henning Kamp #endif 3032cf6bdacSPoul-Henning Kamp 3042cf6bdacSPoul-Henning Kamp #ifdef DIAGNOSTIC 3052cf6bdacSPoul-Henning Kamp static char diag_warn[] = 3062cf6bdacSPoul-Henning Kamp "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n"; 30788b85279SRobert Watson SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2, 3082cf6bdacSPoul-Henning Kamp print_caddr_t, diag_warn) 3092cf6bdacSPoul-Henning Kamp #endif 3102cf6bdacSPoul-Henning Kamp 3117a08bae6SJohn Baldwin static void 3127a08bae6SJohn Baldwin set_boot_verbose(void *data __unused) 3137a08bae6SJohn Baldwin { 3147a08bae6SJohn Baldwin 3157a08bae6SJohn Baldwin if (boothowto & RB_VERBOSE) 3167a08bae6SJohn Baldwin bootverbose++; 3177a08bae6SJohn Baldwin } 3187a08bae6SJohn Baldwin SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL) 3192b14f991SJulian Elischer 320f36ba452SJake Burkholder struct sysentvec null_sysvec = { 321f36ba452SJake Burkholder 0, 322f36ba452SJake Burkholder NULL, 323f36ba452SJake Burkholder 0, 324f36ba452SJake Burkholder 0, 325f36ba452SJake Burkholder NULL, 326f36ba452SJake Burkholder 0, 327f36ba452SJake Burkholder NULL, 328f36ba452SJake Burkholder NULL, 329f36ba452SJake Burkholder NULL, 330f36ba452SJake Burkholder NULL, 331f36ba452SJake Burkholder NULL, 332f36ba452SJake Burkholder NULL, 333f36ba452SJake Burkholder NULL, 334f36ba452SJake Burkholder "null", 335f36ba452SJake Burkholder NULL, 336f36ba452SJake Burkholder NULL, 337f36ba452SJake Burkholder 0, 338f36ba452SJake Burkholder PAGE_SIZE, 339f36ba452SJake Burkholder VM_MIN_ADDRESS, 340f36ba452SJake Burkholder VM_MAXUSER_ADDRESS, 341f36ba452SJake Burkholder USRSTACK, 342f36ba452SJake Burkholder PS_STRINGS, 343f36ba452SJake Burkholder VM_PROT_ALL, 344f36ba452SJake Burkholder NULL, 345c460ac3aSPeter Wemm NULL, 346f36ba452SJake Burkholder NULL 347f36ba452SJake Burkholder }; 3483ebc1248SPeter Wemm 3492b14f991SJulian Elischer /* 3502b14f991SJulian Elischer *************************************************************************** 3512b14f991SJulian Elischer **** 3520c920c0dSGiorgos Keramidas **** The two following SYSINIT's are proc0 specific glue code. I am not 3532b14f991SJulian Elischer **** convinced that they can not be safely combined, but their order of 3542b14f991SJulian Elischer **** operation has been maintained as the same as the original init_main.c 3552b14f991SJulian Elischer **** for right now. 3562b14f991SJulian Elischer **** 3572b14f991SJulian Elischer **** These probably belong in init_proc.c or kern_proc.c, since they 3582b14f991SJulian Elischer **** deal with proc0 (the fork template process). 3592b14f991SJulian Elischer **** 3602b14f991SJulian Elischer *************************************************************************** 3612b14f991SJulian Elischer */ 3622b14f991SJulian Elischer /* ARGSUSED*/ 363154c04e5SPoul-Henning Kamp static void 36437b087a6SPeter Wemm proc0_init(void *dummy __unused) 3652b14f991SJulian Elischer { 3668ec21e3aSPoul-Henning Kamp struct proc *p; 3678ec21e3aSPoul-Henning Kamp unsigned i; 368b40ce416SJulian Elischer struct thread *td; 3698460a577SJohn Birrell #ifdef KSE 370079b7badSJulian Elischer struct ksegrp *kg; 3718460a577SJohn Birrell #endif 372df8bae1dSRodney W. Grimes 3730cddd8f0SMatthew Dillon GIANT_REQUIRED; 374df8bae1dSRodney W. Grimes p = &proc0; 375079b7badSJulian Elischer td = &thread0; 3768460a577SJohn Birrell #ifdef KSE 3774f0db5e0SJulian Elischer kg = &ksegrp0; 3788460a577SJohn Birrell #endif 379df8bae1dSRodney W. Grimes 380df8bae1dSRodney W. Grimes /* 3810384fff8SJason Evans * Initialize magic number. 3820384fff8SJason Evans */ 3830384fff8SJason Evans p->p_magic = P_MAGIC; 3840384fff8SJason Evans 3858460a577SJohn Birrell #ifdef KSE 3860384fff8SJason Evans /* 387ed062c8dSJulian Elischer * Initialize thread, process and ksegrp structures. 388a3bfb996SJeffrey Hsu */ 389ed062c8dSJulian Elischer procinit(); /* set up proc zone */ 390ed062c8dSJulian Elischer threadinit(); /* set up thead, upcall and KSEGRP zones */ 391a3bfb996SJeffrey Hsu 392a3bfb996SJeffrey Hsu /* 393ed062c8dSJulian Elischer * Initialise scheduler resources. 394ed062c8dSJulian Elischer * Add scheduler specific parts to proc, ksegrp, thread as needed. 395ed062c8dSJulian Elischer */ 3968460a577SJohn Birrell #else 3978460a577SJohn Birrell /* 3988460a577SJohn Birrell * Initialize thread and process structures. 3998460a577SJohn Birrell */ 4008460a577SJohn Birrell procinit(); /* set up proc zone */ 4018460a577SJohn Birrell threadinit(); /* set up UMA zones */ 4028460a577SJohn Birrell 4038460a577SJohn Birrell /* 4048460a577SJohn Birrell * Initialise scheduler resources. 4058460a577SJohn Birrell * Add scheduler specific parts to proc, thread as needed. 4068460a577SJohn Birrell */ 4078460a577SJohn Birrell #endif 408ed062c8dSJulian Elischer schedinit(); /* scheduler gets its house in order */ 409ed062c8dSJulian Elischer /* 410b1508c72SDavid Greenman * Initialize sleep queue hash table 411b1508c72SDavid Greenman */ 412b1508c72SDavid Greenman sleepinit(); 413b1508c72SDavid Greenman 414b1508c72SDavid Greenman /* 4153075778bSJohn Dyson * additional VM structures 4163075778bSJohn Dyson */ 4173075778bSJohn Dyson vm_init2(); 4183075778bSJohn Dyson 4193075778bSJohn Dyson /* 420df8bae1dSRodney W. Grimes * Create process 0 (the swapper). 421df8bae1dSRodney W. Grimes */ 422a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&allproc, p, p_list); 4237b531e60SJohn Baldwin LIST_INSERT_HEAD(PIDHASH(0), p, p_hash); 4246008862bSJohn Baldwin mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK); 425df8bae1dSRodney W. Grimes p->p_pgrp = &pgrp0; 426a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); 427a3bfb996SJeffrey Hsu LIST_INIT(&pgrp0.pg_members); 428a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); 429a3bfb996SJeffrey Hsu 430df8bae1dSRodney W. Grimes pgrp0.pg_session = &session0; 4316008862bSJohn Baldwin mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF); 432df8bae1dSRodney W. Grimes session0.s_count = 1; 433df8bae1dSRodney W. Grimes session0.s_leader = p; 434df8bae1dSRodney W. Grimes 4353ebc1248SPeter Wemm p->p_sysent = &null_sysvec; 436f202965eSJohn Baldwin p->p_flag = P_SYSTEM; 437f202965eSJohn Baldwin p->p_sflag = PS_INMEM; 438e602ba25SJulian Elischer p->p_state = PRS_NORMAL; 439571dcd15SSuleiman Souhlal knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL); 4402c255e9dSRobert Watson STAILQ_INIT(&p->p_ktr); 441fa885116SJulian Elischer p->p_nice = NZERO; 442e602ba25SJulian Elischer td->td_state = TDS_RUNNING; 4438460a577SJohn Birrell #ifdef KSE 4442c100766SJulian Elischer kg->kg_pri_class = PRI_TIMESHARE; 4452c100766SJulian Elischer kg->kg_user_pri = PUSER; 44643863138SDavid Xu kg->kg_base_user_pri = PUSER; 4478460a577SJohn Birrell #else 4488460a577SJohn Birrell td->td_pri_class = PRI_TIMESHARE; 4498460a577SJohn Birrell td->td_user_pri = PUSER; 45060d48235SDavid Xu td->td_base_user_pri = PUSER; 4518460a577SJohn Birrell #endif 4522c100766SJulian Elischer td->td_priority = PVM; 4532c100766SJulian Elischer td->td_base_pri = PUSER; 454060563ecSJulian Elischer td->td_oncpu = 0; 4552c1011f7SJohn Dyson p->p_peers = 0; 4562c1011f7SJohn Dyson p->p_leader = p; 457e602ba25SJulian Elischer 4582c1011f7SJohn Dyson 459df8bae1dSRodney W. Grimes bcopy("swapper", p->p_comm, sizeof ("swapper")); 460df8bae1dSRodney W. Grimes 461c06eb4e2SSam Leffler callout_init(&p->p_itcallout, CALLOUT_MPSAFE); 462c06eb4e2SSam Leffler callout_init(&td->td_slpcallout, CALLOUT_MPSAFE); 4634f559836SJake Burkholder 464df8bae1dSRodney W. Grimes /* Create credentials. */ 465df8bae1dSRodney W. Grimes p->p_ucred = crget(); 466df8bae1dSRodney W. Grimes p->p_ucred->cr_ngroups = 1; /* group 0 */ 467f535380cSDon Lewis p->p_ucred->cr_uidinfo = uifind(0); 468b1fc0ec1SRobert Watson p->p_ucred->cr_ruidinfo = uifind(0); 46991421ba2SRobert Watson p->p_ucred->cr_prison = NULL; /* Don't jail it. */ 4703683665bSRobert Watson #ifdef AUDIT 4713683665bSRobert Watson audit_proc_alloc(p); 4723683665bSRobert Watson audit_proc_kproc0(p); 4733683665bSRobert Watson #endif 47440244964SRobert Watson #ifdef MAC 47540244964SRobert Watson mac_create_proc0(p->p_ucred); 47640244964SRobert Watson #endif 4778e2e767bSJohn Baldwin td->td_ucred = crhold(p->p_ucred); 47875c13541SPoul-Henning Kamp 47990af4afaSJohn Baldwin /* Create sigacts. */ 48090af4afaSJohn Baldwin p->p_sigacts = sigacts_alloc(); 4816626c604SJulian Elischer 48237b087a6SPeter Wemm /* Initialize signal state for process 0. */ 48337b087a6SPeter Wemm siginit(&proc0); 48437b087a6SPeter Wemm 485df8bae1dSRodney W. Grimes /* Create the file descriptor table. */ 4868ec21e3aSPoul-Henning Kamp p->p_fd = fdinit(NULL); 487ad05d580STor Egge p->p_fdtol = NULL; 488df8bae1dSRodney W. Grimes 489df8bae1dSRodney W. Grimes /* Create the limits structures. */ 49091d5354aSJohn Baldwin p->p_limit = lim_alloc(); 49191d5354aSJohn Baldwin for (i = 0; i < RLIM_NLIMITS; i++) 49291d5354aSJohn Baldwin p->p_limit->pl_rlimit[i].rlim_cur = 49391d5354aSJohn Baldwin p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY; 49491d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur = 49591d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles; 49691d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur = 49791d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; 498df8bae1dSRodney W. Grimes i = ptoa(cnt.v_free_count); 49991d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i; 50091d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; 50191d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; 5025715307fSJohn Baldwin p->p_cpulimit = RLIM_INFINITY; 503df8bae1dSRodney W. Grimes 5048b059651SDavid Schultz p->p_stats = pstats_alloc(); 5058b059651SDavid Schultz 506df8bae1dSRodney W. Grimes /* Allocate a prototype map so we have something to fork. */ 507b1028ad1SLuoqi Chen pmap_pinit0(vmspace_pmap(&vmspace0)); 508df8bae1dSRodney W. Grimes p->p_vmspace = &vmspace0; 509df8bae1dSRodney W. Grimes vmspace0.vm_refcnt = 1; 51005ba50f5SJake Burkholder vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser, 51105ba50f5SJake Burkholder p->p_sysent->sv_maxuser); 512b1028ad1SLuoqi Chen vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0); 513df8bae1dSRodney W. Grimes 51439fb8e6bSJulian Elischer /* 515a3bfb996SJeffrey Hsu * Charge root for one process. 516df8bae1dSRodney W. Grimes */ 517b1fc0ec1SRobert Watson (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0); 51826f9a767SRodney W. Grimes } 5192b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) 5202b14f991SJulian Elischer 5212b14f991SJulian Elischer /* ARGSUSED*/ 522154c04e5SPoul-Henning Kamp static void 52337b087a6SPeter Wemm proc0_post(void *dummy __unused) 5242b14f991SJulian Elischer { 52500af9731SPoul-Henning Kamp struct timespec ts; 52637b087a6SPeter Wemm struct proc *p; 527a6fc8288SPeter Wemm 5282b14f991SJulian Elischer /* 5291b0b259eSBruce Evans * Now we can look at the time, having had a chance to verify the 5301b0b259eSBruce Evans * time from the filesystem. Pretend that proc0 started now. 5312b14f991SJulian Elischer */ 5321005a129SJohn Baldwin sx_slock(&allproc_lock); 53337b087a6SPeter Wemm LIST_FOREACH(p, &allproc, p_list) { 53487ccef7bSDag-Erling Smørgrav microuptime(&p->p_stats->p_start); 5355b1a8eb3SPoul-Henning Kamp p->p_rux.rux_runtime = 0; 53637b087a6SPeter Wemm } 5371005a129SJohn Baldwin sx_sunlock(&allproc_lock); 5385b1a8eb3SPoul-Henning Kamp PCPU_SET(switchtime, cpu_ticks()); 5390384fff8SJason Evans PCPU_SET(switchticks, ticks); 5402b14f991SJulian Elischer 541a6fc8288SPeter Wemm /* 542a6fc8288SPeter Wemm * Give the ``random'' number generator a thump. 543a6fc8288SPeter Wemm */ 54400af9731SPoul-Henning Kamp nanotime(&ts); 54500af9731SPoul-Henning Kamp srandom(ts.tv_sec ^ ts.tv_nsec); 5462b14f991SJulian Elischer } 5472b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) 5482b14f991SJulian Elischer 549df8bae1dSRodney W. Grimes /* 5502b14f991SJulian Elischer *************************************************************************** 5512b14f991SJulian Elischer **** 5522b14f991SJulian Elischer **** The following SYSINIT's and glue code should be moved to the 5532b14f991SJulian Elischer **** respective files on a per subsystem basis. 5542b14f991SJulian Elischer **** 5552b14f991SJulian Elischer *************************************************************************** 556df8bae1dSRodney W. Grimes */ 557df8bae1dSRodney W. Grimes 558df8bae1dSRodney W. Grimes 559df8bae1dSRodney W. Grimes /* 5602b14f991SJulian Elischer *************************************************************************** 5612b14f991SJulian Elischer **** 5622b14f991SJulian Elischer **** The following code probably belongs in another file, like 56337b087a6SPeter Wemm **** kern/init_init.c. 5642b14f991SJulian Elischer **** 5652b14f991SJulian Elischer *************************************************************************** 566df8bae1dSRodney W. Grimes */ 567df8bae1dSRodney W. Grimes 568df8bae1dSRodney W. Grimes /* 569df8bae1dSRodney W. Grimes * List of paths to try when searching for "init". 570df8bae1dSRodney W. Grimes */ 5715f967b24SDag-Erling Smørgrav static char init_path[MAXPATHLEN] = 57267481196SJohn Birrell #ifdef INIT_PATH 57367481196SJohn Birrell __XSTRING(INIT_PATH); 57467481196SJohn Birrell #else 575f3f4baf0SDag-Erling Smørgrav "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall"; 57667481196SJohn Birrell #endif 577af1408e3SLuigi Rizzo SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0, 578af1408e3SLuigi Rizzo "Path used to search the init process"); 579df8bae1dSRodney W. Grimes 580df8bae1dSRodney W. Grimes /* 581724447acSRalf S. Engelschall * Shutdown timeout of init(8). 582724447acSRalf S. Engelschall * Unused within kernel, but used to control init(8), hence do not remove. 583724447acSRalf S. Engelschall */ 584724447acSRalf S. Engelschall #ifndef INIT_SHUTDOWN_TIMEOUT 585724447acSRalf S. Engelschall #define INIT_SHUTDOWN_TIMEOUT 120 586724447acSRalf S. Engelschall #endif 587724447acSRalf S. Engelschall static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT; 588724447acSRalf S. Engelschall SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout, 589724447acSRalf S. Engelschall CTLFLAG_RW, &init_shutdown_timeout, 0, ""); 590724447acSRalf S. Engelschall 591724447acSRalf S. Engelschall /* 5925f967b24SDag-Erling Smørgrav * Start the initial user process; try exec'ing each pathname in init_path. 593df8bae1dSRodney W. Grimes * The program is invoked with one argument containing the boot flags. 594df8bae1dSRodney W. Grimes */ 595df8bae1dSRodney W. Grimes static void 59637b087a6SPeter Wemm start_init(void *dummy) 597df8bae1dSRodney W. Grimes { 598df8bae1dSRodney W. Grimes vm_offset_t addr; 599df8bae1dSRodney W. Grimes struct execve_args args; 6005f967b24SDag-Erling Smørgrav int options, error; 6015f967b24SDag-Erling Smørgrav char *var, *path, *next, *s; 6025f967b24SDag-Erling Smørgrav char *ucp, **uap, *arg0, *arg1; 603b40ce416SJulian Elischer struct thread *td; 6049c8b8baaSPeter Wemm struct proc *p; 605df8bae1dSRodney W. Grimes 6069ed346baSBosko Milekic mtx_lock(&Giant); 6070384fff8SJason Evans 6080cddd8f0SMatthew Dillon GIANT_REQUIRED; 6090cddd8f0SMatthew Dillon 610b40ce416SJulian Elischer td = curthread; 611b40ce416SJulian Elischer p = td->td_proc; 612df8bae1dSRodney W. Grimes 613563af2ecSMaxime Henrion vfs_mountroot(); 614fb92273bSPoul-Henning Kamp 615b7116168SPeter Wemm /* 616df8bae1dSRodney W. Grimes * Need just enough stack to hold the faked-up "execve()" arguments. 617df8bae1dSRodney W. Grimes */ 61805ba50f5SJake Burkholder addr = p->p_sysent->sv_usrstack - PAGE_SIZE; 6195f967b24SDag-Erling Smørgrav if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, 6205f967b24SDag-Erling Smørgrav FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 621df8bae1dSRodney W. Grimes panic("init: couldn't allocate argument space"); 622df8bae1dSRodney W. Grimes p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 62326f9a767SRodney W. Grimes p->p_vmspace->vm_ssize = 1; 624df8bae1dSRodney W. Grimes 6255f967b24SDag-Erling Smørgrav if ((var = getenv("init_path")) != NULL) { 626e80fb434SRobert Drehmel strlcpy(init_path, var, sizeof(init_path)); 627d786139cSMaxime Henrion freeenv(var); 6285f967b24SDag-Erling Smørgrav } 6295f967b24SDag-Erling Smørgrav 63067481196SJohn Birrell for (path = init_path; *path != '\0'; path = next) { 631e4082284SJohn Birrell while (*path == ':') 6325f967b24SDag-Erling Smørgrav path++; 63367481196SJohn Birrell if (*path == '\0') 6345f967b24SDag-Erling Smørgrav break; 635e4082284SJohn Birrell for (next = path; *next != '\0' && *next != ':'; next++) 6365f967b24SDag-Erling Smørgrav /* nothing */ ; 6375f967b24SDag-Erling Smørgrav if (bootverbose) 638ba41a07dSDmitrij Tejblum printf("start_init: trying %.*s\n", (int)(next - path), 639ba41a07dSDmitrij Tejblum path); 6405f967b24SDag-Erling Smørgrav 641df8bae1dSRodney W. Grimes /* 642df8bae1dSRodney W. Grimes * Move out the boot flag argument. 643df8bae1dSRodney W. Grimes */ 644df8bae1dSRodney W. Grimes options = 0; 64505ba50f5SJake Burkholder ucp = (char *)p->p_sysent->sv_usrstack; 646df8bae1dSRodney W. Grimes (void)subyte(--ucp, 0); /* trailing zero */ 647df8bae1dSRodney W. Grimes if (boothowto & RB_SINGLE) { 648df8bae1dSRodney W. Grimes (void)subyte(--ucp, 's'); 649df8bae1dSRodney W. Grimes options = 1; 650df8bae1dSRodney W. Grimes } 651df8bae1dSRodney W. Grimes #ifdef notyet 652df8bae1dSRodney W. Grimes if (boothowto & RB_FASTBOOT) { 653df8bae1dSRodney W. Grimes (void)subyte(--ucp, 'f'); 654df8bae1dSRodney W. Grimes options = 1; 655df8bae1dSRodney W. Grimes } 656df8bae1dSRodney W. Grimes #endif 65717755ac8SPoul-Henning Kamp 65817755ac8SPoul-Henning Kamp #ifdef BOOTCDROM 65917755ac8SPoul-Henning Kamp (void)subyte(--ucp, 'C'); 66017755ac8SPoul-Henning Kamp options = 1; 66117755ac8SPoul-Henning Kamp #endif 662db901281SPoul-Henning Kamp 663df8bae1dSRodney W. Grimes if (options == 0) 664df8bae1dSRodney W. Grimes (void)subyte(--ucp, '-'); 665df8bae1dSRodney W. Grimes (void)subyte(--ucp, '-'); /* leading hyphen */ 666df8bae1dSRodney W. Grimes arg1 = ucp; 667df8bae1dSRodney W. Grimes 668df8bae1dSRodney W. Grimes /* 669df8bae1dSRodney W. Grimes * Move out the file name (also arg 0). 670df8bae1dSRodney W. Grimes */ 6715f967b24SDag-Erling Smørgrav (void)subyte(--ucp, 0); 6725f967b24SDag-Erling Smørgrav for (s = next - 1; s >= path; s--) 6735f967b24SDag-Erling Smørgrav (void)subyte(--ucp, *s); 674df8bae1dSRodney W. Grimes arg0 = ucp; 675df8bae1dSRodney W. Grimes 676df8bae1dSRodney W. Grimes /* 677df8bae1dSRodney W. Grimes * Move out the arg pointers. 678df8bae1dSRodney W. Grimes */ 679a20d7755SDoug Rabson uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1)); 680c2da0fd9SBruce Evans (void)suword((caddr_t)--uap, (long)0); /* terminator */ 681c2da0fd9SBruce Evans (void)suword((caddr_t)--uap, (long)(intptr_t)arg1); 682c2da0fd9SBruce Evans (void)suword((caddr_t)--uap, (long)(intptr_t)arg0); 683df8bae1dSRodney W. Grimes 684df8bae1dSRodney W. Grimes /* 685df8bae1dSRodney W. Grimes * Point at the arguments. 686df8bae1dSRodney W. Grimes */ 687df8bae1dSRodney W. Grimes args.fname = arg0; 68826f9a767SRodney W. Grimes args.argv = uap; 68926f9a767SRodney W. Grimes args.envv = NULL; 690df8bae1dSRodney W. Grimes 691df8bae1dSRodney W. Grimes /* 692df8bae1dSRodney W. Grimes * Now try to exec the program. If can't for any reason 693df8bae1dSRodney W. Grimes * other than it doesn't exist, complain. 6942b14f991SJulian Elischer * 69537b087a6SPeter Wemm * Otherwise, return via fork_trampoline() all the way 6969c8b8baaSPeter Wemm * to user mode as init! 697df8bae1dSRodney W. Grimes */ 698b40ce416SJulian Elischer if ((error = execve(td, &args)) == 0) { 6999ed346baSBosko Milekic mtx_unlock(&Giant); 700df8bae1dSRodney W. Grimes return; 701db72809dSJohn Baldwin } 702df8bae1dSRodney W. Grimes if (error != ENOENT) 703ba41a07dSDmitrij Tejblum printf("exec %.*s: error %d\n", (int)(next - path), 704ba41a07dSDmitrij Tejblum path, error); 705df8bae1dSRodney W. Grimes } 706580e7e5aSGreg Lehey printf("init: not found in path %s\n", init_path); 707df8bae1dSRodney W. Grimes panic("no init"); 708df8bae1dSRodney W. Grimes } 70937b087a6SPeter Wemm 71037b087a6SPeter Wemm /* 71137b087a6SPeter Wemm * Like kthread_create(), but runs in it's own address space. 71237b087a6SPeter Wemm * We do this early to reserve pid 1. 71337b087a6SPeter Wemm * 71437b087a6SPeter Wemm * Note special case - do not make it runnable yet. Other work 71537b087a6SPeter Wemm * in progress will change this more. 71637b087a6SPeter Wemm */ 71737b087a6SPeter Wemm static void 71837b087a6SPeter Wemm create_init(const void *udata __unused) 71937b087a6SPeter Wemm { 7205a06cb0cSRobert Watson struct ucred *newcred, *oldcred; 72137b087a6SPeter Wemm int error; 72237b087a6SPeter Wemm 723316ec49aSScott Long error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc); 72437b087a6SPeter Wemm if (error) 72537b087a6SPeter Wemm panic("cannot fork init: %d\n", error); 726bafc8f25SRobert Watson KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1")); 7275a06cb0cSRobert Watson /* divorce init's credentials from the kernel's */ 7285a06cb0cSRobert Watson newcred = crget(); 729f202965eSJohn Baldwin PROC_LOCK(initproc); 730f202965eSJohn Baldwin initproc->p_flag |= P_SYSTEM; 7315a06cb0cSRobert Watson oldcred = initproc->p_ucred; 7325a06cb0cSRobert Watson crcopy(newcred, oldcred); 73340244964SRobert Watson #ifdef MAC 73440244964SRobert Watson mac_create_proc1(newcred); 73540244964SRobert Watson #endif 7363683665bSRobert Watson #ifdef AUDIT 7373683665bSRobert Watson audit_proc_init(initproc); 7383683665bSRobert Watson #endif 7395a06cb0cSRobert Watson initproc->p_ucred = newcred; 740f202965eSJohn Baldwin PROC_UNLOCK(initproc); 7415a06cb0cSRobert Watson crfree(oldcred); 7424d1a4bb7SRobert Watson cred_update_thread(FIRST_THREAD_IN_PROC(initproc)); 7439ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 744f202965eSJohn Baldwin initproc->p_sflag |= PS_INMEM; 7459ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 746079b7badSJulian Elischer cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL); 74737b087a6SPeter Wemm } 74837b087a6SPeter Wemm SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL) 74937b087a6SPeter Wemm 75037b087a6SPeter Wemm /* 75137b087a6SPeter Wemm * Make it runnable now. 75237b087a6SPeter Wemm */ 75337b087a6SPeter Wemm static void 75437b087a6SPeter Wemm kick_init(const void *udata __unused) 75537b087a6SPeter Wemm { 756079b7badSJulian Elischer struct thread *td; 757f202965eSJohn Baldwin 758079b7badSJulian Elischer td = FIRST_THREAD_IN_PROC(initproc); 7599ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 76071fad9fdSJulian Elischer TD_SET_CAN_RUN(td); 7618460a577SJohn Birrell #ifdef KSE 7622630e4c9SJulian Elischer setrunqueue(td, SRQ_BORING); /* XXXKSE */ 7638460a577SJohn Birrell #else 7648460a577SJohn Birrell setrunqueue(td, SRQ_BORING); 7658460a577SJohn Birrell #endif 7669ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 76737b087a6SPeter Wemm } 76837b087a6SPeter Wemm SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL) 769