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*56935Smckusick * @(#)init_main.c 7.57 (Berkeley) 12/01/92 823364Smckusick */ 926Sbill 1056934Smckusick #include <sys/param.h> 1156934Smckusick #include <sys/filedesc.h> 1256934Smckusick #include <sys/kernel.h> 1356934Smckusick #include <sys/mount.h> 1456934Smckusick #include <sys/map.h> 1556934Smckusick #include <sys/proc.h> 1656934Smckusick #include <sys/resourcevar.h> 1756934Smckusick #include <sys/signalvar.h> 1856934Smckusick #include <sys/systm.h> 1956934Smckusick #include <sys/vnode.h> 2056934Smckusick #include <sys/conf.h> 2156934Smckusick #include <sys/buf.h> 2256934Smckusick #include <sys/clist.h> 2356934Smckusick #include <sys/protosw.h> 2456934Smckusick #include <sys/reboot.h> 2556934Smckusick #include <sys/user.h> 2647654Skarels 2756934Smckusick #include <ufs/ufs/quota.h> 2826Sbill 2956934Smckusick #include <machine/cpu.h> 3037522Smckusick 3156934Smckusick #include <vm/vm.h> 3245724Smckusick 3355399Smckusick #ifdef HPFPLIB 3449382Skarels char copyright[] = 3555399Smckusick "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"; 3655399Smckusick #else 3755399Smckusick char copyright[] = 3849382Skarels "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n"; 3955399Smckusick #endif 4049382Skarels 4147543Skarels /* 4247543Skarels * Components of process 0; 4347543Skarels * never freed. 4447543Skarels */ 4547543Skarels struct session session0; 4647543Skarels struct pgrp pgrp0; 4747543Skarels struct proc proc0; 4847543Skarels struct pcred cred0; 4947654Skarels struct filedesc0 filedesc0; 5047543Skarels struct plimit limit0; 5147543Skarels struct vmspace vmspace0; 5247654Skarels struct proc *curproc = &proc0; 5347543Skarels struct proc *initproc, *pageproc; 5447543Skarels 5516807Skarels int cmask = CMASK; 5648981Skarels extern struct user *proc0paddr; 5737610Smckusick extern int (*mountroot)(); 5845880Swilliam 5949382Skarels struct vnode *rootvp, *swapdev_vp; 6049382Skarels int boothowto; 6153009Ssklower struct timeval boottime; 6254781Storek struct timeval runtime; 6349382Skarels 6426Sbill /* 6547543Skarels * System startup; initialize the world, create process 0, 6647543Skarels * mount root filesystem, and fork to create init and pagedaemon. 6747543Skarels * Most of the hard work is done in the lower-level initialization 6847543Skarels * routines including startup(), which does memory initialization 6947543Skarels * and autoconfiguration. 7026Sbill */ 7149533Skarels main() 7226Sbill { 73361Sbill register int i; 742451Swnj register struct proc *p; 7547654Skarels register struct filedesc0 *fdp; 7647543Skarels int s, rval[2]; 7754781Storek extern void roundrobin __P((void *)); 7854781Storek extern void schedcpu __P((void *)); 7926Sbill 8045880Swilliam /* 8147543Skarels * Initialize curproc before any possible traps/probes 8247543Skarels * to simplify trap processing. 8345880Swilliam */ 8447543Skarels p = &proc0; 8547543Skarels curproc = p; 8645724Smckusick /* 8747543Skarels * Attempt to find console and initialize 8847543Skarels * in case of early panic or other messages. 8945724Smckusick */ 9047543Skarels consinit(); 9149382Skarels printf(copyright); 9247543Skarels 9345724Smckusick vm_mem_init(); 9445724Smckusick kmeminit(); 9549533Skarels cpu_startup(); 9626Sbill 9726Sbill /* 9826Sbill * set up system process 0 (swapper) 9926Sbill */ 10047543Skarels p = &proc0; 10147543Skarels curproc = p; 10247543Skarels 10354781Storek allproc = (volatile struct proc *)p; 10454781Storek p->p_prev = (struct proc **)&allproc; 10547543Skarels p->p_pgrp = &pgrp0; 10647543Skarels pgrphash[0] = &pgrp0; 10747543Skarels pgrp0.pg_mem = p; 10847543Skarels pgrp0.pg_session = &session0; 10947543Skarels session0.s_count = 1; 11047543Skarels session0.s_leader = p; 11147543Skarels 11247543Skarels p->p_flag = SLOAD|SSYS; 1132451Swnj p->p_stat = SRUN; 1142451Swnj p->p_nice = NZERO; 11547543Skarels bcopy("swapper", p->p_comm, sizeof ("swapper")); 11647543Skarels 11745724Smckusick /* 11847543Skarels * Setup credentials 11945724Smckusick */ 12049745Smckusick cred0.p_refcnt = 1; 12147543Skarels p->p_cred = &cred0; 12247543Skarels p->p_ucred = crget(); 12347543Skarels p->p_ucred->cr_ngroups = 1; /* group 0 */ 12429946Skarels 12545914Smckusick /* 12645914Smckusick * Create the file descriptor table for process 0. 12745914Smckusick */ 12847543Skarels fdp = &filedesc0; 12947654Skarels p->p_fd = &fdp->fd_fd; 13047654Skarels fdp->fd_fd.fd_refcnt = 1; 13147654Skarels fdp->fd_fd.fd_cmask = cmask; 13247654Skarels fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 13347654Skarels fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 13447654Skarels fdp->fd_fd.fd_nfiles = NDFILE; 13547543Skarels 13618278Smckusick /* 13747543Skarels * Set initial limits 13847543Skarels */ 13947543Skarels p->p_limit = &limit0; 14047543Skarels for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 14147543Skarels limit0.pl_rlimit[i].rlim_cur = 14247543Skarels limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 143*56935Smckusick limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; 14447543Skarels limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 14547543Skarels limit0.p_refcnt = 1; 14647543Skarels 14747543Skarels /* 14847543Skarels * Allocate a prototype map so we have something to fork 14947543Skarels */ 15047543Skarels p->p_vmspace = &vmspace0; 15147543Skarels vmspace0.vm_refcnt = 1; 15247543Skarels pmap_pinit(&vmspace0.vm_pmap); 15347543Skarels vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS), 15447543Skarels trunc_page(VM_MAX_ADDRESS), TRUE); 15547543Skarels vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 15647543Skarels p->p_addr = proc0paddr; /* XXX */ 15747543Skarels 15847543Skarels /* 15947543Skarels * We continue to place resource usage info 16047543Skarels * and signal actions in the user struct so they're pageable. 16147543Skarels */ 16248981Skarels p->p_stats = &p->p_addr->u_stats; 16348981Skarels p->p_sigacts = &p->p_addr->u_sigacts; 16447543Skarels 16555406Smckusick /* 16655406Smckusick * Initialize per uid information structure and charge 16755406Smckusick * root for one process. 16855406Smckusick */ 16955406Smckusick usrinfoinit(); 17055406Smckusick (void)chgproccnt(0, 1); 17155406Smckusick 17247543Skarels rqinit(); 17347543Skarels 17447543Skarels /* 17523534Skarels * configure virtual memory system, 17623534Skarels * set vm rlimits 17718278Smckusick */ 17847543Skarels vm_init_limits(p); 17923534Skarels 18037610Smckusick /* 18139431Smckusick * Initialize the file systems. 18237610Smckusick */ 18339431Smckusick vfsinit(); 18437610Smckusick 18554781Storek /* 18654781Storek * Start real time and statistics clocks. 18754781Storek */ 18854781Storek initclocks(); 18926Sbill 19026Sbill /* 1914821Swnj * Initialize tables, protocols, and set up well-known inodes. 19226Sbill */ 1934821Swnj mbinit(); 19421103Skarels cinit(); 19541565Smckusick #ifdef SYSVSHM 19641565Smckusick shminit(); 19741565Smckusick #endif 19826137Skarels #include "sl.h" 19926137Skarels #if NSL > 0 20026137Skarels slattach(); /* XXX */ 20126137Skarels #endif 20241565Smckusick #include "loop.h" 2035855Swnj #if NLOOP > 0 2045855Swnj loattach(); /* XXX */ 2055855Swnj #endif 2069156Ssam /* 2079156Ssam * Block reception of incoming packets 2089156Ssam * until protocols have been initialized. 2099156Ssam */ 2109156Ssam s = splimp(); 2115227Swnj ifinit(); 2128969Sroot domaininit(); 2139156Ssam splx(s); 21447543Skarels 2157419Sroot #ifdef GPROF 2167419Sroot kmstartup(); 2177419Sroot #endif 2187189Sroot 21947543Skarels /* kick off timeout driven events by calling first time */ 22054781Storek roundrobin(NULL); 22154781Storek schedcpu(NULL); 2228096Sroot 22347543Skarels /* 22447543Skarels * Set up the root file system and vnode. 22547543Skarels */ 22637610Smckusick if ((*mountroot)()) 22737610Smckusick panic("cannot mount root"); 22837610Smckusick /* 22937610Smckusick * Get vnode for '/'. 23047654Skarels * Setup rootdir and fdp->fd_fd.fd_cdir to point to it. 23137610Smckusick */ 23237610Smckusick if (VFS_ROOT(rootfs, &rootdir)) 23337610Smckusick panic("cannot find root vnode"); 23447654Skarels fdp->fd_fd.fd_cdir = rootdir; 23547654Skarels VREF(fdp->fd_fd.fd_cdir); 23637726Smckusick VOP_UNLOCK(rootdir); 23747654Skarels fdp->fd_fd.fd_rdir = NULL; 23847543Skarels swapinit(); 23926Sbill 24026Sbill /* 24155796Smckusick * Now can look at time, having had a chance to verify the time 24255796Smckusick * from the file system. Reset p->p_rtime as it may have been 24355796Smckusick * munched in swtch() after the time got set. 24447543Skarels */ 24554943Storek p->p_stats->p_start = runtime = mono_time = boottime = time; 24655796Smckusick p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0; 24747543Skarels 24847543Skarels /* 24916807Skarels * make init process 25016807Skarels */ 25147543Skarels siginit(p); 25252504Sbostic if (fork(p, NULL, rval)) 25347543Skarels panic("fork init"); 25447543Skarels if (rval[1]) { 25549382Skarels extern int icode[]; /* user init code */ 25649382Skarels extern int szicode; /* size of icode */ 25752504Sbostic static char initflags[] = "-sf"; 25852504Sbostic vm_offset_t addr; 25952504Sbostic char *ip; 26045724Smckusick 26147543Skarels /* 26252504Sbostic * Now in process 1. Set init flags into icode, get a minimal 26352504Sbostic * address space, copy out "icode", and return to it to do an 26452504Sbostic * exec of init. 26547543Skarels */ 26652504Sbostic ip = initflags + 1; 26747543Skarels if (boothowto&RB_SINGLE) 26847543Skarels *ip++ = 's'; 26947543Skarels #ifdef notyet 27047543Skarels if (boothowto&RB_FASTBOOT) 27147543Skarels *ip++ = 'f'; 27247689Skarels #endif 27352504Sbostic if (ip == initflags + 1) 27452504Sbostic *ip++ = '-'; 27547543Skarels *ip++ = '\0'; 27647543Skarels 27752505Storek addr = VM_MIN_ADDRESS; 27852504Sbostic initproc = p = curproc; 27947543Skarels if (vm_allocate(&p->p_vmspace->vm_map, &addr, 28047689Skarels round_page(szicode + sizeof(initflags)), FALSE) != 0 || 28152505Storek addr != VM_MIN_ADDRESS) 28245724Smckusick panic("init: couldn't allocate at zero"); 28345724Smckusick 28445724Smckusick /* need just enough stack to exec from */ 28548981Skarels addr = trunc_page(USRSTACK - PAGE_SIZE); 28647543Skarels if (vm_allocate(&p->p_vmspace->vm_map, &addr, 28747543Skarels PAGE_SIZE, FALSE) != KERN_SUCCESS) 28847543Skarels panic("vm_allocate init stack"); 28947543Skarels p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 29052505Storek (void)copyout((caddr_t)icode, (caddr_t)VM_MIN_ADDRESS, 29152505Storek (u_int)szicode); 29252505Storek (void)copyout(initflags, (caddr_t)(VM_MIN_ADDRESS + szicode), 29352505Storek sizeof(initflags)); 29447543Skarels return; /* returns to icode */ 29516807Skarels } 29647543Skarels 29716807Skarels /* 29845724Smckusick * Start up pageout daemon (process 2). 29926Sbill */ 30052504Sbostic if (fork(p, NULL, rval)) 30147543Skarels panic("fork pager"); 30247543Skarels if (rval[1]) { 30347543Skarels /* 30447543Skarels * Now in process 2. 30547543Skarels */ 30647543Skarels p = curproc; 30747543Skarels pageproc = p; 30847543Skarels p->p_flag |= SLOAD|SSYS; /* XXX */ 30947543Skarels bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); 31045724Smckusick vm_pageout(); 3119025Sroot /*NOTREACHED*/ 31226Sbill } 31326Sbill 31426Sbill /* 31526Sbill * enter scheduling loop 31626Sbill */ 31726Sbill sched(); 31826Sbill } 319