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*55399Smckusick * @(#)init_main.c 7.52 (Berkeley) 07/19/92 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 "conf.h" 2117087Sbloom #include "buf.h" 2217087Sbloom #include "clist.h" 2337611Smckusick #include "malloc.h" 2417087Sbloom #include "protosw.h" 2530570Skarels #include "reboot.h" 2647654Skarels #include "user.h" 2747654Skarels 2851453Sbostic #include "ufs/ufs/quota.h" 2926Sbill 3037522Smckusick #include "machine/cpu.h" 3137522Smckusick 3247543Skarels #include "vm/vm.h" 3345724Smckusick 34*55399Smckusick #ifdef HPFPLIB 3549382Skarels char copyright[] = 36*55399Smckusick "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n"; 37*55399Smckusick #else 38*55399Smckusick char copyright[] = 3949382Skarels "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n"; 40*55399Smckusick #endif 4149382Skarels 4247543Skarels /* 4347543Skarels * Components of process 0; 4447543Skarels * never freed. 4547543Skarels */ 4647543Skarels struct session session0; 4747543Skarels struct pgrp pgrp0; 4847543Skarels struct proc proc0; 4947543Skarels struct pcred cred0; 5047654Skarels struct filedesc0 filedesc0; 5147543Skarels struct plimit limit0; 5247543Skarels struct vmspace vmspace0; 5347654Skarels struct proc *curproc = &proc0; 5447543Skarels struct proc *initproc, *pageproc; 5547543Skarels 5616807Skarels int cmask = CMASK; 5748981Skarels extern struct user *proc0paddr; 5837610Smckusick extern int (*mountroot)(); 5945880Swilliam 6049382Skarels struct vnode *rootvp, *swapdev_vp; 6149382Skarels int boothowto; 6253009Ssklower struct timeval boottime; 6354781Storek struct timeval runtime; 6449382Skarels 6526Sbill /* 6647543Skarels * System startup; initialize the world, create process 0, 6747543Skarels * mount root filesystem, and fork to create init and pagedaemon. 6847543Skarels * Most of the hard work is done in the lower-level initialization 6947543Skarels * routines including startup(), which does memory initialization 7047543Skarels * and autoconfiguration. 7126Sbill */ 7249533Skarels main() 7326Sbill { 74361Sbill register int i; 752451Swnj register struct proc *p; 7647654Skarels register struct filedesc0 *fdp; 7747543Skarels int s, rval[2]; 7854781Storek extern void roundrobin __P((void *)); 7954781Storek extern void schedcpu __P((void *)); 8026Sbill 8145880Swilliam /* 8247543Skarels * Initialize curproc before any possible traps/probes 8347543Skarels * to simplify trap processing. 8445880Swilliam */ 8547543Skarels p = &proc0; 8647543Skarels curproc = p; 8745724Smckusick /* 8847543Skarels * Attempt to find console and initialize 8947543Skarels * in case of early panic or other messages. 9045724Smckusick */ 9147543Skarels consinit(); 9249382Skarels printf(copyright); 9347543Skarels 9445724Smckusick vm_mem_init(); 9545724Smckusick kmeminit(); 9649533Skarels cpu_startup(); 9726Sbill 9826Sbill /* 9926Sbill * set up system process 0 (swapper) 10026Sbill */ 10147543Skarels p = &proc0; 10247543Skarels curproc = p; 10347543Skarels 10454781Storek allproc = (volatile struct proc *)p; 10554781Storek p->p_prev = (struct proc **)&allproc; 10647543Skarels p->p_pgrp = &pgrp0; 10747543Skarels pgrphash[0] = &pgrp0; 10847543Skarels pgrp0.pg_mem = p; 10947543Skarels pgrp0.pg_session = &session0; 11047543Skarels session0.s_count = 1; 11147543Skarels session0.s_leader = p; 11247543Skarels 11347543Skarels p->p_flag = SLOAD|SSYS; 1142451Swnj p->p_stat = SRUN; 1152451Swnj p->p_nice = NZERO; 11647543Skarels bcopy("swapper", p->p_comm, sizeof ("swapper")); 11747543Skarels 11845724Smckusick /* 11947543Skarels * Setup credentials 12045724Smckusick */ 12149745Smckusick cred0.p_refcnt = 1; 12247543Skarels p->p_cred = &cred0; 12347543Skarels p->p_ucred = crget(); 12447543Skarels p->p_ucred->cr_ngroups = 1; /* group 0 */ 12529946Skarels 12645914Smckusick /* 12745914Smckusick * Create the file descriptor table for process 0. 12845914Smckusick */ 12947543Skarels fdp = &filedesc0; 13047654Skarels p->p_fd = &fdp->fd_fd; 13147654Skarels fdp->fd_fd.fd_refcnt = 1; 13247654Skarels fdp->fd_fd.fd_cmask = cmask; 13347654Skarels fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 13447654Skarels fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 13547654Skarels fdp->fd_fd.fd_nfiles = NDFILE; 13647543Skarels 13718278Smckusick /* 13847543Skarels * Set initial limits 13947543Skarels */ 14047543Skarels p->p_limit = &limit0; 14147543Skarels for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 14247543Skarels limit0.pl_rlimit[i].rlim_cur = 14347543Skarels limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 14447543Skarels limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE; 14547543Skarels limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 14647543Skarels limit0.p_refcnt = 1; 14747543Skarels 14847543Skarels /* 14947543Skarels * Allocate a prototype map so we have something to fork 15047543Skarels */ 15147543Skarels p->p_vmspace = &vmspace0; 15247543Skarels vmspace0.vm_refcnt = 1; 15347543Skarels pmap_pinit(&vmspace0.vm_pmap); 15447543Skarels vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS), 15547543Skarels trunc_page(VM_MAX_ADDRESS), TRUE); 15647543Skarels vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 15747543Skarels p->p_addr = proc0paddr; /* XXX */ 15847543Skarels 15947543Skarels /* 16047543Skarels * We continue to place resource usage info 16147543Skarels * and signal actions in the user struct so they're pageable. 16247543Skarels */ 16348981Skarels p->p_stats = &p->p_addr->u_stats; 16448981Skarels p->p_sigacts = &p->p_addr->u_sigacts; 16547543Skarels 16647543Skarels rqinit(); 16747543Skarels 16847543Skarels /* 16923534Skarels * configure virtual memory system, 17023534Skarels * set vm rlimits 17118278Smckusick */ 17247543Skarels vm_init_limits(p); 17323534Skarels 17437610Smckusick /* 17539431Smckusick * Initialize the file systems. 17639431Smckusick * 17749382Skarels * Get vnodes for swapdev and rootdev. 17837610Smckusick */ 17939431Smckusick vfsinit(); 18049382Skarels if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) 18137610Smckusick panic("can't setup bdevvp's"); 18237610Smckusick 18354781Storek /* 18454781Storek * Start real time and statistics clocks. 18554781Storek */ 18654781Storek initclocks(); 18726Sbill 18826Sbill /* 1894821Swnj * Initialize tables, protocols, and set up well-known inodes. 19026Sbill */ 1914821Swnj mbinit(); 19221103Skarels cinit(); 19341565Smckusick #ifdef SYSVSHM 19441565Smckusick shminit(); 19541565Smckusick #endif 19626137Skarels #include "sl.h" 19726137Skarels #if NSL > 0 19826137Skarels slattach(); /* XXX */ 19926137Skarels #endif 20041565Smckusick #include "loop.h" 2015855Swnj #if NLOOP > 0 2025855Swnj loattach(); /* XXX */ 2035855Swnj #endif 2049156Ssam /* 2059156Ssam * Block reception of incoming packets 2069156Ssam * until protocols have been initialized. 2079156Ssam */ 2089156Ssam s = splimp(); 2095227Swnj ifinit(); 2108969Sroot domaininit(); 2119156Ssam splx(s); 21247543Skarels 2137419Sroot #ifdef GPROF 2147419Sroot kmstartup(); 2157419Sroot #endif 2167189Sroot 21747543Skarels /* kick off timeout driven events by calling first time */ 21854781Storek roundrobin(NULL); 21954781Storek schedcpu(NULL); 2208096Sroot 22147543Skarels /* 22247543Skarels * Set up the root file system and vnode. 22347543Skarels */ 22437610Smckusick if ((*mountroot)()) 22537610Smckusick panic("cannot mount root"); 22637610Smckusick /* 22737610Smckusick * Get vnode for '/'. 22847654Skarels * Setup rootdir and fdp->fd_fd.fd_cdir to point to it. 22937610Smckusick */ 23037610Smckusick if (VFS_ROOT(rootfs, &rootdir)) 23137610Smckusick panic("cannot find root vnode"); 23247654Skarels fdp->fd_fd.fd_cdir = rootdir; 23347654Skarels VREF(fdp->fd_fd.fd_cdir); 23437726Smckusick VOP_UNLOCK(rootdir); 23547654Skarels fdp->fd_fd.fd_rdir = NULL; 23647543Skarels swapinit(); 23726Sbill 23826Sbill /* 23947543Skarels * Now can look at time, having had a chance 24047543Skarels * to verify the time from the file system. 24147543Skarels */ 24254943Storek p->p_stats->p_start = runtime = mono_time = boottime = time; 24347543Skarels 24447543Skarels /* 24516807Skarels * make init process 24616807Skarels */ 24747543Skarels siginit(p); 24852504Sbostic if (fork(p, NULL, rval)) 24947543Skarels panic("fork init"); 25047543Skarels if (rval[1]) { 25149382Skarels extern int icode[]; /* user init code */ 25249382Skarels extern int szicode; /* size of icode */ 25352504Sbostic static char initflags[] = "-sf"; 25452504Sbostic vm_offset_t addr; 25552504Sbostic char *ip; 25645724Smckusick 25747543Skarels /* 25852504Sbostic * Now in process 1. Set init flags into icode, get a minimal 25952504Sbostic * address space, copy out "icode", and return to it to do an 26052504Sbostic * exec of init. 26147543Skarels */ 26252504Sbostic ip = initflags + 1; 26347543Skarels if (boothowto&RB_SINGLE) 26447543Skarels *ip++ = 's'; 26547543Skarels #ifdef notyet 26647543Skarels if (boothowto&RB_FASTBOOT) 26747543Skarels *ip++ = 'f'; 26847689Skarels #endif 26952504Sbostic if (ip == initflags + 1) 27052504Sbostic *ip++ = '-'; 27147543Skarels *ip++ = '\0'; 27247543Skarels 27352505Storek addr = VM_MIN_ADDRESS; 27452504Sbostic initproc = p = curproc; 27547543Skarels if (vm_allocate(&p->p_vmspace->vm_map, &addr, 27647689Skarels round_page(szicode + sizeof(initflags)), FALSE) != 0 || 27752505Storek addr != VM_MIN_ADDRESS) 27845724Smckusick panic("init: couldn't allocate at zero"); 27945724Smckusick 28045724Smckusick /* need just enough stack to exec from */ 28148981Skarels addr = trunc_page(USRSTACK - PAGE_SIZE); 28247543Skarels if (vm_allocate(&p->p_vmspace->vm_map, &addr, 28347543Skarels PAGE_SIZE, FALSE) != KERN_SUCCESS) 28447543Skarels panic("vm_allocate init stack"); 28547543Skarels p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 28652505Storek (void)copyout((caddr_t)icode, (caddr_t)VM_MIN_ADDRESS, 28752505Storek (u_int)szicode); 28852505Storek (void)copyout(initflags, (caddr_t)(VM_MIN_ADDRESS + szicode), 28952505Storek sizeof(initflags)); 29047543Skarels return; /* returns to icode */ 29116807Skarels } 29247543Skarels 29316807Skarels /* 29445724Smckusick * Start up pageout daemon (process 2). 29526Sbill */ 29652504Sbostic if (fork(p, NULL, rval)) 29747543Skarels panic("fork pager"); 29847543Skarels if (rval[1]) { 29947543Skarels /* 30047543Skarels * Now in process 2. 30147543Skarels */ 30247543Skarels p = curproc; 30347543Skarels pageproc = p; 30447543Skarels p->p_flag |= SLOAD|SSYS; /* XXX */ 30547543Skarels bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); 30645724Smckusick vm_pageout(); 3079025Sroot /*NOTREACHED*/ 30826Sbill } 30926Sbill 31026Sbill /* 31126Sbill * enter scheduling loop 31226Sbill */ 31326Sbill sched(); 31426Sbill } 315