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