1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)init_main.c 7.40 (Berkeley) 05/09/91 8 */ 9 10 #include "param.h" 11 #include "filedesc.h" 12 #include "kernel.h" 13 #include "mount.h" 14 #include "map.h" 15 #include "proc.h" 16 #include "resourcevar.h" 17 #include "signalvar.h" 18 #include "systm.h" 19 #include "vnode.h" 20 #include "seg.h" 21 #include "conf.h" 22 #include "buf.h" 23 #include "clist.h" 24 #include "malloc.h" 25 #include "protosw.h" 26 #include "reboot.h" 27 #include "user.h" 28 29 #include "ufs/quota.h" 30 31 #include "machine/cpu.h" 32 33 #include "vm/vm.h" 34 35 char copyright[] = 36 "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n"; 37 38 /* 39 * Components of process 0; 40 * never freed. 41 */ 42 struct session session0; 43 struct pgrp pgrp0; 44 struct proc proc0; 45 struct pcred cred0; 46 struct filedesc0 filedesc0; 47 struct plimit limit0; 48 struct vmspace vmspace0; 49 struct proc *curproc = &proc0; 50 struct proc *initproc, *pageproc; 51 52 int cmask = CMASK; 53 extern struct user *proc0paddr; 54 extern int (*mountroot)(); 55 56 struct vnode *rootvp, *swapdev_vp; 57 int boothowto; 58 59 /* 60 * System startup; initialize the world, create process 0, 61 * mount root filesystem, and fork to create init and pagedaemon. 62 * Most of the hard work is done in the lower-level initialization 63 * routines including startup(), which does memory initialization 64 * and autoconfiguration. 65 */ 66 main() 67 { 68 register int i; 69 register struct proc *p; 70 register struct filedesc0 *fdp; 71 int s, rval[2]; 72 73 /* 74 * Initialize curproc before any possible traps/probes 75 * to simplify trap processing. 76 */ 77 p = &proc0; 78 curproc = p; 79 /* 80 * Attempt to find console and initialize 81 * in case of early panic or other messages. 82 */ 83 consinit(); 84 printf(copyright); 85 86 vm_mem_init(); 87 kmeminit(); 88 cpu_startup(); 89 90 /* 91 * set up system process 0 (swapper) 92 */ 93 p = &proc0; 94 curproc = p; 95 96 allproc = p; 97 p->p_prev = &allproc; 98 p->p_pgrp = &pgrp0; 99 pgrphash[0] = &pgrp0; 100 pgrp0.pg_mem = p; 101 pgrp0.pg_session = &session0; 102 session0.s_count = 1; 103 session0.s_leader = p; 104 105 p->p_flag = SLOAD|SSYS; 106 p->p_stat = SRUN; 107 p->p_nice = NZERO; 108 bcopy("swapper", p->p_comm, sizeof ("swapper")); 109 110 /* 111 * Setup credentials 112 */ 113 p->p_cred = &cred0; 114 p->p_ucred = crget(); 115 p->p_ucred->cr_ngroups = 1; /* group 0 */ 116 117 /* 118 * Create the file descriptor table for process 0. 119 */ 120 fdp = &filedesc0; 121 p->p_fd = &fdp->fd_fd; 122 fdp->fd_fd.fd_refcnt = 1; 123 fdp->fd_fd.fd_cmask = cmask; 124 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 125 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 126 fdp->fd_fd.fd_nfiles = NDFILE; 127 128 /* 129 * Set initial limits 130 */ 131 p->p_limit = &limit0; 132 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 133 limit0.pl_rlimit[i].rlim_cur = 134 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 135 limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE; 136 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 137 limit0.p_refcnt = 1; 138 139 /* 140 * Allocate a prototype map so we have something to fork 141 */ 142 p->p_vmspace = &vmspace0; 143 vmspace0.vm_refcnt = 1; 144 pmap_pinit(&vmspace0.vm_pmap); 145 vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS), 146 trunc_page(VM_MAX_ADDRESS), TRUE); 147 vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 148 p->p_addr = proc0paddr; /* XXX */ 149 150 /* 151 * We continue to place resource usage info 152 * and signal actions in the user struct so they're pageable. 153 */ 154 p->p_stats = &p->p_addr->u_stats; 155 p->p_sigacts = &p->p_addr->u_sigacts; 156 157 rqinit(); 158 159 /* 160 * configure virtual memory system, 161 * set vm rlimits 162 */ 163 vm_init_limits(p); 164 165 /* 166 * Initialize the file systems. 167 * 168 * Get vnodes for swapdev and rootdev. 169 */ 170 vfsinit(); 171 if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) 172 panic("can't setup bdevvp's"); 173 174 startrtclock(); 175 #if defined(vax) 176 #include "kg.h" 177 #if NKG > 0 178 startkgclock(); 179 #endif 180 #endif 181 182 /* 183 * Initialize tables, protocols, and set up well-known inodes. 184 */ 185 mbinit(); 186 cinit(); 187 #ifdef SYSVSHM 188 shminit(); 189 #endif 190 #include "sl.h" 191 #if NSL > 0 192 slattach(); /* XXX */ 193 #endif 194 #include "loop.h" 195 #if NLOOP > 0 196 loattach(); /* XXX */ 197 #endif 198 /* 199 * Block reception of incoming packets 200 * until protocols have been initialized. 201 */ 202 s = splimp(); 203 ifinit(); 204 domaininit(); 205 splx(s); 206 207 #ifdef GPROF 208 kmstartup(); 209 #endif 210 211 /* kick off timeout driven events by calling first time */ 212 roundrobin(); 213 schedcpu(); 214 enablertclock(); /* enable realtime clock interrupts */ 215 216 /* 217 * Set up the root file system and vnode. 218 */ 219 if ((*mountroot)()) 220 panic("cannot mount root"); 221 /* 222 * Get vnode for '/'. 223 * Setup rootdir and fdp->fd_fd.fd_cdir to point to it. 224 */ 225 if (VFS_ROOT(rootfs, &rootdir)) 226 panic("cannot find root vnode"); 227 fdp->fd_fd.fd_cdir = rootdir; 228 VREF(fdp->fd_fd.fd_cdir); 229 VOP_UNLOCK(rootdir); 230 fdp->fd_fd.fd_rdir = NULL; 231 swapinit(); 232 233 /* 234 * Now can look at time, having had a chance 235 * to verify the time from the file system. 236 */ 237 boottime = p->p_stats->p_start = time; 238 239 /* 240 * make init process 241 */ 242 siginit(p); 243 if (fork(p, (void *) NULL, rval)) 244 panic("fork init"); 245 if (rval[1]) { 246 static char initflags[] = "-sf"; 247 char *ip = initflags + 1; 248 vm_offset_t addr = 0; 249 extern int icode[]; /* user init code */ 250 extern int szicode; /* size of icode */ 251 252 /* 253 * Now in process 1. Set init flags into icode, 254 * get a minimal address space, copy out "icode", 255 * and return to it to do an exec of init. 256 */ 257 p = curproc; 258 initproc = p; 259 if (boothowto&RB_SINGLE) 260 *ip++ = 's'; 261 #ifdef notyet 262 if (boothowto&RB_FASTBOOT) 263 *ip++ = 'f'; 264 #endif 265 *ip++ = '\0'; 266 267 if (vm_allocate(&p->p_vmspace->vm_map, &addr, 268 round_page(szicode + sizeof(initflags)), FALSE) != 0 || 269 addr != 0) 270 panic("init: couldn't allocate at zero"); 271 272 /* need just enough stack to exec from */ 273 addr = trunc_page(USRSTACK - PAGE_SIZE); 274 if (vm_allocate(&p->p_vmspace->vm_map, &addr, 275 PAGE_SIZE, FALSE) != KERN_SUCCESS) 276 panic("vm_allocate init stack"); 277 p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 278 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 279 (void) copyout(initflags, (caddr_t)szicode, sizeof(initflags)); 280 return; /* returns to icode */ 281 } 282 283 /* 284 * Start up pageout daemon (process 2). 285 */ 286 if (fork(p, (void *) NULL, rval)) 287 panic("fork pager"); 288 if (rval[1]) { 289 /* 290 * Now in process 2. 291 */ 292 p = curproc; 293 pageproc = p; 294 p->p_flag |= SLOAD|SSYS; /* XXX */ 295 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); 296 vm_pageout(); 297 /*NOTREACHED*/ 298 } 299 300 /* 301 * enter scheduling loop 302 */ 303 sched(); 304 } 305