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 793683665bSRobert Watson #include <security/audit/audit.h> 803683665bSRobert Watson 81df8bae1dSRodney W. Grimes #include <vm/vm.h> 82efeaf95aSDavid Greenman #include <vm/vm_param.h> 83efeaf95aSDavid Greenman #include <vm/pmap.h> 84efeaf95aSDavid Greenman #include <vm/vm_map.h> 856faaa756SWolfram Schneider #include <sys/copyright.h> 86df8bae1dSRodney W. Grimes 8737b087a6SPeter Wemm void mi_startup(void); /* Should be elsewhere */ 88df8bae1dSRodney W. Grimes 89df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */ 90154c04e5SPoul-Henning Kamp static struct session session0; 91154c04e5SPoul-Henning Kamp static struct pgrp pgrp0; 92df8bae1dSRodney W. Grimes struct proc proc0; 93079b7badSJulian Elischer struct thread thread0; 944f0db5e0SJulian Elischer struct ksegrp ksegrp0; 9523734995SJake Burkholder struct vmspace vmspace0; 962b14f991SJulian Elischer struct proc *initproc; 97df8bae1dSRodney W. Grimes 98c463cf1cSBruce Evans int boothowto = 0; /* initialized so that it can be patched */ 998d0bf3d6SJordan K. Hubbard SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, ""); 1007a08bae6SJohn Baldwin int bootverbose; 1017a08bae6SJohn Baldwin SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, ""); 102946bb7a2SPoul-Henning Kamp 1032b14f991SJulian Elischer /* 1042b14f991SJulian Elischer * This ensures that there is at least one entry so that the sysinit_set 1052b14f991SJulian Elischer * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never 1062b14f991SJulian Elischer * executed. 10726f9a767SRodney W. Grimes */ 1082b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL) 1098a129caeSDavid Greenman 11094e9d7c1SPeter Wemm /* 11194e9d7c1SPeter Wemm * The sysinit table itself. Items are checked off as the are run. 11294e9d7c1SPeter Wemm * If we want to register new sysinit types, add them to newsysinit. 11394e9d7c1SPeter Wemm */ 114f41325dbSPeter Wemm SET_DECLARE(sysinit_set, struct sysinit); 115f41325dbSPeter Wemm struct sysinit **sysinit, **sysinit_end; 116f41325dbSPeter Wemm struct sysinit **newsysinit, **newsysinit_end; 11794e9d7c1SPeter Wemm 11894e9d7c1SPeter Wemm /* 11994e9d7c1SPeter Wemm * Merge a new sysinit set into the current set, reallocating it if 12094e9d7c1SPeter Wemm * necessary. This can only be called after malloc is running. 12194e9d7c1SPeter Wemm */ 12294e9d7c1SPeter Wemm void 123f41325dbSPeter Wemm sysinit_add(struct sysinit **set, struct sysinit **set_end) 12494e9d7c1SPeter Wemm { 12594e9d7c1SPeter Wemm struct sysinit **newset; 12694e9d7c1SPeter Wemm struct sysinit **sipp; 12794e9d7c1SPeter Wemm struct sysinit **xipp; 128f41325dbSPeter Wemm int count; 12994e9d7c1SPeter Wemm 130f41325dbSPeter Wemm count = set_end - set; 131ddd62546SPeter Wemm if (newsysinit) 132f41325dbSPeter Wemm count += newsysinit_end - newsysinit; 133ddd62546SPeter Wemm else 134f41325dbSPeter Wemm count += sysinit_end - sysinit; 13594e9d7c1SPeter Wemm newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT); 13694e9d7c1SPeter Wemm if (newset == NULL) 13794e9d7c1SPeter Wemm panic("cannot malloc for sysinit"); 13894e9d7c1SPeter Wemm xipp = newset; 139ddd62546SPeter Wemm if (newsysinit) 140f41325dbSPeter Wemm for (sipp = newsysinit; sipp < newsysinit_end; sipp++) 141ddd62546SPeter Wemm *xipp++ = *sipp; 142ddd62546SPeter Wemm else 143f41325dbSPeter Wemm for (sipp = sysinit; sipp < sysinit_end; sipp++) 14494e9d7c1SPeter Wemm *xipp++ = *sipp; 145f41325dbSPeter Wemm for (sipp = set; sipp < set_end; sipp++) 14694e9d7c1SPeter Wemm *xipp++ = *sipp; 147ddd62546SPeter Wemm if (newsysinit) 148ddd62546SPeter Wemm free(newsysinit, M_TEMP); 14994e9d7c1SPeter Wemm newsysinit = newset; 150f41325dbSPeter Wemm newsysinit_end = newset + count; 15194e9d7c1SPeter Wemm } 15226f9a767SRodney W. Grimes 153df8bae1dSRodney W. Grimes /* 154df8bae1dSRodney W. Grimes * System startup; initialize the world, create process 0, mount root 155df8bae1dSRodney W. Grimes * filesystem, and fork to create init and pagedaemon. Most of the 156df8bae1dSRodney W. Grimes * hard work is done in the lower-level initialization routines including 157df8bae1dSRodney W. Grimes * startup(), which does memory initialization and autoconfiguration. 1582b14f991SJulian Elischer * 1592b14f991SJulian Elischer * This allows simple addition of new kernel subsystems that require 1602b14f991SJulian Elischer * boot time initialization. It also allows substitution of subsystem 1612b14f991SJulian Elischer * (for instance, a scheduler, kernel profiler, or VM system) by object 162c5b193bfSPoul-Henning Kamp * module. Finally, it allows for optional "kernel threads". 163df8bae1dSRodney W. Grimes */ 16426f9a767SRodney W. Grimes void 16537b087a6SPeter Wemm mi_startup(void) 166df8bae1dSRodney W. Grimes { 1672b14f991SJulian Elischer 1682b14f991SJulian Elischer register struct sysinit **sipp; /* system initialization*/ 1692b14f991SJulian Elischer register struct sysinit **xipp; /* interior loop of sort*/ 1702b14f991SJulian Elischer register struct sysinit *save; /* bubble*/ 1712b14f991SJulian Elischer 172f41325dbSPeter Wemm if (sysinit == NULL) { 173f41325dbSPeter Wemm sysinit = SET_BEGIN(sysinit_set); 174f41325dbSPeter Wemm sysinit_end = SET_LIMIT(sysinit_set); 175f41325dbSPeter Wemm } 176f41325dbSPeter Wemm 17794e9d7c1SPeter Wemm restart: 1782b14f991SJulian Elischer /* 1792b14f991SJulian Elischer * Perform a bubble sort of the system initialization objects by 1802b14f991SJulian Elischer * their subsystem (primary key) and order (secondary key). 1812b14f991SJulian Elischer */ 182f41325dbSPeter Wemm for (sipp = sysinit; sipp < sysinit_end; sipp++) { 183f41325dbSPeter Wemm for (xipp = sipp + 1; xipp < sysinit_end; xipp++) { 1842b14f991SJulian Elischer if ((*sipp)->subsystem < (*xipp)->subsystem || 1852b14f991SJulian Elischer ((*sipp)->subsystem == (*xipp)->subsystem && 186af4b2d2dSPeter Wemm (*sipp)->order <= (*xipp)->order)) 1872b14f991SJulian Elischer continue; /* skip*/ 1882b14f991SJulian Elischer save = *sipp; 1892b14f991SJulian Elischer *sipp = *xipp; 1902b14f991SJulian Elischer *xipp = save; 1912b14f991SJulian Elischer } 1922b14f991SJulian Elischer } 1932b14f991SJulian Elischer 1942b14f991SJulian Elischer /* 1952b14f991SJulian Elischer * Traverse the (now) ordered list of system initialization tasks. 1962b14f991SJulian Elischer * Perform each task, and continue on to the next task. 1972b14f991SJulian Elischer * 1982b14f991SJulian Elischer * The last item on the list is expected to be the scheduler, 1992b14f991SJulian Elischer * which will not return. 2002b14f991SJulian Elischer */ 201f41325dbSPeter Wemm for (sipp = sysinit; sipp < sysinit_end; sipp++) { 20274b2192aSJohn Dyson 2032b14f991SJulian Elischer if ((*sipp)->subsystem == SI_SUB_DUMMY) 2042b14f991SJulian Elischer continue; /* skip dummy task(s)*/ 2052b14f991SJulian Elischer 20694e9d7c1SPeter Wemm if ((*sipp)->subsystem == SI_SUB_DONE) 20794e9d7c1SPeter Wemm continue; 20894e9d7c1SPeter Wemm 2099c8b8baaSPeter Wemm /* Call function */ 2102b14f991SJulian Elischer (*((*sipp)->func))((*sipp)->udata); 21194e9d7c1SPeter Wemm 21294e9d7c1SPeter Wemm /* Check off the one we're just done */ 21394e9d7c1SPeter Wemm (*sipp)->subsystem = SI_SUB_DONE; 21494e9d7c1SPeter Wemm 21594e9d7c1SPeter Wemm /* Check if we've installed more sysinit items via KLD */ 21694e9d7c1SPeter Wemm if (newsysinit != NULL) { 217f41325dbSPeter Wemm if (sysinit != SET_BEGIN(sysinit_set)) 21894e9d7c1SPeter Wemm free(sysinit, M_TEMP); 21994e9d7c1SPeter Wemm sysinit = newsysinit; 220f41325dbSPeter Wemm sysinit_end = newsysinit_end; 22194e9d7c1SPeter Wemm newsysinit = NULL; 222f41325dbSPeter Wemm newsysinit_end = NULL; 22394e9d7c1SPeter Wemm goto restart; 22494e9d7c1SPeter Wemm } 2252b14f991SJulian Elischer } 2262b14f991SJulian Elischer 227477a642cSPeter Wemm panic("Shouldn't get here!"); 2282b14f991SJulian Elischer /* NOTREACHED*/ 2292b14f991SJulian Elischer } 2302b14f991SJulian Elischer 2312b14f991SJulian Elischer 2322b14f991SJulian Elischer /* 2332b14f991SJulian Elischer *************************************************************************** 2342b14f991SJulian Elischer **** 2352b14f991SJulian Elischer **** The following SYSINIT's belong elsewhere, but have not yet 2362b14f991SJulian Elischer **** been moved. 2372b14f991SJulian Elischer **** 2382b14f991SJulian Elischer *************************************************************************** 2392b14f991SJulian Elischer */ 2409ef6c28aSBruce Evans static void 24137b087a6SPeter Wemm print_caddr_t(void *data __unused) 2429ef6c28aSBruce Evans { 2439ef6c28aSBruce Evans printf("%s", (char *)data); 2449ef6c28aSBruce Evans } 245d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) 2467a08bae6SJohn Baldwin SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, version) 2477a08bae6SJohn Baldwin 2482cf6bdacSPoul-Henning Kamp #ifdef WITNESS 2492cf6bdacSPoul-Henning Kamp static char wit_warn[] = 2502cf6bdacSPoul-Henning Kamp "WARNING: WITNESS option enabled, expect reduced performance.\n"; 2512cf6bdacSPoul-Henning Kamp SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_SECOND + 1, 2522cf6bdacSPoul-Henning Kamp print_caddr_t, wit_warn) 2532cf6bdacSPoul-Henning Kamp #endif 2542cf6bdacSPoul-Henning Kamp 2552cf6bdacSPoul-Henning Kamp #ifdef DIAGNOSTIC 2562cf6bdacSPoul-Henning Kamp static char diag_warn[] = 2572cf6bdacSPoul-Henning Kamp "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n"; 2582cf6bdacSPoul-Henning Kamp SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_SECOND + 2, 2592cf6bdacSPoul-Henning Kamp print_caddr_t, diag_warn) 2602cf6bdacSPoul-Henning Kamp #endif 2612cf6bdacSPoul-Henning Kamp 2627a08bae6SJohn Baldwin static void 2637a08bae6SJohn Baldwin set_boot_verbose(void *data __unused) 2647a08bae6SJohn Baldwin { 2657a08bae6SJohn Baldwin 2667a08bae6SJohn Baldwin if (boothowto & RB_VERBOSE) 2677a08bae6SJohn Baldwin bootverbose++; 2687a08bae6SJohn Baldwin } 2697a08bae6SJohn Baldwin SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL) 2702b14f991SJulian Elischer 271f36ba452SJake Burkholder struct sysentvec null_sysvec = { 272f36ba452SJake Burkholder 0, 273f36ba452SJake Burkholder NULL, 274f36ba452SJake Burkholder 0, 275f36ba452SJake Burkholder 0, 276f36ba452SJake Burkholder NULL, 277f36ba452SJake Burkholder 0, 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 NULL, 287f36ba452SJake Burkholder NULL, 288f36ba452SJake Burkholder 0, 289f36ba452SJake Burkholder PAGE_SIZE, 290f36ba452SJake Burkholder VM_MIN_ADDRESS, 291f36ba452SJake Burkholder VM_MAXUSER_ADDRESS, 292f36ba452SJake Burkholder USRSTACK, 293f36ba452SJake Burkholder PS_STRINGS, 294f36ba452SJake Burkholder VM_PROT_ALL, 295f36ba452SJake Burkholder NULL, 296c460ac3aSPeter Wemm NULL, 297f36ba452SJake Burkholder NULL 298f36ba452SJake Burkholder }; 2993ebc1248SPeter Wemm 3002b14f991SJulian Elischer /* 3012b14f991SJulian Elischer *************************************************************************** 3022b14f991SJulian Elischer **** 3030c920c0dSGiorgos Keramidas **** The two following SYSINIT's are proc0 specific glue code. I am not 3042b14f991SJulian Elischer **** convinced that they can not be safely combined, but their order of 3052b14f991SJulian Elischer **** operation has been maintained as the same as the original init_main.c 3062b14f991SJulian Elischer **** for right now. 3072b14f991SJulian Elischer **** 3082b14f991SJulian Elischer **** These probably belong in init_proc.c or kern_proc.c, since they 3092b14f991SJulian Elischer **** deal with proc0 (the fork template process). 3102b14f991SJulian Elischer **** 3112b14f991SJulian Elischer *************************************************************************** 3122b14f991SJulian Elischer */ 3132b14f991SJulian Elischer /* ARGSUSED*/ 314154c04e5SPoul-Henning Kamp static void 31537b087a6SPeter Wemm proc0_init(void *dummy __unused) 3162b14f991SJulian Elischer { 3178ec21e3aSPoul-Henning Kamp struct proc *p; 3188ec21e3aSPoul-Henning Kamp unsigned i; 319b40ce416SJulian Elischer struct thread *td; 320079b7badSJulian Elischer struct ksegrp *kg; 321df8bae1dSRodney W. Grimes 3220cddd8f0SMatthew Dillon GIANT_REQUIRED; 323df8bae1dSRodney W. Grimes p = &proc0; 324079b7badSJulian Elischer td = &thread0; 3254f0db5e0SJulian Elischer kg = &ksegrp0; 326df8bae1dSRodney W. Grimes 327df8bae1dSRodney W. Grimes /* 3280384fff8SJason Evans * Initialize magic number. 3290384fff8SJason Evans */ 3300384fff8SJason Evans p->p_magic = P_MAGIC; 3310384fff8SJason Evans 3320384fff8SJason Evans /* 333ed062c8dSJulian Elischer * Initialize thread, process and ksegrp structures. 334a3bfb996SJeffrey Hsu */ 335ed062c8dSJulian Elischer procinit(); /* set up proc zone */ 336ed062c8dSJulian Elischer threadinit(); /* set up thead, upcall and KSEGRP zones */ 337a3bfb996SJeffrey Hsu 338a3bfb996SJeffrey Hsu /* 339ed062c8dSJulian Elischer * Initialise scheduler resources. 340ed062c8dSJulian Elischer * Add scheduler specific parts to proc, ksegrp, thread as needed. 341ed062c8dSJulian Elischer */ 342ed062c8dSJulian Elischer schedinit(); /* scheduler gets its house in order */ 343ed062c8dSJulian Elischer /* 344b1508c72SDavid Greenman * Initialize sleep queue hash table 345b1508c72SDavid Greenman */ 346b1508c72SDavid Greenman sleepinit(); 347b1508c72SDavid Greenman 348b1508c72SDavid Greenman /* 3493075778bSJohn Dyson * additional VM structures 3503075778bSJohn Dyson */ 3513075778bSJohn Dyson vm_init2(); 3523075778bSJohn Dyson 3533075778bSJohn Dyson /* 354df8bae1dSRodney W. Grimes * Create process 0 (the swapper). 355df8bae1dSRodney W. Grimes */ 356a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&allproc, p, p_list); 3577b531e60SJohn Baldwin LIST_INSERT_HEAD(PIDHASH(0), p, p_hash); 3586008862bSJohn Baldwin mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK); 359df8bae1dSRodney W. Grimes p->p_pgrp = &pgrp0; 360a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); 361a3bfb996SJeffrey Hsu LIST_INIT(&pgrp0.pg_members); 362a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); 363a3bfb996SJeffrey Hsu 364df8bae1dSRodney W. Grimes pgrp0.pg_session = &session0; 3656008862bSJohn Baldwin mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF); 366df8bae1dSRodney W. Grimes session0.s_count = 1; 367df8bae1dSRodney W. Grimes session0.s_leader = p; 368df8bae1dSRodney W. Grimes 3693ebc1248SPeter Wemm p->p_sysent = &null_sysvec; 370f202965eSJohn Baldwin p->p_flag = P_SYSTEM; 371f202965eSJohn Baldwin p->p_sflag = PS_INMEM; 372e602ba25SJulian Elischer p->p_state = PRS_NORMAL; 373571dcd15SSuleiman Souhlal knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL); 3742c255e9dSRobert Watson STAILQ_INIT(&p->p_ktr); 375fa885116SJulian Elischer p->p_nice = NZERO; 376e602ba25SJulian Elischer td->td_state = TDS_RUNNING; 3772c100766SJulian Elischer kg->kg_pri_class = PRI_TIMESHARE; 3782c100766SJulian Elischer kg->kg_user_pri = PUSER; 3792c100766SJulian Elischer td->td_priority = PVM; 3802c100766SJulian Elischer td->td_base_pri = PUSER; 381060563ecSJulian Elischer td->td_oncpu = 0; 3822c1011f7SJohn Dyson p->p_peers = 0; 3832c1011f7SJohn Dyson p->p_leader = p; 384e602ba25SJulian Elischer 3852c1011f7SJohn Dyson 386df8bae1dSRodney W. Grimes bcopy("swapper", p->p_comm, sizeof ("swapper")); 387df8bae1dSRodney W. Grimes 388c06eb4e2SSam Leffler callout_init(&p->p_itcallout, CALLOUT_MPSAFE); 389c06eb4e2SSam Leffler callout_init(&td->td_slpcallout, CALLOUT_MPSAFE); 3904f559836SJake Burkholder 391df8bae1dSRodney W. Grimes /* Create credentials. */ 392df8bae1dSRodney W. Grimes p->p_ucred = crget(); 393df8bae1dSRodney W. Grimes p->p_ucred->cr_ngroups = 1; /* group 0 */ 394f535380cSDon Lewis p->p_ucred->cr_uidinfo = uifind(0); 395b1fc0ec1SRobert Watson p->p_ucred->cr_ruidinfo = uifind(0); 39691421ba2SRobert Watson p->p_ucred->cr_prison = NULL; /* Don't jail it. */ 3973683665bSRobert Watson #ifdef AUDIT 3983683665bSRobert Watson audit_proc_alloc(p); 3993683665bSRobert Watson audit_proc_kproc0(p); 4003683665bSRobert Watson #endif 40140244964SRobert Watson #ifdef MAC 40240244964SRobert Watson mac_create_proc0(p->p_ucred); 40340244964SRobert Watson #endif 4048e2e767bSJohn Baldwin td->td_ucred = crhold(p->p_ucred); 40575c13541SPoul-Henning Kamp 40690af4afaSJohn Baldwin /* Create sigacts. */ 40790af4afaSJohn Baldwin p->p_sigacts = sigacts_alloc(); 4086626c604SJulian Elischer 40937b087a6SPeter Wemm /* Initialize signal state for process 0. */ 41037b087a6SPeter Wemm siginit(&proc0); 41137b087a6SPeter Wemm 412df8bae1dSRodney W. Grimes /* Create the file descriptor table. */ 4138ec21e3aSPoul-Henning Kamp p->p_fd = fdinit(NULL); 414ad05d580STor Egge p->p_fdtol = NULL; 415df8bae1dSRodney W. Grimes 416df8bae1dSRodney W. Grimes /* Create the limits structures. */ 41791d5354aSJohn Baldwin p->p_limit = lim_alloc(); 41891d5354aSJohn Baldwin for (i = 0; i < RLIM_NLIMITS; i++) 41991d5354aSJohn Baldwin p->p_limit->pl_rlimit[i].rlim_cur = 42091d5354aSJohn Baldwin p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY; 42191d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur = 42291d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles; 42391d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur = 42491d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; 425df8bae1dSRodney W. Grimes i = ptoa(cnt.v_free_count); 42691d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i; 42791d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; 42891d5354aSJohn Baldwin p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; 4295715307fSJohn Baldwin p->p_cpulimit = RLIM_INFINITY; 430df8bae1dSRodney W. Grimes 4318b059651SDavid Schultz p->p_stats = pstats_alloc(); 4328b059651SDavid Schultz 433df8bae1dSRodney W. Grimes /* Allocate a prototype map so we have something to fork. */ 434b1028ad1SLuoqi Chen pmap_pinit0(vmspace_pmap(&vmspace0)); 435df8bae1dSRodney W. Grimes p->p_vmspace = &vmspace0; 436df8bae1dSRodney W. Grimes vmspace0.vm_refcnt = 1; 43705ba50f5SJake Burkholder vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser, 43805ba50f5SJake Burkholder p->p_sysent->sv_maxuser); 439b1028ad1SLuoqi Chen vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0); 440df8bae1dSRodney W. Grimes 44139fb8e6bSJulian Elischer /* 442a3bfb996SJeffrey Hsu * Charge root for one process. 443df8bae1dSRodney W. Grimes */ 444b1fc0ec1SRobert Watson (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0); 44526f9a767SRodney W. Grimes } 4462b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) 4472b14f991SJulian Elischer 4482b14f991SJulian Elischer /* ARGSUSED*/ 449154c04e5SPoul-Henning Kamp static void 45037b087a6SPeter Wemm proc0_post(void *dummy __unused) 4512b14f991SJulian Elischer { 45200af9731SPoul-Henning Kamp struct timespec ts; 45337b087a6SPeter Wemm struct proc *p; 454a6fc8288SPeter Wemm 4552b14f991SJulian Elischer /* 4561b0b259eSBruce Evans * Now we can look at the time, having had a chance to verify the 4571b0b259eSBruce Evans * time from the filesystem. Pretend that proc0 started now. 4582b14f991SJulian Elischer */ 4591005a129SJohn Baldwin sx_slock(&allproc_lock); 46037b087a6SPeter Wemm LIST_FOREACH(p, &allproc, p_list) { 46187ccef7bSDag-Erling Smørgrav microuptime(&p->p_stats->p_start); 46278c85e8dSJohn Baldwin p->p_rux.rux_runtime.sec = 0; 46378c85e8dSJohn Baldwin p->p_rux.rux_runtime.frac = 0; 46437b087a6SPeter Wemm } 4651005a129SJohn Baldwin sx_sunlock(&allproc_lock); 466e2256f43SPeter Wemm binuptime(PCPU_PTR(switchtime)); 4670384fff8SJason Evans PCPU_SET(switchticks, ticks); 4682b14f991SJulian Elischer 469a6fc8288SPeter Wemm /* 470a6fc8288SPeter Wemm * Give the ``random'' number generator a thump. 471a6fc8288SPeter Wemm */ 47200af9731SPoul-Henning Kamp nanotime(&ts); 47300af9731SPoul-Henning Kamp srandom(ts.tv_sec ^ ts.tv_nsec); 4742b14f991SJulian Elischer } 4752b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) 4762b14f991SJulian Elischer 477df8bae1dSRodney W. Grimes /* 4782b14f991SJulian Elischer *************************************************************************** 4792b14f991SJulian Elischer **** 4802b14f991SJulian Elischer **** The following SYSINIT's and glue code should be moved to the 4812b14f991SJulian Elischer **** respective files on a per subsystem basis. 4822b14f991SJulian Elischer **** 4832b14f991SJulian Elischer *************************************************************************** 484df8bae1dSRodney W. Grimes */ 485df8bae1dSRodney W. Grimes 486df8bae1dSRodney W. Grimes 487df8bae1dSRodney W. Grimes /* 4882b14f991SJulian Elischer *************************************************************************** 4892b14f991SJulian Elischer **** 4902b14f991SJulian Elischer **** The following code probably belongs in another file, like 49137b087a6SPeter Wemm **** kern/init_init.c. 4922b14f991SJulian Elischer **** 4932b14f991SJulian Elischer *************************************************************************** 494df8bae1dSRodney W. Grimes */ 495df8bae1dSRodney W. Grimes 496df8bae1dSRodney W. Grimes /* 497df8bae1dSRodney W. Grimes * List of paths to try when searching for "init". 498df8bae1dSRodney W. Grimes */ 4995f967b24SDag-Erling Smørgrav static char init_path[MAXPATHLEN] = 50067481196SJohn Birrell #ifdef INIT_PATH 50167481196SJohn Birrell __XSTRING(INIT_PATH); 50267481196SJohn Birrell #else 503f3f4baf0SDag-Erling Smørgrav "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall"; 50467481196SJohn Birrell #endif 505af1408e3SLuigi Rizzo SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0, 506af1408e3SLuigi Rizzo "Path used to search the init process"); 507df8bae1dSRodney W. Grimes 508df8bae1dSRodney W. Grimes /* 509724447acSRalf S. Engelschall * Shutdown timeout of init(8). 510724447acSRalf S. Engelschall * Unused within kernel, but used to control init(8), hence do not remove. 511724447acSRalf S. Engelschall */ 512724447acSRalf S. Engelschall #ifndef INIT_SHUTDOWN_TIMEOUT 513724447acSRalf S. Engelschall #define INIT_SHUTDOWN_TIMEOUT 120 514724447acSRalf S. Engelschall #endif 515724447acSRalf S. Engelschall static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT; 516724447acSRalf S. Engelschall SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout, 517724447acSRalf S. Engelschall CTLFLAG_RW, &init_shutdown_timeout, 0, ""); 518724447acSRalf S. Engelschall 519724447acSRalf S. Engelschall /* 5205f967b24SDag-Erling Smørgrav * Start the initial user process; try exec'ing each pathname in init_path. 521df8bae1dSRodney W. Grimes * The program is invoked with one argument containing the boot flags. 522df8bae1dSRodney W. Grimes */ 523df8bae1dSRodney W. Grimes static void 52437b087a6SPeter Wemm start_init(void *dummy) 525df8bae1dSRodney W. Grimes { 526df8bae1dSRodney W. Grimes vm_offset_t addr; 527df8bae1dSRodney W. Grimes struct execve_args args; 5285f967b24SDag-Erling Smørgrav int options, error; 5295f967b24SDag-Erling Smørgrav char *var, *path, *next, *s; 5305f967b24SDag-Erling Smørgrav char *ucp, **uap, *arg0, *arg1; 531b40ce416SJulian Elischer struct thread *td; 5329c8b8baaSPeter Wemm struct proc *p; 533df8bae1dSRodney W. Grimes 5349ed346baSBosko Milekic mtx_lock(&Giant); 5350384fff8SJason Evans 5360cddd8f0SMatthew Dillon GIANT_REQUIRED; 5370cddd8f0SMatthew Dillon 538b40ce416SJulian Elischer td = curthread; 539b40ce416SJulian Elischer p = td->td_proc; 540df8bae1dSRodney W. Grimes 541563af2ecSMaxime Henrion vfs_mountroot(); 542fb92273bSPoul-Henning Kamp 543b7116168SPeter Wemm /* 544df8bae1dSRodney W. Grimes * Need just enough stack to hold the faked-up "execve()" arguments. 545df8bae1dSRodney W. Grimes */ 54605ba50f5SJake Burkholder addr = p->p_sysent->sv_usrstack - PAGE_SIZE; 5475f967b24SDag-Erling Smørgrav if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, 5485f967b24SDag-Erling Smørgrav FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 549df8bae1dSRodney W. Grimes panic("init: couldn't allocate argument space"); 550df8bae1dSRodney W. Grimes p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 55126f9a767SRodney W. Grimes p->p_vmspace->vm_ssize = 1; 552df8bae1dSRodney W. Grimes 5535f967b24SDag-Erling Smørgrav if ((var = getenv("init_path")) != NULL) { 554e80fb434SRobert Drehmel strlcpy(init_path, var, sizeof(init_path)); 555d786139cSMaxime Henrion freeenv(var); 5565f967b24SDag-Erling Smørgrav } 5575f967b24SDag-Erling Smørgrav 55867481196SJohn Birrell for (path = init_path; *path != '\0'; path = next) { 559e4082284SJohn Birrell while (*path == ':') 5605f967b24SDag-Erling Smørgrav path++; 56167481196SJohn Birrell if (*path == '\0') 5625f967b24SDag-Erling Smørgrav break; 563e4082284SJohn Birrell for (next = path; *next != '\0' && *next != ':'; next++) 5645f967b24SDag-Erling Smørgrav /* nothing */ ; 5655f967b24SDag-Erling Smørgrav if (bootverbose) 566ba41a07dSDmitrij Tejblum printf("start_init: trying %.*s\n", (int)(next - path), 567ba41a07dSDmitrij Tejblum path); 5685f967b24SDag-Erling Smørgrav 569df8bae1dSRodney W. Grimes /* 570df8bae1dSRodney W. Grimes * Move out the boot flag argument. 571df8bae1dSRodney W. Grimes */ 572df8bae1dSRodney W. Grimes options = 0; 57305ba50f5SJake Burkholder ucp = (char *)p->p_sysent->sv_usrstack; 574df8bae1dSRodney W. Grimes (void)subyte(--ucp, 0); /* trailing zero */ 575df8bae1dSRodney W. Grimes if (boothowto & RB_SINGLE) { 576df8bae1dSRodney W. Grimes (void)subyte(--ucp, 's'); 577df8bae1dSRodney W. Grimes options = 1; 578df8bae1dSRodney W. Grimes } 579df8bae1dSRodney W. Grimes #ifdef notyet 580df8bae1dSRodney W. Grimes if (boothowto & RB_FASTBOOT) { 581df8bae1dSRodney W. Grimes (void)subyte(--ucp, 'f'); 582df8bae1dSRodney W. Grimes options = 1; 583df8bae1dSRodney W. Grimes } 584df8bae1dSRodney W. Grimes #endif 58517755ac8SPoul-Henning Kamp 58617755ac8SPoul-Henning Kamp #ifdef BOOTCDROM 58717755ac8SPoul-Henning Kamp (void)subyte(--ucp, 'C'); 58817755ac8SPoul-Henning Kamp options = 1; 58917755ac8SPoul-Henning Kamp #endif 590db901281SPoul-Henning Kamp 591df8bae1dSRodney W. Grimes if (options == 0) 592df8bae1dSRodney W. Grimes (void)subyte(--ucp, '-'); 593df8bae1dSRodney W. Grimes (void)subyte(--ucp, '-'); /* leading hyphen */ 594df8bae1dSRodney W. Grimes arg1 = ucp; 595df8bae1dSRodney W. Grimes 596df8bae1dSRodney W. Grimes /* 597df8bae1dSRodney W. Grimes * Move out the file name (also arg 0). 598df8bae1dSRodney W. Grimes */ 5995f967b24SDag-Erling Smørgrav (void)subyte(--ucp, 0); 6005f967b24SDag-Erling Smørgrav for (s = next - 1; s >= path; s--) 6015f967b24SDag-Erling Smørgrav (void)subyte(--ucp, *s); 602df8bae1dSRodney W. Grimes arg0 = ucp; 603df8bae1dSRodney W. Grimes 604df8bae1dSRodney W. Grimes /* 605df8bae1dSRodney W. Grimes * Move out the arg pointers. 606df8bae1dSRodney W. Grimes */ 607a20d7755SDoug Rabson uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1)); 608c2da0fd9SBruce Evans (void)suword((caddr_t)--uap, (long)0); /* terminator */ 609c2da0fd9SBruce Evans (void)suword((caddr_t)--uap, (long)(intptr_t)arg1); 610c2da0fd9SBruce Evans (void)suword((caddr_t)--uap, (long)(intptr_t)arg0); 611df8bae1dSRodney W. Grimes 612df8bae1dSRodney W. Grimes /* 613df8bae1dSRodney W. Grimes * Point at the arguments. 614df8bae1dSRodney W. Grimes */ 615df8bae1dSRodney W. Grimes args.fname = arg0; 61626f9a767SRodney W. Grimes args.argv = uap; 61726f9a767SRodney W. Grimes args.envv = NULL; 618df8bae1dSRodney W. Grimes 619df8bae1dSRodney W. Grimes /* 620df8bae1dSRodney W. Grimes * Now try to exec the program. If can't for any reason 621df8bae1dSRodney W. Grimes * other than it doesn't exist, complain. 6222b14f991SJulian Elischer * 62337b087a6SPeter Wemm * Otherwise, return via fork_trampoline() all the way 6249c8b8baaSPeter Wemm * to user mode as init! 625df8bae1dSRodney W. Grimes */ 626b40ce416SJulian Elischer if ((error = execve(td, &args)) == 0) { 6279ed346baSBosko Milekic mtx_unlock(&Giant); 628df8bae1dSRodney W. Grimes return; 629db72809dSJohn Baldwin } 630df8bae1dSRodney W. Grimes if (error != ENOENT) 631ba41a07dSDmitrij Tejblum printf("exec %.*s: error %d\n", (int)(next - path), 632ba41a07dSDmitrij Tejblum path, error); 633df8bae1dSRodney W. Grimes } 634580e7e5aSGreg Lehey printf("init: not found in path %s\n", init_path); 635df8bae1dSRodney W. Grimes panic("no init"); 636df8bae1dSRodney W. Grimes } 63737b087a6SPeter Wemm 63837b087a6SPeter Wemm /* 63937b087a6SPeter Wemm * Like kthread_create(), but runs in it's own address space. 64037b087a6SPeter Wemm * We do this early to reserve pid 1. 64137b087a6SPeter Wemm * 64237b087a6SPeter Wemm * Note special case - do not make it runnable yet. Other work 64337b087a6SPeter Wemm * in progress will change this more. 64437b087a6SPeter Wemm */ 64537b087a6SPeter Wemm static void 64637b087a6SPeter Wemm create_init(const void *udata __unused) 64737b087a6SPeter Wemm { 6485a06cb0cSRobert Watson struct ucred *newcred, *oldcred; 64937b087a6SPeter Wemm int error; 65037b087a6SPeter Wemm 651316ec49aSScott Long error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc); 65237b087a6SPeter Wemm if (error) 65337b087a6SPeter Wemm panic("cannot fork init: %d\n", error); 654bafc8f25SRobert Watson KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1")); 6555a06cb0cSRobert Watson /* divorce init's credentials from the kernel's */ 6565a06cb0cSRobert Watson newcred = crget(); 657f202965eSJohn Baldwin PROC_LOCK(initproc); 658f202965eSJohn Baldwin initproc->p_flag |= P_SYSTEM; 6595a06cb0cSRobert Watson oldcred = initproc->p_ucred; 6605a06cb0cSRobert Watson crcopy(newcred, oldcred); 66140244964SRobert Watson #ifdef MAC 66240244964SRobert Watson mac_create_proc1(newcred); 66340244964SRobert Watson #endif 6643683665bSRobert Watson #ifdef AUDIT 6653683665bSRobert Watson audit_proc_init(initproc); 6663683665bSRobert Watson #endif 6675a06cb0cSRobert Watson initproc->p_ucred = newcred; 668f202965eSJohn Baldwin PROC_UNLOCK(initproc); 6695a06cb0cSRobert Watson crfree(oldcred); 6704d1a4bb7SRobert Watson cred_update_thread(FIRST_THREAD_IN_PROC(initproc)); 6719ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 672f202965eSJohn Baldwin initproc->p_sflag |= PS_INMEM; 6739ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 674079b7badSJulian Elischer cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL); 67537b087a6SPeter Wemm } 67637b087a6SPeter Wemm SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL) 67737b087a6SPeter Wemm 67837b087a6SPeter Wemm /* 67937b087a6SPeter Wemm * Make it runnable now. 68037b087a6SPeter Wemm */ 68137b087a6SPeter Wemm static void 68237b087a6SPeter Wemm kick_init(const void *udata __unused) 68337b087a6SPeter Wemm { 684079b7badSJulian Elischer struct thread *td; 685f202965eSJohn Baldwin 686079b7badSJulian Elischer td = FIRST_THREAD_IN_PROC(initproc); 6879ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 68871fad9fdSJulian Elischer TD_SET_CAN_RUN(td); 6892630e4c9SJulian Elischer setrunqueue(td, SRQ_BORING); /* XXXKSE */ 6909ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 69137b087a6SPeter Wemm } 69237b087a6SPeter Wemm SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL) 693