1df8bae1dSRodney W. Grimes /* 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 42b1508c72SDavid Greenman * $Id: init_main.c,v 1.43 1996/06/14 11:01:25 asami Exp $ 43df8bae1dSRodney W. Grimes */ 44df8bae1dSRodney W. Grimes 454bd49128SPeter Wemm #include "opt_rlimit.h" 464bd49128SPeter Wemm 47df8bae1dSRodney W. Grimes #include <sys/param.h> 48df8bae1dSRodney W. Grimes #include <sys/filedesc.h> 49df8bae1dSRodney W. Grimes #include <sys/errno.h> 50df8bae1dSRodney W. Grimes #include <sys/exec.h> 51df8bae1dSRodney W. Grimes #include <sys/kernel.h> 52946bb7a2SPoul-Henning Kamp #include <sys/sysctl.h> 53b5e8ce9fSBruce Evans #ifdef GPROF 54b5e8ce9fSBruce Evans #include <sys/gmon.h> 55b5e8ce9fSBruce Evans #endif 56df8bae1dSRodney W. Grimes #include <sys/mount.h> 57df8bae1dSRodney W. Grimes #include <sys/proc.h> 58df8bae1dSRodney W. Grimes #include <sys/resourcevar.h> 59df8bae1dSRodney W. Grimes #include <sys/signalvar.h> 60df8bae1dSRodney W. Grimes #include <sys/systm.h> 61df8bae1dSRodney W. Grimes #include <sys/vnode.h> 62f3f0ca60SSøren Schmidt #include <sys/sysent.h> 63df8bae1dSRodney W. Grimes #include <sys/conf.h> 64df8bae1dSRodney W. Grimes #include <sys/buf.h> 65df8bae1dSRodney W. Grimes #include <sys/clist.h> 663aa12267SBruce Evans #include <sys/msg.h> 67df8bae1dSRodney W. Grimes #include <sys/protosw.h> 68df8bae1dSRodney W. Grimes #include <sys/reboot.h> 693aa12267SBruce Evans #include <sys/sem.h> 703aa12267SBruce Evans #include <sys/shm.h> 71ad7507e2SSteven Wallace #include <sys/sysproto.h> 72efeaf95aSDavid Greenman #include <sys/vmmeter.h> 73df8bae1dSRodney W. Grimes 74df8bae1dSRodney W. Grimes #include <ufs/ufs/quota.h> 75df8bae1dSRodney W. Grimes 76df8bae1dSRodney W. Grimes #include <machine/cpu.h> 77df8bae1dSRodney W. Grimes 78df8bae1dSRodney W. Grimes #include <vm/vm.h> 79efeaf95aSDavid Greenman #include <vm/vm_param.h> 80efeaf95aSDavid Greenman #include <vm/vm_prot.h> 81efeaf95aSDavid Greenman #include <vm/lock.h> 82efeaf95aSDavid Greenman #include <vm/pmap.h> 83efeaf95aSDavid Greenman #include <vm/vm_map.h> 84efeaf95aSDavid Greenman #include <vm/vm_extern.h> 85efeaf95aSDavid Greenman #include <sys/user.h> 86df8bae1dSRodney W. Grimes 879ef6c28aSBruce Evans extern struct linker_set sysinit_set; /* XXX */ 889ef6c28aSBruce Evans 899ef6c28aSBruce Evans extern void __main __P((void)); 909ef6c28aSBruce Evans extern void main __P((void *framep)); 91df8bae1dSRodney W. Grimes 92df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */ 93154c04e5SPoul-Henning Kamp static struct session session0; 94154c04e5SPoul-Henning Kamp static struct pgrp pgrp0; 95df8bae1dSRodney W. Grimes struct proc proc0; 96154c04e5SPoul-Henning Kamp static struct pcred cred0; 97154c04e5SPoul-Henning Kamp static struct filedesc0 filedesc0; 98154c04e5SPoul-Henning Kamp static struct plimit limit0; 99154c04e5SPoul-Henning Kamp static struct vmspace vmspace0; 100df8bae1dSRodney W. Grimes struct proc *curproc = &proc0; 1012b14f991SJulian Elischer struct proc *initproc; 102df8bae1dSRodney W. Grimes 103dedb7b62SPeter Wemm int cmask = CMASK; 104df8bae1dSRodney W. Grimes extern struct user *proc0paddr; 105df8bae1dSRodney W. Grimes 1062976b7f1SDavid Greenman struct vnode *rootvp; 107df8bae1dSRodney W. Grimes int boothowto; 108946bb7a2SPoul-Henning Kamp 109df8bae1dSRodney W. Grimes struct timeval boottime; 110946bb7a2SPoul-Henning Kamp SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, 111946bb7a2SPoul-Henning Kamp CTLFLAG_RW, &boottime, timeval, ""); 112946bb7a2SPoul-Henning Kamp 113df8bae1dSRodney W. Grimes struct timeval runtime; 114df8bae1dSRodney W. Grimes 1152b14f991SJulian Elischer /* 1162b14f991SJulian Elischer * Promiscuous argument pass for start_init() 1172b14f991SJulian Elischer * 1182b14f991SJulian Elischer * This is a kludge because we use a return from main() rather than a call 1192b14f991SJulian Elischer * to a new reoutine in locore.s to kick the kernel alive from locore.s. 1202b14f991SJulian Elischer */ 1212b14f991SJulian Elischer static void *init_framep; 1222b14f991SJulian Elischer 123df8bae1dSRodney W. Grimes 12426f9a767SRodney W. Grimes #if __GNUC__ >= 2 12526f9a767SRodney W. Grimes void __main() {} 12626f9a767SRodney W. Grimes #endif 12726f9a767SRodney W. Grimes 1282b14f991SJulian Elischer 12926f9a767SRodney W. Grimes /* 1302b14f991SJulian Elischer * This ensures that there is at least one entry so that the sysinit_set 1312b14f991SJulian Elischer * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never 1322b14f991SJulian Elischer * executed. 13326f9a767SRodney W. Grimes */ 1342b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL) 1358a129caeSDavid Greenman 13626f9a767SRodney W. Grimes 137df8bae1dSRodney W. Grimes /* 138df8bae1dSRodney W. Grimes * System startup; initialize the world, create process 0, mount root 139df8bae1dSRodney W. Grimes * filesystem, and fork to create init and pagedaemon. Most of the 140df8bae1dSRodney W. Grimes * hard work is done in the lower-level initialization routines including 141df8bae1dSRodney W. Grimes * startup(), which does memory initialization and autoconfiguration. 1422b14f991SJulian Elischer * 1432b14f991SJulian Elischer * This allows simple addition of new kernel subsystems that require 1442b14f991SJulian Elischer * boot time initialization. It also allows substitution of subsystem 1452b14f991SJulian Elischer * (for instance, a scheduler, kernel profiler, or VM system) by object 1462b14f991SJulian Elischer * module. Finally, it allows for optional "kernel threads", like an LFS 1472b14f991SJulian Elischer * cleaner. 148df8bae1dSRodney W. Grimes */ 14926f9a767SRodney W. Grimes void 150df8bae1dSRodney W. Grimes main(framep) 151df8bae1dSRodney W. Grimes void *framep; 152df8bae1dSRodney W. Grimes { 1532b14f991SJulian Elischer 1542b14f991SJulian Elischer register struct sysinit **sipp; /* system initialization*/ 1552b14f991SJulian Elischer register struct sysinit **xipp; /* interior loop of sort*/ 1562b14f991SJulian Elischer register struct sysinit *save; /* bubble*/ 1572b14f991SJulian Elischer int rval[2]; /* SI_TYPE_KTHREAD support*/ 1582b14f991SJulian Elischer 1592b14f991SJulian Elischer /* 1602b14f991SJulian Elischer * Save the locore.s frame pointer for start_init(). 1612b14f991SJulian Elischer */ 1622b14f991SJulian Elischer init_framep = framep; 1632b14f991SJulian Elischer 1642b14f991SJulian Elischer /* 1652b14f991SJulian Elischer * Perform a bubble sort of the system initialization objects by 1662b14f991SJulian Elischer * their subsystem (primary key) and order (secondary key). 1672b14f991SJulian Elischer * 1682b14f991SJulian Elischer * Since some things care about execution order, this is the 1692b14f991SJulian Elischer * operation which ensures continued function. 1702b14f991SJulian Elischer */ 1712b14f991SJulian Elischer for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) { 1722b14f991SJulian Elischer for( xipp = sipp + 1; *xipp; xipp++) { 1732b14f991SJulian Elischer if( (*sipp)->subsystem < (*xipp)->subsystem || 1742b14f991SJulian Elischer ( (*sipp)->subsystem == (*xipp)->subsystem && 1752b14f991SJulian Elischer (*sipp)->order < (*xipp)->order)) 1762b14f991SJulian Elischer continue; /* skip*/ 1772b14f991SJulian Elischer save = *sipp; 1782b14f991SJulian Elischer *sipp = *xipp; 1792b14f991SJulian Elischer *xipp = save; 1802b14f991SJulian Elischer } 1812b14f991SJulian Elischer } 1822b14f991SJulian Elischer 1832b14f991SJulian Elischer /* 1842b14f991SJulian Elischer * Traverse the (now) ordered list of system initialization tasks. 1852b14f991SJulian Elischer * Perform each task, and continue on to the next task. 1862b14f991SJulian Elischer * 1872b14f991SJulian Elischer * The last item on the list is expected to be the scheduler, 1882b14f991SJulian Elischer * which will not return. 1892b14f991SJulian Elischer */ 1902b14f991SJulian Elischer for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) { 1912b14f991SJulian Elischer if( (*sipp)->subsystem == SI_SUB_DUMMY) 1922b14f991SJulian Elischer continue; /* skip dummy task(s)*/ 1932b14f991SJulian Elischer 1942b14f991SJulian Elischer switch( (*sipp)->type) { 1952b14f991SJulian Elischer case SI_TYPE_DEFAULT: 1962b14f991SJulian Elischer /* no special processing*/ 1972b14f991SJulian Elischer (*((*sipp)->func))( (*sipp)->udata); 1982b14f991SJulian Elischer break; 1992b14f991SJulian Elischer 2002b14f991SJulian Elischer case SI_TYPE_KTHREAD: 2012b14f991SJulian Elischer /* kernel thread*/ 2022b14f991SJulian Elischer if (fork(&proc0, NULL, rval)) 2032b14f991SJulian Elischer panic("fork kernel process"); 2042b14f991SJulian Elischer if (rval[1]) { 2052b14f991SJulian Elischer (*((*sipp)->func))( (*sipp)->udata); 2062b14f991SJulian Elischer /* 2072b14f991SJulian Elischer * The call to start "init" returns 2082b14f991SJulian Elischer * here after the scheduler has been 2092b14f991SJulian Elischer * started, and returns to the caller 2102b14f991SJulian Elischer * in i386/i386/locore.s. This is a 2112b14f991SJulian Elischer * necessary part of initialization 2122b14f991SJulian Elischer * and is rather non-obvious. 2132b14f991SJulian Elischer * 2142b14f991SJulian Elischer * No other "kernel threads" should 2152b14f991SJulian Elischer * return here. Call panic() instead. 2162b14f991SJulian Elischer */ 2172b14f991SJulian Elischer return; 2182b14f991SJulian Elischer } 2192b14f991SJulian Elischer break; 2202b14f991SJulian Elischer 2212b14f991SJulian Elischer default: 2222b14f991SJulian Elischer panic( "init_main: unrecognized init type"); 2232b14f991SJulian Elischer } 2242b14f991SJulian Elischer } 2252b14f991SJulian Elischer 2262b14f991SJulian Elischer /* NOTREACHED*/ 2272b14f991SJulian Elischer } 2282b14f991SJulian Elischer 2292b14f991SJulian Elischer 2302b14f991SJulian Elischer /* 2312b14f991SJulian Elischer * Start a kernel process. This is called after a fork() call in 2322b14f991SJulian Elischer * main() in the file kern/init_main.c. 2332b14f991SJulian Elischer * 2342b14f991SJulian Elischer * This function is used to start "internal" daemons. 2352b14f991SJulian Elischer */ 2362b14f991SJulian Elischer /* ARGSUSED*/ 2372b14f991SJulian Elischer void 2382b14f991SJulian Elischer kproc_start(udata) 239d841aaa7SBruce Evans void *udata; 2402b14f991SJulian Elischer { 241d841aaa7SBruce Evans struct kproc_desc *kp = udata; 2422b14f991SJulian Elischer struct proc *p = curproc; 2432b14f991SJulian Elischer 2442b14f991SJulian Elischer /* save a global descriptor, if desired*/ 2452b14f991SJulian Elischer if( kp->global_procpp != NULL) 2462b14f991SJulian Elischer *kp->global_procpp = p; 2472b14f991SJulian Elischer 2482b14f991SJulian Elischer /* this is a non-swapped system process*/ 2492b14f991SJulian Elischer p->p_flag |= P_INMEM | P_SYSTEM; 2502b14f991SJulian Elischer 2512b14f991SJulian Elischer /* set up arg0 for 'ps', et al*/ 2522b14f991SJulian Elischer strcpy( p->p_comm, kp->arg0); 2532b14f991SJulian Elischer 2542b14f991SJulian Elischer /* call the processes' main()...*/ 2552b14f991SJulian Elischer (*kp->func)(); 2562b14f991SJulian Elischer 2572b14f991SJulian Elischer /* NOTREACHED */ 2582b14f991SJulian Elischer panic("kproc_start: %s", kp->arg0); 2592b14f991SJulian Elischer } 2602b14f991SJulian Elischer 2612b14f991SJulian Elischer 2622b14f991SJulian Elischer /* 2632b14f991SJulian Elischer *************************************************************************** 2642b14f991SJulian Elischer **** 2652b14f991SJulian Elischer **** The following SYSINIT's belong elsewhere, but have not yet 2662b14f991SJulian Elischer **** been moved. 2672b14f991SJulian Elischer **** 2682b14f991SJulian Elischer *************************************************************************** 2692b14f991SJulian Elischer */ 2702b14f991SJulian Elischer #ifdef OMIT 2712b14f991SJulian Elischer /* 2722b14f991SJulian Elischer * Handled by vfs_mountroot (bad idea) at this time... should be 2732b14f991SJulian Elischer * done the same as 4.4Lite2. 2742b14f991SJulian Elischer */ 2752b14f991SJulian Elischer SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL) 2762b14f991SJulian Elischer #endif /* OMIT*/ 2772b14f991SJulian Elischer 2782b14f991SJulian Elischer /* 2792b14f991SJulian Elischer * Should get its own file... 2802b14f991SJulian Elischer */ 2812b14f991SJulian Elischer #ifdef HPFPLIB 2822b14f991SJulian Elischer char copyright[] = 2832b14f991SJulian Elischer "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n"; 2842b14f991SJulian Elischer #else 2852b14f991SJulian Elischer char copyright[] = 286ad63a118SSatoshi Asami #ifdef PC98 287ad63a118SSatoshi Asami "Copyright (c) 1994-1996 FreeBSD(98) porting team.\n" 288ad63a118SSatoshi Asami "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\n" 289ad63a118SSatoshi Asami "Copyright (c) 1992 A.Kojima F.Ukai M.Ishii (KMC).\n" 290ad63a118SSatoshi Asami "\tAll rights reserved.\n\n"; 291ad63a118SSatoshi Asami #else 2922b14f991SJulian Elischer "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n"; 2932b14f991SJulian Elischer #endif 294ad63a118SSatoshi Asami #endif 2954590fd3aSDavid Greenman static void print_caddr_t __P((void *data)); 2969ef6c28aSBruce Evans static void 2979ef6c28aSBruce Evans print_caddr_t(data) 2984590fd3aSDavid Greenman void *data; 2999ef6c28aSBruce Evans { 3009ef6c28aSBruce Evans printf("%s", (char *)data); 3019ef6c28aSBruce Evans } 302d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) 3032b14f991SJulian Elischer 3042b14f991SJulian Elischer 3052b14f991SJulian Elischer /* 3062b14f991SJulian Elischer *************************************************************************** 3072b14f991SJulian Elischer **** 3082b14f991SJulian Elischer **** The two following SYSINT's are proc0 specific glue code. I am not 3092b14f991SJulian Elischer **** convinced that they can not be safely combined, but their order of 3102b14f991SJulian Elischer **** operation has been maintained as the same as the original init_main.c 3112b14f991SJulian Elischer **** for right now. 3122b14f991SJulian Elischer **** 3132b14f991SJulian Elischer **** These probably belong in init_proc.c or kern_proc.c, since they 3142b14f991SJulian Elischer **** deal with proc0 (the fork template process). 3152b14f991SJulian Elischer **** 3162b14f991SJulian Elischer *************************************************************************** 3172b14f991SJulian Elischer */ 3182b14f991SJulian Elischer /* ARGSUSED*/ 319154c04e5SPoul-Henning Kamp static void proc0_init __P((void *dummy)); 320154c04e5SPoul-Henning Kamp static void 321d841aaa7SBruce Evans proc0_init(dummy) 322d841aaa7SBruce Evans void *dummy; 3232b14f991SJulian Elischer { 324df8bae1dSRodney W. Grimes register struct proc *p; 325df8bae1dSRodney W. Grimes register struct filedesc0 *fdp; 326df8bae1dSRodney W. Grimes register int i; 327df8bae1dSRodney W. Grimes 328df8bae1dSRodney W. Grimes /* 329df8bae1dSRodney W. Grimes * Initialize the current process pointer (curproc) before 330df8bae1dSRodney W. Grimes * any possible traps/probes to simplify trap processing. 331df8bae1dSRodney W. Grimes */ 332df8bae1dSRodney W. Grimes p = &proc0; 3332b14f991SJulian Elischer curproc = p; /* XXX redundant*/ 334df8bae1dSRodney W. Grimes 335df8bae1dSRodney W. Grimes /* 336a3bfb996SJeffrey Hsu * Initialize process and pgrp structures. 337a3bfb996SJeffrey Hsu */ 338a3bfb996SJeffrey Hsu procinit(); 339a3bfb996SJeffrey Hsu 340a3bfb996SJeffrey Hsu /* 341b1508c72SDavid Greenman * Initialize sleep queue hash table 342b1508c72SDavid Greenman */ 343b1508c72SDavid Greenman sleepinit(); 344b1508c72SDavid Greenman 345b1508c72SDavid Greenman /* 346df8bae1dSRodney W. Grimes * Create process 0 (the swapper). 347df8bae1dSRodney W. Grimes */ 348a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&allproc, p, p_list); 349df8bae1dSRodney W. Grimes p->p_pgrp = &pgrp0; 350a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); 351a3bfb996SJeffrey Hsu LIST_INIT(&pgrp0.pg_members); 352a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); 353a3bfb996SJeffrey Hsu 354df8bae1dSRodney W. Grimes pgrp0.pg_session = &session0; 355df8bae1dSRodney W. Grimes session0.s_count = 1; 356df8bae1dSRodney W. Grimes session0.s_leader = p; 357df8bae1dSRodney W. Grimes 358f3f0ca60SSøren Schmidt p->p_sysent = &aout_sysvec; 359f3f0ca60SSøren Schmidt 360df8bae1dSRodney W. Grimes p->p_flag = P_INMEM | P_SYSTEM; 361df8bae1dSRodney W. Grimes p->p_stat = SRUN; 362df8bae1dSRodney W. Grimes p->p_nice = NZERO; 3637216391eSDavid Greenman p->p_rtprio.type = RTP_PRIO_NORMAL; 3647216391eSDavid Greenman p->p_rtprio.prio = 0; 365f992f480SDavid Greenman 366df8bae1dSRodney W. Grimes bcopy("swapper", p->p_comm, sizeof ("swapper")); 367df8bae1dSRodney W. Grimes 368df8bae1dSRodney W. Grimes /* Create credentials. */ 369df8bae1dSRodney W. Grimes cred0.p_refcnt = 1; 370df8bae1dSRodney W. Grimes p->p_cred = &cred0; 371df8bae1dSRodney W. Grimes p->p_ucred = crget(); 372df8bae1dSRodney W. Grimes p->p_ucred->cr_ngroups = 1; /* group 0 */ 373df8bae1dSRodney W. Grimes 374df8bae1dSRodney W. Grimes /* Create the file descriptor table. */ 375df8bae1dSRodney W. Grimes fdp = &filedesc0; 376df8bae1dSRodney W. Grimes p->p_fd = &fdp->fd_fd; 377df8bae1dSRodney W. Grimes fdp->fd_fd.fd_refcnt = 1; 378df8bae1dSRodney W. Grimes fdp->fd_fd.fd_cmask = cmask; 379df8bae1dSRodney W. Grimes fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 380df8bae1dSRodney W. Grimes fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 381df8bae1dSRodney W. Grimes fdp->fd_fd.fd_nfiles = NDFILE; 382df8bae1dSRodney W. Grimes 383df8bae1dSRodney W. Grimes /* Create the limits structures. */ 384df8bae1dSRodney W. Grimes p->p_limit = &limit0; 385df8bae1dSRodney W. Grimes for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 386df8bae1dSRodney W. Grimes limit0.pl_rlimit[i].rlim_cur = 387df8bae1dSRodney W. Grimes limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 388df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; 389df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 390df8bae1dSRodney W. Grimes i = ptoa(cnt.v_free_count); 391df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i; 392df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; 393df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; 394df8bae1dSRodney W. Grimes limit0.p_refcnt = 1; 395df8bae1dSRodney W. Grimes 396df8bae1dSRodney W. Grimes /* Allocate a prototype map so we have something to fork. */ 397df8bae1dSRodney W. Grimes p->p_vmspace = &vmspace0; 398df8bae1dSRodney W. Grimes vmspace0.vm_refcnt = 1; 399df8bae1dSRodney W. Grimes pmap_pinit(&vmspace0.vm_pmap); 40026f9a767SRodney W. Grimes vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS), 40147dcd2e5SJohn Dyson trunc_page(VM_MAXUSER_ADDRESS), TRUE); 402df8bae1dSRodney W. Grimes vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 403df8bae1dSRodney W. Grimes p->p_addr = proc0paddr; /* XXX */ 404df8bae1dSRodney W. Grimes 4052b14f991SJulian Elischer #define INCOMPAT_LITES2 4062b14f991SJulian Elischer #ifdef INCOMPAT_LITES2 407df8bae1dSRodney W. Grimes /* 4082384fde5SDavid Greenman * proc0 needs to have a coherent frame base, too. 4092384fde5SDavid Greenman * This probably makes the identical call for the init proc 4102384fde5SDavid Greenman * that happens later unnecessary since it should inherit 4112384fde5SDavid Greenman * it during the fork. 4122384fde5SDavid Greenman */ 4132b14f991SJulian Elischer cpu_set_init_frame(p, init_framep); /* XXX! */ 4142b14f991SJulian Elischer #endif /* INCOMPAT_LITES2*/ 4152384fde5SDavid Greenman 4162384fde5SDavid Greenman /* 417df8bae1dSRodney W. Grimes * We continue to place resource usage info and signal 418df8bae1dSRodney W. Grimes * actions in the user struct so they're pageable. 419df8bae1dSRodney W. Grimes */ 420df8bae1dSRodney W. Grimes p->p_stats = &p->p_addr->u_stats; 421df8bae1dSRodney W. Grimes p->p_sigacts = &p->p_addr->u_sigacts; 422df8bae1dSRodney W. Grimes 423df8bae1dSRodney W. Grimes /* 424a3bfb996SJeffrey Hsu * Charge root for one process. 425df8bae1dSRodney W. Grimes */ 426df8bae1dSRodney W. Grimes (void)chgproccnt(0, 1); 42726f9a767SRodney W. Grimes } 4282b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) 4292b14f991SJulian Elischer 4302b14f991SJulian Elischer /* ARGSUSED*/ 431154c04e5SPoul-Henning Kamp static void proc0_post __P((void *dummy)); 432154c04e5SPoul-Henning Kamp static void 433d841aaa7SBruce Evans proc0_post(dummy) 434d841aaa7SBruce Evans void *dummy; 4352b14f991SJulian Elischer { 4362b14f991SJulian Elischer /* 4372b14f991SJulian Elischer * Now can look at time, having had a chance to verify the time 4382b14f991SJulian Elischer * from the file system. Reset p->p_rtime as it may have been 4392b14f991SJulian Elischer * munched in mi_switch() after the time got set. 4402b14f991SJulian Elischer */ 4412b14f991SJulian Elischer proc0.p_stats->p_start = runtime = mono_time = boottime = time; 4422b14f991SJulian Elischer proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0; 4432b14f991SJulian Elischer 4442b14f991SJulian Elischer /* Initialize signal state for process 0. */ 4452b14f991SJulian Elischer siginit(&proc0); 4462b14f991SJulian Elischer } 4472b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) 4482b14f991SJulian Elischer 4492b14f991SJulian Elischer 4502b14f991SJulian Elischer 451df8bae1dSRodney W. Grimes 452df8bae1dSRodney W. Grimes /* 4532b14f991SJulian Elischer *************************************************************************** 4542b14f991SJulian Elischer **** 4552b14f991SJulian Elischer **** The following SYSINIT's and glue code should be moved to the 4562b14f991SJulian Elischer **** respective files on a per subsystem basis. 4572b14f991SJulian Elischer **** 4582b14f991SJulian Elischer *************************************************************************** 459df8bae1dSRodney W. Grimes */ 4602b14f991SJulian Elischer /* ARGSUSED*/ 461154c04e5SPoul-Henning Kamp static void sched_setup __P((void *dummy)); 462154c04e5SPoul-Henning Kamp static void 463d841aaa7SBruce Evans sched_setup(dummy) 464d841aaa7SBruce Evans void *dummy; 4652b14f991SJulian Elischer { 466df8bae1dSRodney W. Grimes /* Kick off timeout driven events by calling first time. */ 467df8bae1dSRodney W. Grimes roundrobin(NULL); 468df8bae1dSRodney W. Grimes schedcpu(NULL); 4692b14f991SJulian Elischer } 4702b14f991SJulian Elischer SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL) 471df8bae1dSRodney W. Grimes 4722b14f991SJulian Elischer /* ARGSUSED*/ 473154c04e5SPoul-Henning Kamp static void xxx_vfs_mountroot __P((void *dummy)); 474154c04e5SPoul-Henning Kamp static void 475d841aaa7SBruce Evans xxx_vfs_mountroot(dummy) 476d841aaa7SBruce Evans void *dummy; 4772b14f991SJulian Elischer { 478df8bae1dSRodney W. Grimes /* Mount the root file system. */ 4794590fd3aSDavid Greenman if ((*mountroot)(mountrootvfsops)) 480df8bae1dSRodney W. Grimes panic("cannot mount root"); 4812b14f991SJulian Elischer } 4822b14f991SJulian Elischer SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL) 4832b14f991SJulian Elischer 4842b14f991SJulian Elischer /* ARGSUSED*/ 485154c04e5SPoul-Henning Kamp static void xxx_vfs_root_fdtab __P((void *dummy)); 486154c04e5SPoul-Henning Kamp static void 487d841aaa7SBruce Evans xxx_vfs_root_fdtab(dummy) 488d841aaa7SBruce Evans void *dummy; 4892b14f991SJulian Elischer { 4902b14f991SJulian Elischer register struct filedesc0 *fdp = &filedesc0; 491df8bae1dSRodney W. Grimes 492df8bae1dSRodney W. Grimes /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ 493628641f8SDavid Greenman if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) 494df8bae1dSRodney W. Grimes panic("cannot find root vnode"); 495df8bae1dSRodney W. Grimes fdp->fd_fd.fd_cdir = rootvnode; 496df8bae1dSRodney W. Grimes VREF(fdp->fd_fd.fd_cdir); 497df8bae1dSRodney W. Grimes VOP_UNLOCK(rootvnode); 498df8bae1dSRodney W. Grimes fdp->fd_fd.fd_rdir = NULL; 4992b14f991SJulian Elischer } 5002b14f991SJulian Elischer SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL) 5012b14f991SJulian Elischer 502df8bae1dSRodney W. Grimes 503df8bae1dSRodney W. Grimes /* 5042b14f991SJulian Elischer *************************************************************************** 5052b14f991SJulian Elischer **** 5062b14f991SJulian Elischer **** The following code probably belongs in another file, like 5072b14f991SJulian Elischer **** kern/init_init.c. It is here for two reasons only: 5082b14f991SJulian Elischer **** 5092b14f991SJulian Elischer **** 1) This code returns to startup the system; this is 5102b14f991SJulian Elischer **** abnormal for a kernel thread. 5112b14f991SJulian Elischer **** 2) This code promiscuously uses init_frame 5122b14f991SJulian Elischer **** 5132b14f991SJulian Elischer *************************************************************************** 514df8bae1dSRodney W. Grimes */ 515df8bae1dSRodney W. Grimes 516d841aaa7SBruce Evans static void kthread_init __P((void *dummy)); 5172b14f991SJulian Elischer SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL) 5182b14f991SJulian Elischer 5192b14f991SJulian Elischer 5202b14f991SJulian Elischer static void start_init __P((struct proc *p, void *framep)); 5212b14f991SJulian Elischer 5222b14f991SJulian Elischer /* ARGSUSED*/ 5232b14f991SJulian Elischer static void 524d841aaa7SBruce Evans kthread_init(dummy) 525d841aaa7SBruce Evans void *dummy; 5262b14f991SJulian Elischer { 527df8bae1dSRodney W. Grimes 528df8bae1dSRodney W. Grimes /* Create process 1 (init(8)). */ 5292b14f991SJulian Elischer start_init(curproc, init_framep); 5302b14f991SJulian Elischer 5312b14f991SJulian Elischer /* 5322b14f991SJulian Elischer * This is the only kernel thread allowed to return yo the 5332b14f991SJulian Elischer * caller!!! 5342b14f991SJulian Elischer */ 535df8bae1dSRodney W. Grimes return; 536df8bae1dSRodney W. Grimes } 537df8bae1dSRodney W. Grimes 538df8bae1dSRodney W. Grimes 539df8bae1dSRodney W. Grimes /* 540df8bae1dSRodney W. Grimes * List of paths to try when searching for "init". 541df8bae1dSRodney W. Grimes */ 542df8bae1dSRodney W. Grimes static char *initpaths[] = { 543df8bae1dSRodney W. Grimes "/sbin/init", 544df8bae1dSRodney W. Grimes "/sbin/oinit", 545df8bae1dSRodney W. Grimes "/sbin/init.bak", 5462257b745SPoul-Henning Kamp "/stand/sysinstall", 547df8bae1dSRodney W. Grimes NULL, 548df8bae1dSRodney W. Grimes }; 549df8bae1dSRodney W. Grimes 550df8bae1dSRodney W. Grimes /* 551df8bae1dSRodney W. Grimes * Start the initial user process; try exec'ing each pathname in "initpaths". 552df8bae1dSRodney W. Grimes * The program is invoked with one argument containing the boot flags. 553df8bae1dSRodney W. Grimes */ 554df8bae1dSRodney W. Grimes static void 555df8bae1dSRodney W. Grimes start_init(p, framep) 556df8bae1dSRodney W. Grimes struct proc *p; 557df8bae1dSRodney W. Grimes void *framep; 558df8bae1dSRodney W. Grimes { 559df8bae1dSRodney W. Grimes vm_offset_t addr; 560df8bae1dSRodney W. Grimes struct execve_args args; 561df8bae1dSRodney W. Grimes int options, i, retval[2], error; 562df8bae1dSRodney W. Grimes char **pathp, *path, *ucp, **uap, *arg0, *arg1; 563df8bae1dSRodney W. Grimes 564df8bae1dSRodney W. Grimes initproc = p; 565df8bae1dSRodney W. Grimes 566df8bae1dSRodney W. Grimes /* 567df8bae1dSRodney W. Grimes * We need to set the system call frame as if we were entered through 568df8bae1dSRodney W. Grimes * a syscall() so that when we call execve() below, it will be able 569df8bae1dSRodney W. Grimes * to set the entry point (see setregs) when it tries to exec. The 570df8bae1dSRodney W. Grimes * startup code in "locore.s" has allocated space for the frame and 571df8bae1dSRodney W. Grimes * passed a pointer to that space as main's argument. 572df8bae1dSRodney W. Grimes */ 573df8bae1dSRodney W. Grimes cpu_set_init_frame(p, framep); 574df8bae1dSRodney W. Grimes 575df8bae1dSRodney W. Grimes /* 576df8bae1dSRodney W. Grimes * Need just enough stack to hold the faked-up "execve()" arguments. 577df8bae1dSRodney W. Grimes */ 57826f9a767SRodney W. Grimes addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE); 579bd7e5f99SJohn Dyson if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 580df8bae1dSRodney W. Grimes panic("init: couldn't allocate argument space"); 581df8bae1dSRodney W. Grimes p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 58226f9a767SRodney W. Grimes p->p_vmspace->vm_ssize = 1; 583df8bae1dSRodney W. Grimes 584df8bae1dSRodney W. Grimes for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { 585df8bae1dSRodney W. Grimes /* 586df8bae1dSRodney W. Grimes * Move out the boot flag argument. 587df8bae1dSRodney W. Grimes */ 588df8bae1dSRodney W. Grimes options = 0; 589df8bae1dSRodney W. Grimes ucp = (char *)USRSTACK; 590df8bae1dSRodney W. Grimes (void)subyte(--ucp, 0); /* trailing zero */ 591df8bae1dSRodney W. Grimes if (boothowto & RB_SINGLE) { 592df8bae1dSRodney W. Grimes (void)subyte(--ucp, 's'); 593df8bae1dSRodney W. Grimes options = 1; 594df8bae1dSRodney W. Grimes } 595df8bae1dSRodney W. Grimes #ifdef notyet 596df8bae1dSRodney W. Grimes if (boothowto & RB_FASTBOOT) { 597df8bae1dSRodney W. Grimes (void)subyte(--ucp, 'f'); 598df8bae1dSRodney W. Grimes options = 1; 599df8bae1dSRodney W. Grimes } 600df8bae1dSRodney W. Grimes #endif 60117755ac8SPoul-Henning Kamp 60217755ac8SPoul-Henning Kamp #ifdef BOOTCDROM 60317755ac8SPoul-Henning Kamp (void)subyte(--ucp, 'C'); 60417755ac8SPoul-Henning Kamp options = 1; 60517755ac8SPoul-Henning Kamp #endif 606df8bae1dSRodney W. Grimes if (options == 0) 607df8bae1dSRodney W. Grimes (void)subyte(--ucp, '-'); 608df8bae1dSRodney W. Grimes (void)subyte(--ucp, '-'); /* leading hyphen */ 609df8bae1dSRodney W. Grimes arg1 = ucp; 610df8bae1dSRodney W. Grimes 611df8bae1dSRodney W. Grimes /* 612df8bae1dSRodney W. Grimes * Move out the file name (also arg 0). 613df8bae1dSRodney W. Grimes */ 614df8bae1dSRodney W. Grimes for (i = strlen(path) + 1; i >= 0; i--) 615df8bae1dSRodney W. Grimes (void)subyte(--ucp, path[i]); 616df8bae1dSRodney W. Grimes arg0 = ucp; 617df8bae1dSRodney W. Grimes 618df8bae1dSRodney W. Grimes /* 619df8bae1dSRodney W. Grimes * Move out the arg pointers. 620df8bae1dSRodney W. Grimes */ 621df8bae1dSRodney W. Grimes uap = (char **)((int)ucp & ~(NBPW-1)); 622df8bae1dSRodney W. Grimes (void)suword((caddr_t)--uap, 0); /* terminator */ 623df8bae1dSRodney W. Grimes (void)suword((caddr_t)--uap, (int)arg1); 624df8bae1dSRodney W. Grimes (void)suword((caddr_t)--uap, (int)arg0); 625df8bae1dSRodney W. Grimes 626df8bae1dSRodney W. Grimes /* 627df8bae1dSRodney W. Grimes * Point at the arguments. 628df8bae1dSRodney W. Grimes */ 629df8bae1dSRodney W. Grimes args.fname = arg0; 63026f9a767SRodney W. Grimes args.argv = uap; 63126f9a767SRodney W. Grimes args.envv = NULL; 632df8bae1dSRodney W. Grimes 633df8bae1dSRodney W. Grimes /* 634df8bae1dSRodney W. Grimes * Now try to exec the program. If can't for any reason 635df8bae1dSRodney W. Grimes * other than it doesn't exist, complain. 6362b14f991SJulian Elischer * 6372b14f991SJulian Elischer * Otherwise return to main() which returns to btext 6382b14f991SJulian Elischer * which completes the system startup. 639df8bae1dSRodney W. Grimes */ 640b5e8ce9fSBruce Evans if ((error = execve(p, &args, &retval[0])) == 0) 641df8bae1dSRodney W. Grimes return; 642df8bae1dSRodney W. Grimes if (error != ENOENT) 643df8bae1dSRodney W. Grimes printf("exec %s: error %d\n", path, error); 644df8bae1dSRodney W. Grimes } 645df8bae1dSRodney W. Grimes printf("init: not found\n"); 646df8bae1dSRodney W. Grimes panic("no init"); 647df8bae1dSRodney W. Grimes } 648