123364Smckusick /* 247543Skarels * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. 347817Skarels * All rights reserved. 423364Smckusick * 547817Skarels * %sccs.include.redist.c% 647817Skarels * 7*49533Skarels * @(#)init_main.c 7.40 (Berkeley) 05/09/91 823364Smckusick */ 926Sbill 1017087Sbloom #include "param.h" 1145914Smckusick #include "filedesc.h" 1217087Sbloom #include "kernel.h" 1317087Sbloom #include "mount.h" 1417087Sbloom #include "map.h" 1517087Sbloom #include "proc.h" 1647654Skarels #include "resourcevar.h" 1747654Skarels #include "signalvar.h" 1847654Skarels #include "systm.h" 1937610Smckusick #include "vnode.h" 2017087Sbloom #include "seg.h" 2117087Sbloom #include "conf.h" 2217087Sbloom #include "buf.h" 2317087Sbloom #include "clist.h" 2437611Smckusick #include "malloc.h" 2517087Sbloom #include "protosw.h" 2630570Skarels #include "reboot.h" 2747654Skarels #include "user.h" 2847654Skarels 2947543Skarels #include "ufs/quota.h" 3026Sbill 3137522Smckusick #include "machine/cpu.h" 3237522Smckusick 3347543Skarels #include "vm/vm.h" 3445724Smckusick 3549382Skarels char copyright[] = 3649382Skarels "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n"; 3749382Skarels 3847543Skarels /* 3947543Skarels * Components of process 0; 4047543Skarels * never freed. 4147543Skarels */ 4247543Skarels struct session session0; 4347543Skarels struct pgrp pgrp0; 4447543Skarels struct proc proc0; 4547543Skarels struct pcred cred0; 4647654Skarels struct filedesc0 filedesc0; 4747543Skarels struct plimit limit0; 4847543Skarels struct vmspace vmspace0; 4947654Skarels struct proc *curproc = &proc0; 5047543Skarels struct proc *initproc, *pageproc; 5147543Skarels 5216807Skarels int cmask = CMASK; 5348981Skarels extern struct user *proc0paddr; 5437610Smckusick extern int (*mountroot)(); 5545880Swilliam 5649382Skarels struct vnode *rootvp, *swapdev_vp; 5749382Skarels int boothowto; 5849382Skarels 5926Sbill /* 6047543Skarels * System startup; initialize the world, create process 0, 6147543Skarels * mount root filesystem, and fork to create init and pagedaemon. 6247543Skarels * Most of the hard work is done in the lower-level initialization 6347543Skarels * routines including startup(), which does memory initialization 6447543Skarels * and autoconfiguration. 6526Sbill */ 66*49533Skarels main() 6726Sbill { 68361Sbill register int i; 692451Swnj register struct proc *p; 7047654Skarels register struct filedesc0 *fdp; 7147543Skarels int s, rval[2]; 7226Sbill 7345880Swilliam /* 7447543Skarels * Initialize curproc before any possible traps/probes 7547543Skarels * to simplify trap processing. 7645880Swilliam */ 7747543Skarels p = &proc0; 7847543Skarels curproc = p; 7945724Smckusick /* 8047543Skarels * Attempt to find console and initialize 8147543Skarels * in case of early panic or other messages. 8245724Smckusick */ 8347543Skarels consinit(); 8449382Skarels printf(copyright); 8547543Skarels 8645724Smckusick vm_mem_init(); 8745724Smckusick kmeminit(); 88*49533Skarels cpu_startup(); 8926Sbill 9026Sbill /* 9126Sbill * set up system process 0 (swapper) 9226Sbill */ 9347543Skarels p = &proc0; 9447543Skarels curproc = p; 9547543Skarels 9647543Skarels allproc = p; 9747543Skarels p->p_prev = &allproc; 9847543Skarels p->p_pgrp = &pgrp0; 9947543Skarels pgrphash[0] = &pgrp0; 10047543Skarels pgrp0.pg_mem = p; 10147543Skarels pgrp0.pg_session = &session0; 10247543Skarels session0.s_count = 1; 10347543Skarels session0.s_leader = p; 10447543Skarels 10547543Skarels p->p_flag = SLOAD|SSYS; 1062451Swnj p->p_stat = SRUN; 1072451Swnj p->p_nice = NZERO; 10847543Skarels bcopy("swapper", p->p_comm, sizeof ("swapper")); 10947543Skarels 11045724Smckusick /* 11147543Skarels * Setup credentials 11245724Smckusick */ 11347543Skarels p->p_cred = &cred0; 11447543Skarels p->p_ucred = crget(); 11547543Skarels p->p_ucred->cr_ngroups = 1; /* group 0 */ 11629946Skarels 11745914Smckusick /* 11845914Smckusick * Create the file descriptor table for process 0. 11945914Smckusick */ 12047543Skarels fdp = &filedesc0; 12147654Skarels p->p_fd = &fdp->fd_fd; 12247654Skarels fdp->fd_fd.fd_refcnt = 1; 12347654Skarels fdp->fd_fd.fd_cmask = cmask; 12447654Skarels fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 12547654Skarels fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 12647654Skarels fdp->fd_fd.fd_nfiles = NDFILE; 12747543Skarels 12818278Smckusick /* 12947543Skarels * Set initial limits 13047543Skarels */ 13147543Skarels p->p_limit = &limit0; 13247543Skarels for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 13347543Skarels limit0.pl_rlimit[i].rlim_cur = 13447543Skarels limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 13547543Skarels limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE; 13647543Skarels limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 13747543Skarels limit0.p_refcnt = 1; 13847543Skarels 13947543Skarels /* 14047543Skarels * Allocate a prototype map so we have something to fork 14147543Skarels */ 14247543Skarels p->p_vmspace = &vmspace0; 14347543Skarels vmspace0.vm_refcnt = 1; 14447543Skarels pmap_pinit(&vmspace0.vm_pmap); 14547543Skarels vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS), 14647543Skarels trunc_page(VM_MAX_ADDRESS), TRUE); 14747543Skarels vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 14847543Skarels p->p_addr = proc0paddr; /* XXX */ 14947543Skarels 15047543Skarels /* 15147543Skarels * We continue to place resource usage info 15247543Skarels * and signal actions in the user struct so they're pageable. 15347543Skarels */ 15448981Skarels p->p_stats = &p->p_addr->u_stats; 15548981Skarels p->p_sigacts = &p->p_addr->u_sigacts; 15647543Skarels 15747543Skarels rqinit(); 15847543Skarels 15947543Skarels /* 16023534Skarels * configure virtual memory system, 16123534Skarels * set vm rlimits 16218278Smckusick */ 16347543Skarels vm_init_limits(p); 16423534Skarels 16537610Smckusick /* 16639431Smckusick * Initialize the file systems. 16739431Smckusick * 16849382Skarels * Get vnodes for swapdev and rootdev. 16937610Smckusick */ 17039431Smckusick vfsinit(); 17149382Skarels if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) 17237610Smckusick panic("can't setup bdevvp's"); 17337610Smckusick 17430256Ssam startrtclock(); 17529946Skarels #if defined(vax) 17612823Ssam #include "kg.h" 17712823Ssam #if NKG > 0 17811356Smckusick startkgclock(); 17911356Smckusick #endif 18029946Skarels #endif 18126Sbill 18226Sbill /* 1834821Swnj * Initialize tables, protocols, and set up well-known inodes. 18426Sbill */ 1854821Swnj mbinit(); 18621103Skarels cinit(); 18741565Smckusick #ifdef SYSVSHM 18841565Smckusick shminit(); 18941565Smckusick #endif 19026137Skarels #include "sl.h" 19126137Skarels #if NSL > 0 19226137Skarels slattach(); /* XXX */ 19326137Skarels #endif 19441565Smckusick #include "loop.h" 1955855Swnj #if NLOOP > 0 1965855Swnj loattach(); /* XXX */ 1975855Swnj #endif 1989156Ssam /* 1999156Ssam * Block reception of incoming packets 2009156Ssam * until protocols have been initialized. 2019156Ssam */ 2029156Ssam s = splimp(); 2035227Swnj ifinit(); 2048969Sroot domaininit(); 2059156Ssam splx(s); 20647543Skarels 2077419Sroot #ifdef GPROF 2087419Sroot kmstartup(); 2097419Sroot #endif 2107189Sroot 21147543Skarels /* kick off timeout driven events by calling first time */ 2128096Sroot roundrobin(); 2138096Sroot schedcpu(); 21445880Swilliam enablertclock(); /* enable realtime clock interrupts */ 2158096Sroot 21647543Skarels /* 21747543Skarels * Set up the root file system and vnode. 21847543Skarels */ 21937610Smckusick if ((*mountroot)()) 22037610Smckusick panic("cannot mount root"); 22137610Smckusick /* 22237610Smckusick * Get vnode for '/'. 22347654Skarels * Setup rootdir and fdp->fd_fd.fd_cdir to point to it. 22437610Smckusick */ 22537610Smckusick if (VFS_ROOT(rootfs, &rootdir)) 22637610Smckusick panic("cannot find root vnode"); 22747654Skarels fdp->fd_fd.fd_cdir = rootdir; 22847654Skarels VREF(fdp->fd_fd.fd_cdir); 22937726Smckusick VOP_UNLOCK(rootdir); 23047654Skarels fdp->fd_fd.fd_rdir = NULL; 23147543Skarels swapinit(); 23226Sbill 23326Sbill /* 23447543Skarels * Now can look at time, having had a chance 23547543Skarels * to verify the time from the file system. 23647543Skarels */ 23747543Skarels boottime = p->p_stats->p_start = time; 23847543Skarels 23947543Skarels /* 24016807Skarels * make init process 24116807Skarels */ 24247543Skarels siginit(p); 24347543Skarels if (fork(p, (void *) NULL, rval)) 24447543Skarels panic("fork init"); 24547543Skarels if (rval[1]) { 24647689Skarels static char initflags[] = "-sf"; 24747689Skarels char *ip = initflags + 1; 24845724Smckusick vm_offset_t addr = 0; 24949382Skarels extern int icode[]; /* user init code */ 25049382Skarels extern int szicode; /* size of icode */ 25145724Smckusick 25247543Skarels /* 25347543Skarels * Now in process 1. Set init flags into icode, 25447543Skarels * get a minimal address space, copy out "icode", 25547543Skarels * and return to it to do an exec of init. 25647543Skarels */ 25747543Skarels p = curproc; 25847543Skarels initproc = p; 25947543Skarels if (boothowto&RB_SINGLE) 26047543Skarels *ip++ = 's'; 26147543Skarels #ifdef notyet 26247543Skarels if (boothowto&RB_FASTBOOT) 26347543Skarels *ip++ = 'f'; 26447689Skarels #endif 26547543Skarels *ip++ = '\0'; 26647543Skarels 26747543Skarels if (vm_allocate(&p->p_vmspace->vm_map, &addr, 26847689Skarels round_page(szicode + sizeof(initflags)), FALSE) != 0 || 26947689Skarels addr != 0) 27045724Smckusick panic("init: couldn't allocate at zero"); 27145724Smckusick 27245724Smckusick /* need just enough stack to exec from */ 27348981Skarels addr = trunc_page(USRSTACK - PAGE_SIZE); 27447543Skarels if (vm_allocate(&p->p_vmspace->vm_map, &addr, 27547543Skarels PAGE_SIZE, FALSE) != KERN_SUCCESS) 27647543Skarels panic("vm_allocate init stack"); 27747543Skarels p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 27816807Skarels (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 27947689Skarels (void) copyout(initflags, (caddr_t)szicode, sizeof(initflags)); 28047543Skarels return; /* returns to icode */ 28116807Skarels } 28247543Skarels 28316807Skarels /* 28445724Smckusick * Start up pageout daemon (process 2). 28526Sbill */ 28647543Skarels if (fork(p, (void *) NULL, rval)) 28747543Skarels panic("fork pager"); 28847543Skarels if (rval[1]) { 28947543Skarels /* 29047543Skarels * Now in process 2. 29147543Skarels */ 29247543Skarels p = curproc; 29347543Skarels pageproc = p; 29447543Skarels p->p_flag |= SLOAD|SSYS; /* XXX */ 29547543Skarels bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); 29645724Smckusick vm_pageout(); 2979025Sroot /*NOTREACHED*/ 29826Sbill } 29926Sbill 30026Sbill /* 30126Sbill * enter scheduling loop 30226Sbill */ 30326Sbill sched(); 30426Sbill } 305