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 421130b656SJordan K. Hubbard * $FreeBSD$ 43df8bae1dSRodney W. Grimes */ 44df8bae1dSRodney W. Grimes 454bd49128SPeter Wemm #include "opt_rlimit.h" 4619060a3aSPoul-Henning Kamp #include "opt_devfs.h" 474bd49128SPeter Wemm 48df8bae1dSRodney W. Grimes #include <sys/param.h> 49df8bae1dSRodney W. Grimes #include <sys/filedesc.h> 50df8bae1dSRodney W. Grimes #include <sys/kernel.h> 51ac0ad63fSBruce Evans #include <sys/mount.h> 52946bb7a2SPoul-Henning Kamp #include <sys/sysctl.h> 53df8bae1dSRodney W. Grimes #include <sys/proc.h> 54df8bae1dSRodney W. Grimes #include <sys/resourcevar.h> 55df8bae1dSRodney W. Grimes #include <sys/signalvar.h> 56df8bae1dSRodney W. Grimes #include <sys/systm.h> 57df8bae1dSRodney W. Grimes #include <sys/vnode.h> 58f3f0ca60SSøren Schmidt #include <sys/sysent.h> 59df8bae1dSRodney W. Grimes #include <sys/reboot.h> 60ad7507e2SSteven Wallace #include <sys/sysproto.h> 61efeaf95aSDavid Greenman #include <sys/vmmeter.h> 62df8bae1dSRodney W. Grimes 63df8bae1dSRodney W. Grimes #include <machine/cpu.h> 64df8bae1dSRodney W. Grimes 65df8bae1dSRodney W. Grimes #include <vm/vm.h> 66efeaf95aSDavid Greenman #include <vm/vm_param.h> 67efeaf95aSDavid Greenman #include <vm/vm_prot.h> 68efeaf95aSDavid Greenman #include <vm/lock.h> 69efeaf95aSDavid Greenman #include <vm/pmap.h> 70efeaf95aSDavid Greenman #include <vm/vm_map.h> 71efeaf95aSDavid Greenman #include <sys/user.h> 72df8bae1dSRodney W. Grimes 739ef6c28aSBruce Evans extern struct linker_set sysinit_set; /* XXX */ 749ef6c28aSBruce Evans 759ef6c28aSBruce Evans extern void __main __P((void)); 769ef6c28aSBruce Evans extern void main __P((void *framep)); 77df8bae1dSRodney W. Grimes 78df8bae1dSRodney W. Grimes /* Components of the first process -- never freed. */ 79154c04e5SPoul-Henning Kamp static struct session session0; 80154c04e5SPoul-Henning Kamp static struct pgrp pgrp0; 81df8bae1dSRodney W. Grimes struct proc proc0; 82154c04e5SPoul-Henning Kamp static struct pcred cred0; 83154c04e5SPoul-Henning Kamp static struct filedesc0 filedesc0; 84154c04e5SPoul-Henning Kamp static struct plimit limit0; 85154c04e5SPoul-Henning Kamp static struct vmspace vmspace0; 86df8bae1dSRodney W. Grimes struct proc *curproc = &proc0; 872b14f991SJulian Elischer struct proc *initproc; 88df8bae1dSRodney W. Grimes 89dedb7b62SPeter Wemm int cmask = CMASK; 90df8bae1dSRodney W. Grimes extern struct user *proc0paddr; 91df8bae1dSRodney W. Grimes 922976b7f1SDavid Greenman struct vnode *rootvp; 93df8bae1dSRodney W. Grimes int boothowto; 94946bb7a2SPoul-Henning Kamp 95df8bae1dSRodney W. Grimes struct timeval boottime; 96946bb7a2SPoul-Henning Kamp SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, 97946bb7a2SPoul-Henning Kamp CTLFLAG_RW, &boottime, timeval, ""); 98946bb7a2SPoul-Henning Kamp 99df8bae1dSRodney W. Grimes struct timeval runtime; 100df8bae1dSRodney W. Grimes 1012b14f991SJulian Elischer /* 1022b14f991SJulian Elischer * Promiscuous argument pass for start_init() 1032b14f991SJulian Elischer * 1042b14f991SJulian Elischer * This is a kludge because we use a return from main() rather than a call 10537b688c4SAlexander Langer * to a new routine in locore.s to kick the kernel alive from locore.s. 1062b14f991SJulian Elischer */ 1072b14f991SJulian Elischer static void *init_framep; 1082b14f991SJulian Elischer 109df8bae1dSRodney W. Grimes 11026f9a767SRodney W. Grimes #if __GNUC__ >= 2 11126f9a767SRodney W. Grimes void __main() {} 11226f9a767SRodney W. Grimes #endif 11326f9a767SRodney W. Grimes 1142b14f991SJulian Elischer 11526f9a767SRodney W. Grimes /* 1162b14f991SJulian Elischer * This ensures that there is at least one entry so that the sysinit_set 1172b14f991SJulian Elischer * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never 1182b14f991SJulian Elischer * executed. 11926f9a767SRodney W. Grimes */ 1202b14f991SJulian Elischer SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL) 1218a129caeSDavid Greenman 12226f9a767SRodney W. Grimes 123df8bae1dSRodney W. Grimes /* 124df8bae1dSRodney W. Grimes * System startup; initialize the world, create process 0, mount root 125df8bae1dSRodney W. Grimes * filesystem, and fork to create init and pagedaemon. Most of the 126df8bae1dSRodney W. Grimes * hard work is done in the lower-level initialization routines including 127df8bae1dSRodney W. Grimes * startup(), which does memory initialization and autoconfiguration. 1282b14f991SJulian Elischer * 1292b14f991SJulian Elischer * This allows simple addition of new kernel subsystems that require 1302b14f991SJulian Elischer * boot time initialization. It also allows substitution of subsystem 1312b14f991SJulian Elischer * (for instance, a scheduler, kernel profiler, or VM system) by object 1322b14f991SJulian Elischer * module. Finally, it allows for optional "kernel threads", like an LFS 1332b14f991SJulian Elischer * cleaner. 134df8bae1dSRodney W. Grimes */ 13526f9a767SRodney W. Grimes void 136df8bae1dSRodney W. Grimes main(framep) 137df8bae1dSRodney W. Grimes void *framep; 138df8bae1dSRodney W. Grimes { 1392b14f991SJulian Elischer 1402b14f991SJulian Elischer register struct sysinit **sipp; /* system initialization*/ 1412b14f991SJulian Elischer register struct sysinit **xipp; /* interior loop of sort*/ 1422b14f991SJulian Elischer register struct sysinit *save; /* bubble*/ 1432b14f991SJulian Elischer int rval[2]; /* SI_TYPE_KTHREAD support*/ 1442b14f991SJulian Elischer 1452b14f991SJulian Elischer /* 1462b14f991SJulian Elischer * Save the locore.s frame pointer for start_init(). 1472b14f991SJulian Elischer */ 1482b14f991SJulian Elischer init_framep = framep; 1492b14f991SJulian Elischer 1502b14f991SJulian Elischer /* 1512b14f991SJulian Elischer * Perform a bubble sort of the system initialization objects by 1522b14f991SJulian Elischer * their subsystem (primary key) and order (secondary key). 1532b14f991SJulian Elischer * 1542b14f991SJulian Elischer * Since some things care about execution order, this is the 1552b14f991SJulian Elischer * operation which ensures continued function. 1562b14f991SJulian Elischer */ 1572b14f991SJulian Elischer for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) { 1582b14f991SJulian Elischer for( xipp = sipp + 1; *xipp; xipp++) { 1592b14f991SJulian Elischer if( (*sipp)->subsystem < (*xipp)->subsystem || 1602b14f991SJulian Elischer ( (*sipp)->subsystem == (*xipp)->subsystem && 1612b14f991SJulian Elischer (*sipp)->order < (*xipp)->order)) 1622b14f991SJulian Elischer continue; /* skip*/ 1632b14f991SJulian Elischer save = *sipp; 1642b14f991SJulian Elischer *sipp = *xipp; 1652b14f991SJulian Elischer *xipp = save; 1662b14f991SJulian Elischer } 1672b14f991SJulian Elischer } 1682b14f991SJulian Elischer 1692b14f991SJulian Elischer /* 1702b14f991SJulian Elischer * Traverse the (now) ordered list of system initialization tasks. 1712b14f991SJulian Elischer * Perform each task, and continue on to the next task. 1722b14f991SJulian Elischer * 1732b14f991SJulian Elischer * The last item on the list is expected to be the scheduler, 1742b14f991SJulian Elischer * which will not return. 1752b14f991SJulian Elischer */ 1762b14f991SJulian Elischer for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) { 1772b14f991SJulian Elischer if( (*sipp)->subsystem == SI_SUB_DUMMY) 1782b14f991SJulian Elischer continue; /* skip dummy task(s)*/ 1792b14f991SJulian Elischer 1802b14f991SJulian Elischer switch( (*sipp)->type) { 1812b14f991SJulian Elischer case SI_TYPE_DEFAULT: 1822b14f991SJulian Elischer /* no special processing*/ 1832b14f991SJulian Elischer (*((*sipp)->func))( (*sipp)->udata); 1842b14f991SJulian Elischer break; 1852b14f991SJulian Elischer 1862b14f991SJulian Elischer case SI_TYPE_KTHREAD: 1872b14f991SJulian Elischer /* kernel thread*/ 1882b14f991SJulian Elischer if (fork(&proc0, NULL, rval)) 1892b14f991SJulian Elischer panic("fork kernel process"); 1902b14f991SJulian Elischer if (rval[1]) { 1912b14f991SJulian Elischer (*((*sipp)->func))( (*sipp)->udata); 1922b14f991SJulian Elischer /* 1932b14f991SJulian Elischer * The call to start "init" returns 1942b14f991SJulian Elischer * here after the scheduler has been 1952b14f991SJulian Elischer * started, and returns to the caller 1962b14f991SJulian Elischer * in i386/i386/locore.s. This is a 1972b14f991SJulian Elischer * necessary part of initialization 1982b14f991SJulian Elischer * and is rather non-obvious. 1992b14f991SJulian Elischer * 2002b14f991SJulian Elischer * No other "kernel threads" should 2012b14f991SJulian Elischer * return here. Call panic() instead. 2022b14f991SJulian Elischer */ 2032b14f991SJulian Elischer return; 2042b14f991SJulian Elischer } 2052b14f991SJulian Elischer break; 2062b14f991SJulian Elischer 2072b14f991SJulian Elischer default: 2082b14f991SJulian Elischer panic( "init_main: unrecognized init type"); 2092b14f991SJulian Elischer } 2102b14f991SJulian Elischer } 2112b14f991SJulian Elischer 2122b14f991SJulian Elischer /* NOTREACHED*/ 2132b14f991SJulian Elischer } 2142b14f991SJulian Elischer 2152b14f991SJulian Elischer 2162b14f991SJulian Elischer /* 2172b14f991SJulian Elischer * Start a kernel process. This is called after a fork() call in 2182b14f991SJulian Elischer * main() in the file kern/init_main.c. 2192b14f991SJulian Elischer * 2202b14f991SJulian Elischer * This function is used to start "internal" daemons. 2212b14f991SJulian Elischer */ 2222b14f991SJulian Elischer /* ARGSUSED*/ 2232b14f991SJulian Elischer void 2242b14f991SJulian Elischer kproc_start(udata) 225d841aaa7SBruce Evans void *udata; 2262b14f991SJulian Elischer { 227d841aaa7SBruce Evans struct kproc_desc *kp = udata; 2282b14f991SJulian Elischer struct proc *p = curproc; 2292b14f991SJulian Elischer 2302b14f991SJulian Elischer /* save a global descriptor, if desired*/ 2312b14f991SJulian Elischer if( kp->global_procpp != NULL) 2322b14f991SJulian Elischer *kp->global_procpp = p; 2332b14f991SJulian Elischer 2342b14f991SJulian Elischer /* this is a non-swapped system process*/ 2352b14f991SJulian Elischer p->p_flag |= P_INMEM | P_SYSTEM; 2362b14f991SJulian Elischer 2372b14f991SJulian Elischer /* set up arg0 for 'ps', et al*/ 2382b14f991SJulian Elischer strcpy( p->p_comm, kp->arg0); 2392b14f991SJulian Elischer 2402b14f991SJulian Elischer /* call the processes' main()...*/ 2412b14f991SJulian Elischer (*kp->func)(); 2422b14f991SJulian Elischer 2432b14f991SJulian Elischer /* NOTREACHED */ 2442b14f991SJulian Elischer panic("kproc_start: %s", kp->arg0); 2452b14f991SJulian Elischer } 2462b14f991SJulian Elischer 2472b14f991SJulian Elischer 2482b14f991SJulian Elischer /* 2492b14f991SJulian Elischer *************************************************************************** 2502b14f991SJulian Elischer **** 2512b14f991SJulian Elischer **** The following SYSINIT's belong elsewhere, but have not yet 2522b14f991SJulian Elischer **** been moved. 2532b14f991SJulian Elischer **** 2542b14f991SJulian Elischer *************************************************************************** 2552b14f991SJulian Elischer */ 2562b14f991SJulian Elischer #ifdef OMIT 2572b14f991SJulian Elischer /* 2582b14f991SJulian Elischer * Handled by vfs_mountroot (bad idea) at this time... should be 2592b14f991SJulian Elischer * done the same as 4.4Lite2. 2602b14f991SJulian Elischer */ 2612b14f991SJulian Elischer SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL) 2622b14f991SJulian Elischer #endif /* OMIT*/ 2632b14f991SJulian Elischer 2642b14f991SJulian Elischer /* 2652b14f991SJulian Elischer * Should get its own file... 2662b14f991SJulian Elischer */ 2672b14f991SJulian Elischer #ifdef HPFPLIB 2682b14f991SJulian Elischer char copyright[] = 2692b14f991SJulian 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"; 2702b14f991SJulian Elischer #else 2712b14f991SJulian Elischer char copyright[] = 272b316c8b2SSatoshi Asami "Copyright (c) 1992-1996 FreeBSD Inc.\n" 273ad63a118SSatoshi Asami #ifdef PC98 274ad63a118SSatoshi Asami "Copyright (c) 1994-1996 FreeBSD(98) porting team.\n" 275ad63a118SSatoshi Asami "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\n" 276ad63a118SSatoshi Asami "Copyright (c) 1992 A.Kojima F.Ukai M.Ishii (KMC).\n" 277ad63a118SSatoshi Asami "\tAll rights reserved.\n\n"; 278ad63a118SSatoshi Asami #else 2792b14f991SJulian Elischer "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n"; 2802b14f991SJulian Elischer #endif 281ad63a118SSatoshi Asami #endif 2824590fd3aSDavid Greenman static void print_caddr_t __P((void *data)); 2839ef6c28aSBruce Evans static void 2849ef6c28aSBruce Evans print_caddr_t(data) 2854590fd3aSDavid Greenman void *data; 2869ef6c28aSBruce Evans { 2879ef6c28aSBruce Evans printf("%s", (char *)data); 2889ef6c28aSBruce Evans } 289d841aaa7SBruce Evans SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) 2902b14f991SJulian Elischer 2912b14f991SJulian Elischer 2922b14f991SJulian Elischer /* 2932b14f991SJulian Elischer *************************************************************************** 2942b14f991SJulian Elischer **** 2952b14f991SJulian Elischer **** The two following SYSINT's are proc0 specific glue code. I am not 2962b14f991SJulian Elischer **** convinced that they can not be safely combined, but their order of 2972b14f991SJulian Elischer **** operation has been maintained as the same as the original init_main.c 2982b14f991SJulian Elischer **** for right now. 2992b14f991SJulian Elischer **** 3002b14f991SJulian Elischer **** These probably belong in init_proc.c or kern_proc.c, since they 3012b14f991SJulian Elischer **** deal with proc0 (the fork template process). 3022b14f991SJulian Elischer **** 3032b14f991SJulian Elischer *************************************************************************** 3042b14f991SJulian Elischer */ 3052b14f991SJulian Elischer /* ARGSUSED*/ 306154c04e5SPoul-Henning Kamp static void proc0_init __P((void *dummy)); 307154c04e5SPoul-Henning Kamp static void 308d841aaa7SBruce Evans proc0_init(dummy) 309d841aaa7SBruce Evans void *dummy; 3102b14f991SJulian Elischer { 311df8bae1dSRodney W. Grimes register struct proc *p; 312df8bae1dSRodney W. Grimes register struct filedesc0 *fdp; 31392579404SAlexander Langer register unsigned i; 314df8bae1dSRodney W. Grimes 315df8bae1dSRodney W. Grimes /* 316df8bae1dSRodney W. Grimes * Initialize the current process pointer (curproc) before 317df8bae1dSRodney W. Grimes * any possible traps/probes to simplify trap processing. 318df8bae1dSRodney W. Grimes */ 319df8bae1dSRodney W. Grimes p = &proc0; 3202b14f991SJulian Elischer curproc = p; /* XXX redundant*/ 321df8bae1dSRodney W. Grimes 322df8bae1dSRodney W. Grimes /* 323a3bfb996SJeffrey Hsu * Initialize process and pgrp structures. 324a3bfb996SJeffrey Hsu */ 325a3bfb996SJeffrey Hsu procinit(); 326a3bfb996SJeffrey Hsu 327a3bfb996SJeffrey Hsu /* 328b1508c72SDavid Greenman * Initialize sleep queue hash table 329b1508c72SDavid Greenman */ 330b1508c72SDavid Greenman sleepinit(); 331b1508c72SDavid Greenman 332b1508c72SDavid Greenman /* 333df8bae1dSRodney W. Grimes * Create process 0 (the swapper). 334df8bae1dSRodney W. Grimes */ 335a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&allproc, p, p_list); 336df8bae1dSRodney W. Grimes p->p_pgrp = &pgrp0; 337a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); 338a3bfb996SJeffrey Hsu LIST_INIT(&pgrp0.pg_members); 339a3bfb996SJeffrey Hsu LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); 340a3bfb996SJeffrey Hsu 341df8bae1dSRodney W. Grimes pgrp0.pg_session = &session0; 342df8bae1dSRodney W. Grimes session0.s_count = 1; 343df8bae1dSRodney W. Grimes session0.s_leader = p; 344df8bae1dSRodney W. Grimes 345f3f0ca60SSøren Schmidt p->p_sysent = &aout_sysvec; 346f3f0ca60SSøren Schmidt 347df8bae1dSRodney W. Grimes p->p_flag = P_INMEM | P_SYSTEM; 348df8bae1dSRodney W. Grimes p->p_stat = SRUN; 349df8bae1dSRodney W. Grimes p->p_nice = NZERO; 3507216391eSDavid Greenman p->p_rtprio.type = RTP_PRIO_NORMAL; 3517216391eSDavid Greenman p->p_rtprio.prio = 0; 352f992f480SDavid Greenman 353df8bae1dSRodney W. Grimes bcopy("swapper", p->p_comm, sizeof ("swapper")); 354df8bae1dSRodney W. Grimes 355df8bae1dSRodney W. Grimes /* Create credentials. */ 356df8bae1dSRodney W. Grimes cred0.p_refcnt = 1; 357df8bae1dSRodney W. Grimes p->p_cred = &cred0; 358df8bae1dSRodney W. Grimes p->p_ucred = crget(); 359df8bae1dSRodney W. Grimes p->p_ucred->cr_ngroups = 1; /* group 0 */ 360df8bae1dSRodney W. Grimes 361df8bae1dSRodney W. Grimes /* Create the file descriptor table. */ 362df8bae1dSRodney W. Grimes fdp = &filedesc0; 363df8bae1dSRodney W. Grimes p->p_fd = &fdp->fd_fd; 364df8bae1dSRodney W. Grimes fdp->fd_fd.fd_refcnt = 1; 365df8bae1dSRodney W. Grimes fdp->fd_fd.fd_cmask = cmask; 366df8bae1dSRodney W. Grimes fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 367df8bae1dSRodney W. Grimes fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 368df8bae1dSRodney W. Grimes fdp->fd_fd.fd_nfiles = NDFILE; 369df8bae1dSRodney W. Grimes 370df8bae1dSRodney W. Grimes /* Create the limits structures. */ 371df8bae1dSRodney W. Grimes p->p_limit = &limit0; 372df8bae1dSRodney W. Grimes for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 373df8bae1dSRodney W. Grimes limit0.pl_rlimit[i].rlim_cur = 374df8bae1dSRodney W. Grimes limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 375df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; 376df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 377df8bae1dSRodney W. Grimes i = ptoa(cnt.v_free_count); 378df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i; 379df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; 380df8bae1dSRodney W. Grimes limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; 381df8bae1dSRodney W. Grimes limit0.p_refcnt = 1; 382df8bae1dSRodney W. Grimes 383df8bae1dSRodney W. Grimes /* Allocate a prototype map so we have something to fork. */ 384df8bae1dSRodney W. Grimes p->p_vmspace = &vmspace0; 385df8bae1dSRodney W. Grimes vmspace0.vm_refcnt = 1; 386df8bae1dSRodney W. Grimes pmap_pinit(&vmspace0.vm_pmap); 38726f9a767SRodney W. Grimes vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS), 38847dcd2e5SJohn Dyson trunc_page(VM_MAXUSER_ADDRESS), TRUE); 389df8bae1dSRodney W. Grimes vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 390df8bae1dSRodney W. Grimes p->p_addr = proc0paddr; /* XXX */ 391df8bae1dSRodney W. Grimes 3922b14f991SJulian Elischer #define INCOMPAT_LITES2 3932b14f991SJulian Elischer #ifdef INCOMPAT_LITES2 394df8bae1dSRodney W. Grimes /* 3952384fde5SDavid Greenman * proc0 needs to have a coherent frame base, too. 3962384fde5SDavid Greenman * This probably makes the identical call for the init proc 3972384fde5SDavid Greenman * that happens later unnecessary since it should inherit 3982384fde5SDavid Greenman * it during the fork. 3992384fde5SDavid Greenman */ 4002b14f991SJulian Elischer cpu_set_init_frame(p, init_framep); /* XXX! */ 4012b14f991SJulian Elischer #endif /* INCOMPAT_LITES2*/ 4022384fde5SDavid Greenman 4032384fde5SDavid Greenman /* 404df8bae1dSRodney W. Grimes * We continue to place resource usage info and signal 405df8bae1dSRodney W. Grimes * actions in the user struct so they're pageable. 406df8bae1dSRodney W. Grimes */ 407df8bae1dSRodney W. Grimes p->p_stats = &p->p_addr->u_stats; 408df8bae1dSRodney W. Grimes p->p_sigacts = &p->p_addr->u_sigacts; 409df8bae1dSRodney W. Grimes 410df8bae1dSRodney W. Grimes /* 411a3bfb996SJeffrey Hsu * Charge root for one process. 412df8bae1dSRodney W. Grimes */ 413df8bae1dSRodney W. Grimes (void)chgproccnt(0, 1); 41426f9a767SRodney W. Grimes } 4152b14f991SJulian Elischer SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) 4162b14f991SJulian Elischer 4172b14f991SJulian Elischer /* ARGSUSED*/ 418154c04e5SPoul-Henning Kamp static void proc0_post __P((void *dummy)); 419154c04e5SPoul-Henning Kamp static void 420d841aaa7SBruce Evans proc0_post(dummy) 421d841aaa7SBruce Evans void *dummy; 4222b14f991SJulian Elischer { 423a6fc8288SPeter Wemm struct timeval tv; 424a6fc8288SPeter Wemm 4252b14f991SJulian Elischer /* 4262b14f991SJulian Elischer * Now can look at time, having had a chance to verify the time 4272b14f991SJulian Elischer * from the file system. Reset p->p_rtime as it may have been 4282b14f991SJulian Elischer * munched in mi_switch() after the time got set. 4292b14f991SJulian Elischer */ 4302b14f991SJulian Elischer proc0.p_stats->p_start = runtime = mono_time = boottime = time; 4312b14f991SJulian Elischer proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0; 4322b14f991SJulian Elischer 433a6fc8288SPeter Wemm /* 434a6fc8288SPeter Wemm * Give the ``random'' number generator a thump. 435a6fc8288SPeter Wemm */ 436a6fc8288SPeter Wemm microtime(&tv); 437a6fc8288SPeter Wemm srandom(tv.tv_sec ^ tv.tv_usec); 438a6fc8288SPeter Wemm 4392b14f991SJulian Elischer /* Initialize signal state for process 0. */ 4402b14f991SJulian Elischer siginit(&proc0); 4412b14f991SJulian Elischer } 4422b14f991SJulian Elischer SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) 4432b14f991SJulian Elischer 4442b14f991SJulian Elischer 4452b14f991SJulian Elischer 446df8bae1dSRodney W. Grimes 447df8bae1dSRodney W. Grimes /* 4482b14f991SJulian Elischer *************************************************************************** 4492b14f991SJulian Elischer **** 4502b14f991SJulian Elischer **** The following SYSINIT's and glue code should be moved to the 4512b14f991SJulian Elischer **** respective files on a per subsystem basis. 4522b14f991SJulian Elischer **** 4532b14f991SJulian Elischer *************************************************************************** 454df8bae1dSRodney W. Grimes */ 4552b14f991SJulian Elischer /* ARGSUSED*/ 456154c04e5SPoul-Henning Kamp static void sched_setup __P((void *dummy)); 457154c04e5SPoul-Henning Kamp static void 458d841aaa7SBruce Evans sched_setup(dummy) 459d841aaa7SBruce Evans void *dummy; 4602b14f991SJulian Elischer { 461df8bae1dSRodney W. Grimes /* Kick off timeout driven events by calling first time. */ 462df8bae1dSRodney W. Grimes roundrobin(NULL); 463df8bae1dSRodney W. Grimes schedcpu(NULL); 4642b14f991SJulian Elischer } 4652b14f991SJulian Elischer SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL) 466df8bae1dSRodney W. Grimes 4672b14f991SJulian Elischer /* ARGSUSED*/ 468154c04e5SPoul-Henning Kamp static void xxx_vfs_mountroot __P((void *dummy)); 469154c04e5SPoul-Henning Kamp static void 470d841aaa7SBruce Evans xxx_vfs_mountroot(dummy) 471d841aaa7SBruce Evans void *dummy; 4722b14f991SJulian Elischer { 473df8bae1dSRodney W. Grimes /* Mount the root file system. */ 4744590fd3aSDavid Greenman if ((*mountroot)(mountrootvfsops)) 475df8bae1dSRodney W. Grimes panic("cannot mount root"); 4762b14f991SJulian Elischer } 4772b14f991SJulian Elischer SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL) 4782b14f991SJulian Elischer 4792b14f991SJulian Elischer /* ARGSUSED*/ 480154c04e5SPoul-Henning Kamp static void xxx_vfs_root_fdtab __P((void *dummy)); 481154c04e5SPoul-Henning Kamp static void 482d841aaa7SBruce Evans xxx_vfs_root_fdtab(dummy) 483d841aaa7SBruce Evans void *dummy; 4842b14f991SJulian Elischer { 4852b14f991SJulian Elischer register struct filedesc0 *fdp = &filedesc0; 486df8bae1dSRodney W. Grimes 487df8bae1dSRodney W. Grimes /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ 488628641f8SDavid Greenman if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) 489df8bae1dSRodney W. Grimes panic("cannot find root vnode"); 490df8bae1dSRodney W. Grimes fdp->fd_fd.fd_cdir = rootvnode; 491df8bae1dSRodney W. Grimes VREF(fdp->fd_fd.fd_cdir); 492df8bae1dSRodney W. Grimes VOP_UNLOCK(rootvnode); 493df8bae1dSRodney W. Grimes fdp->fd_fd.fd_rdir = NULL; 4942b14f991SJulian Elischer } 4952b14f991SJulian Elischer SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL) 4962b14f991SJulian Elischer 497df8bae1dSRodney W. Grimes 498df8bae1dSRodney W. Grimes /* 4992b14f991SJulian Elischer *************************************************************************** 5002b14f991SJulian Elischer **** 5012b14f991SJulian Elischer **** The following code probably belongs in another file, like 5022b14f991SJulian Elischer **** kern/init_init.c. It is here for two reasons only: 5032b14f991SJulian Elischer **** 5042b14f991SJulian Elischer **** 1) This code returns to startup the system; this is 5052b14f991SJulian Elischer **** abnormal for a kernel thread. 5062b14f991SJulian Elischer **** 2) This code promiscuously uses init_frame 5072b14f991SJulian Elischer **** 5082b14f991SJulian Elischer *************************************************************************** 509df8bae1dSRodney W. Grimes */ 510df8bae1dSRodney W. Grimes 511d841aaa7SBruce Evans static void kthread_init __P((void *dummy)); 5122b14f991SJulian Elischer SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL) 5132b14f991SJulian Elischer 5142b14f991SJulian Elischer 5152b14f991SJulian Elischer static void start_init __P((struct proc *p, void *framep)); 5162b14f991SJulian Elischer 5172b14f991SJulian Elischer /* ARGSUSED*/ 5182b14f991SJulian Elischer static void 519d841aaa7SBruce Evans kthread_init(dummy) 520d841aaa7SBruce Evans void *dummy; 5212b14f991SJulian Elischer { 522df8bae1dSRodney W. Grimes 523df8bae1dSRodney W. Grimes /* Create process 1 (init(8)). */ 5242b14f991SJulian Elischer start_init(curproc, init_framep); 5252b14f991SJulian Elischer 5262b14f991SJulian Elischer /* 5272b14f991SJulian Elischer * This is the only kernel thread allowed to return yo the 5282b14f991SJulian Elischer * caller!!! 5292b14f991SJulian Elischer */ 530df8bae1dSRodney W. Grimes return; 531df8bae1dSRodney W. Grimes } 532df8bae1dSRodney W. Grimes 533df8bae1dSRodney W. Grimes 534df8bae1dSRodney W. Grimes /* 535df8bae1dSRodney W. Grimes * List of paths to try when searching for "init". 536df8bae1dSRodney W. Grimes */ 537df8bae1dSRodney W. Grimes static char *initpaths[] = { 538df8bae1dSRodney W. Grimes "/sbin/init", 539df8bae1dSRodney W. Grimes "/sbin/oinit", 540df8bae1dSRodney W. Grimes "/sbin/init.bak", 5412257b745SPoul-Henning Kamp "/stand/sysinstall", 542df8bae1dSRodney W. Grimes NULL, 543df8bae1dSRodney W. Grimes }; 544df8bae1dSRodney W. Grimes 545df8bae1dSRodney W. Grimes /* 546df8bae1dSRodney W. Grimes * Start the initial user process; try exec'ing each pathname in "initpaths". 547df8bae1dSRodney W. Grimes * The program is invoked with one argument containing the boot flags. 548df8bae1dSRodney W. Grimes */ 549df8bae1dSRodney W. Grimes static void 550df8bae1dSRodney W. Grimes start_init(p, framep) 551df8bae1dSRodney W. Grimes struct proc *p; 552df8bae1dSRodney W. Grimes void *framep; 553df8bae1dSRodney W. Grimes { 554df8bae1dSRodney W. Grimes vm_offset_t addr; 555df8bae1dSRodney W. Grimes struct execve_args args; 556df8bae1dSRodney W. Grimes int options, i, retval[2], error; 557df8bae1dSRodney W. Grimes char **pathp, *path, *ucp, **uap, *arg0, *arg1; 558df8bae1dSRodney W. Grimes 559df8bae1dSRodney W. Grimes initproc = p; 560df8bae1dSRodney W. Grimes 561df8bae1dSRodney W. Grimes /* 562df8bae1dSRodney W. Grimes * We need to set the system call frame as if we were entered through 563df8bae1dSRodney W. Grimes * a syscall() so that when we call execve() below, it will be able 564df8bae1dSRodney W. Grimes * to set the entry point (see setregs) when it tries to exec. The 565df8bae1dSRodney W. Grimes * startup code in "locore.s" has allocated space for the frame and 566df8bae1dSRodney W. Grimes * passed a pointer to that space as main's argument. 567df8bae1dSRodney W. Grimes */ 568df8bae1dSRodney W. Grimes cpu_set_init_frame(p, framep); 569df8bae1dSRodney W. Grimes 570df8bae1dSRodney W. Grimes /* 571df8bae1dSRodney W. Grimes * Need just enough stack to hold the faked-up "execve()" arguments. 572df8bae1dSRodney W. Grimes */ 57326f9a767SRodney W. Grimes addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE); 574bd7e5f99SJohn Dyson if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 575df8bae1dSRodney W. Grimes panic("init: couldn't allocate argument space"); 576df8bae1dSRodney W. Grimes p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 57726f9a767SRodney W. Grimes p->p_vmspace->vm_ssize = 1; 578df8bae1dSRodney W. Grimes 579df8bae1dSRodney W. Grimes for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { 580df8bae1dSRodney W. Grimes /* 581df8bae1dSRodney W. Grimes * Move out the boot flag argument. 582df8bae1dSRodney W. Grimes */ 583df8bae1dSRodney W. Grimes options = 0; 584df8bae1dSRodney W. Grimes ucp = (char *)USRSTACK; 585df8bae1dSRodney W. Grimes (void)subyte(--ucp, 0); /* trailing zero */ 586df8bae1dSRodney W. Grimes if (boothowto & RB_SINGLE) { 587df8bae1dSRodney W. Grimes (void)subyte(--ucp, 's'); 588df8bae1dSRodney W. Grimes options = 1; 589df8bae1dSRodney W. Grimes } 590df8bae1dSRodney W. Grimes #ifdef notyet 591df8bae1dSRodney W. Grimes if (boothowto & RB_FASTBOOT) { 592df8bae1dSRodney W. Grimes (void)subyte(--ucp, 'f'); 593df8bae1dSRodney W. Grimes options = 1; 594df8bae1dSRodney W. Grimes } 595df8bae1dSRodney W. Grimes #endif 59617755ac8SPoul-Henning Kamp 59717755ac8SPoul-Henning Kamp #ifdef BOOTCDROM 59817755ac8SPoul-Henning Kamp (void)subyte(--ucp, 'C'); 59917755ac8SPoul-Henning Kamp options = 1; 60017755ac8SPoul-Henning Kamp #endif 60119060a3aSPoul-Henning Kamp 60219060a3aSPoul-Henning Kamp #if defined(DEVFS) && defined(DEVFS_ROOT) 60319060a3aSPoul-Henning Kamp (void)subyte(--ucp, 'd'); 60419060a3aSPoul-Henning Kamp options = 1; 60519060a3aSPoul-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