|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms, with or without ! 6: * modification, are permitted provided that the following conditions ! 7: * are met: ! 8: * 1. Redistributions of source code must retain the above copyright ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * 3. All advertising materials mentioning features or use of this software ! 14: * must display the following acknowledgement: ! 15: * This product includes software developed by the University of ! 16: * California, Berkeley and its contributors. ! 17: * 4. Neither the name of the University nor the names of its contributors ! 18: * may be used to endorse or promote products derived from this software ! 19: * without specific prior written permission. ! 20: * ! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 31: * SUCH DAMAGE. ! 32: * ! 33: * @(#)init_main.c 7.41 (Berkeley) 5/15/91 ! 34: */ ! 35: ! 36: #include "param.h" ! 37: #include "filedesc.h" ! 38: #include "kernel.h" ! 39: #include "mount.h" ! 40: #include "map.h" ! 41: #include "proc.h" ! 42: #include "resourcevar.h" ! 43: #include "signalvar.h" ! 44: #include "systm.h" ! 45: #include "vnode.h" ! 46: #include "seg.h" ! 47: #include "conf.h" ! 48: #include "buf.h" ! 49: #include "clist.h" ! 50: #include "malloc.h" ! 51: #include "protosw.h" ! 52: #include "reboot.h" ! 53: #include "user.h" ! 54: ! 55: #include "ufs/quota.h" ! 56: ! 57: #include "machine/cpu.h" ! 58: ! 59: #include "vm/vm.h" ! 60: ! 61: char copyright[] = ! 62: "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n"; ! 63: ! 64: /* ! 65: * Components of process 0; ! 66: * never freed. ! 67: */ ! 68: struct session session0; ! 69: struct pgrp pgrp0; ! 70: struct proc proc0; ! 71: struct pcred cred0; ! 72: struct filedesc0 filedesc0; ! 73: struct plimit limit0; ! 74: struct vmspace vmspace0; ! 75: struct proc *curproc = &proc0; ! 76: struct proc *initproc, *pageproc; ! 77: ! 78: int cmask = CMASK; ! 79: extern struct user *proc0paddr; ! 80: extern int (*mountroot)(); ! 81: ! 82: struct vnode *rootvp, *swapdev_vp; ! 83: int boothowto; ! 84: ! 85: /* ! 86: * System startup; initialize the world, create process 0, ! 87: * mount root filesystem, and fork to create init and pagedaemon. ! 88: * Most of the hard work is done in the lower-level initialization ! 89: * routines including startup(), which does memory initialization ! 90: * and autoconfiguration. ! 91: */ ! 92: main() ! 93: { ! 94: register int i; ! 95: register struct proc *p; ! 96: register struct filedesc0 *fdp; ! 97: int s, rval[2]; ! 98: ! 99: /* ! 100: * Initialize curproc before any possible traps/probes ! 101: * to simplify trap processing. ! 102: */ ! 103: p = &proc0; ! 104: curproc = p; ! 105: /* ! 106: * Attempt to find console and initialize ! 107: * in case of early panic or other messages. ! 108: */ ! 109: consinit(); ! 110: printf(copyright); ! 111: ! 112: vm_mem_init(); ! 113: kmeminit(); ! 114: cpu_startup(); ! 115: ! 116: /* ! 117: * set up system process 0 (swapper) ! 118: */ ! 119: p = &proc0; ! 120: curproc = p; ! 121: ! 122: allproc = p; ! 123: p->p_prev = &allproc; ! 124: p->p_pgrp = &pgrp0; ! 125: pgrphash[0] = &pgrp0; ! 126: pgrp0.pg_mem = p; ! 127: pgrp0.pg_session = &session0; ! 128: session0.s_count = 1; ! 129: session0.s_leader = p; ! 130: ! 131: p->p_flag = SLOAD|SSYS; ! 132: p->p_stat = SRUN; ! 133: p->p_nice = NZERO; ! 134: bcopy("swapper", p->p_comm, sizeof ("swapper")); ! 135: ! 136: /* ! 137: * Setup credentials ! 138: */ ! 139: cred0.p_refcnt = 1; ! 140: p->p_cred = &cred0; ! 141: p->p_ucred = crget(); ! 142: p->p_ucred->cr_ngroups = 1; /* group 0 */ ! 143: ! 144: /* ! 145: * Create the file descriptor table for process 0. ! 146: */ ! 147: fdp = &filedesc0; ! 148: p->p_fd = &fdp->fd_fd; ! 149: fdp->fd_fd.fd_refcnt = 1; ! 150: fdp->fd_fd.fd_cmask = cmask; ! 151: fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; ! 152: fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; ! 153: fdp->fd_fd.fd_nfiles = NDFILE; ! 154: ! 155: /* ! 156: * Set initial limits ! 157: */ ! 158: p->p_limit = &limit0; ! 159: for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) ! 160: limit0.pl_rlimit[i].rlim_cur = ! 161: limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; ! 162: limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE; ! 163: limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; ! 164: limit0.p_refcnt = 1; ! 165: ! 166: /* ! 167: * Allocate a prototype map so we have something to fork ! 168: */ ! 169: p->p_vmspace = &vmspace0; ! 170: vmspace0.vm_refcnt = 1; ! 171: pmap_pinit(&vmspace0.vm_pmap); ! 172: vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS), ! 173: trunc_page(VM_MAX_ADDRESS), TRUE); ! 174: vmspace0.vm_map.pmap = &vmspace0.vm_pmap; ! 175: p->p_addr = proc0paddr; /* XXX */ ! 176: ! 177: /* ! 178: * We continue to place resource usage info ! 179: * and signal actions in the user struct so they're pageable. ! 180: */ ! 181: p->p_stats = &p->p_addr->u_stats; ! 182: p->p_sigacts = &p->p_addr->u_sigacts; ! 183: ! 184: rqinit(); ! 185: ! 186: /* ! 187: * configure virtual memory system, ! 188: * set vm rlimits ! 189: */ ! 190: vm_init_limits(p); ! 191: ! 192: /* ! 193: * Initialize the file systems. ! 194: * ! 195: * Get vnodes for swapdev and rootdev. ! 196: */ ! 197: vfsinit(); ! 198: if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) ! 199: panic("can't setup bdevvp's"); ! 200: ! 201: startrtclock(); ! 202: #if defined(vax) ! 203: #include "kg.h" ! 204: #if NKG > 0 ! 205: startkgclock(); ! 206: #endif ! 207: #endif ! 208: ! 209: /* ! 210: * Initialize tables, protocols, and set up well-known inodes. ! 211: */ ! 212: mbinit(); ! 213: cinit(); ! 214: #ifdef SYSVSHM ! 215: shminit(); ! 216: #endif ! 217: #include "sl.h" ! 218: #if NSL > 0 ! 219: slattach(); /* XXX */ ! 220: #endif ! 221: #include "loop.h" ! 222: #if NLOOP > 0 ! 223: loattach(); /* XXX */ ! 224: #endif ! 225: /* ! 226: * Block reception of incoming packets ! 227: * until protocols have been initialized. ! 228: */ ! 229: s = splimp(); ! 230: ifinit(); ! 231: domaininit(); ! 232: splx(s); ! 233: ! 234: #ifdef GPROF ! 235: kmstartup(); ! 236: #endif ! 237: ! 238: /* kick off timeout driven events by calling first time */ ! 239: roundrobin(); ! 240: schedcpu(); ! 241: enablertclock(); /* enable realtime clock interrupts */ ! 242: ! 243: /* ! 244: * Set up the root file system and vnode. ! 245: */ ! 246: if ((*mountroot)()) ! 247: panic("cannot mount root"); ! 248: /* ! 249: * Get vnode for '/'. ! 250: * Setup rootdir and fdp->fd_fd.fd_cdir to point to it. ! 251: */ ! 252: if (VFS_ROOT(rootfs, &rootdir)) ! 253: panic("cannot find root vnode"); ! 254: fdp->fd_fd.fd_cdir = rootdir; ! 255: VREF(fdp->fd_fd.fd_cdir); ! 256: VOP_UNLOCK(rootdir); ! 257: fdp->fd_fd.fd_rdir = NULL; ! 258: swapinit(); ! 259: ! 260: /* ! 261: * Now can look at time, having had a chance ! 262: * to verify the time from the file system. ! 263: */ ! 264: boottime = p->p_stats->p_start = time; ! 265: ! 266: /* ! 267: * make init process ! 268: */ ! 269: siginit(p); ! 270: if (fork(p, (void *) NULL, rval)) ! 271: panic("fork init"); ! 272: if (rval[1]) { ! 273: static char initflags[] = "-sf"; ! 274: char *ip = initflags + 1; ! 275: vm_offset_t addr = 0; ! 276: extern int icode[]; /* user init code */ ! 277: extern int szicode; /* size of icode */ ! 278: ! 279: /* ! 280: * Now in process 1. Set init flags into icode, ! 281: * get a minimal address space, copy out "icode", ! 282: * and return to it to do an exec of init. ! 283: */ ! 284: p = curproc; ! 285: initproc = p; ! 286: if (boothowto&RB_SINGLE) ! 287: *ip++ = 's'; ! 288: #ifdef notyet ! 289: if (boothowto&RB_FASTBOOT) ! 290: *ip++ = 'f'; ! 291: #endif ! 292: *ip++ = '\0'; ! 293: ! 294: if (vm_allocate(&p->p_vmspace->vm_map, &addr, ! 295: round_page(szicode + sizeof(initflags)), FALSE) != 0 || ! 296: addr != 0) ! 297: panic("init: couldn't allocate at zero"); ! 298: ! 299: /* need just enough stack to exec from */ ! 300: addr = trunc_page(USRSTACK - PAGE_SIZE); ! 301: if (vm_allocate(&p->p_vmspace->vm_map, &addr, ! 302: PAGE_SIZE, FALSE) != KERN_SUCCESS) ! 303: panic("vm_allocate init stack"); ! 304: p->p_vmspace->vm_maxsaddr = (caddr_t)addr; ! 305: (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); ! 306: (void) copyout(initflags, (caddr_t)szicode, sizeof(initflags)); ! 307: return; /* returns to icode */ ! 308: } ! 309: ! 310: /* ! 311: * Start up pageout daemon (process 2). ! 312: */ ! 313: if (fork(p, (void *) NULL, rval)) ! 314: panic("fork pager"); ! 315: if (rval[1]) { ! 316: /* ! 317: * Now in process 2. ! 318: */ ! 319: p = curproc; ! 320: pageproc = p; ! 321: p->p_flag |= SLOAD|SSYS; /* XXX */ ! 322: bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); ! 323: vm_pageout(); ! 324: /*NOTREACHED*/ ! 325: } ! 326: ! 327: /* ! 328: * enter scheduling loop ! 329: */ ! 330: sched(); ! 331: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.