1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)init_main.c 7.30 (Berkeley) 12/05/90 7 */ 8 9 #include "param.h" 10 #include "systm.h" 11 #include "user.h" 12 #include "kernel.h" 13 #include "mount.h" 14 #include "map.h" 15 #include "proc.h" 16 #include "vnode.h" 17 #include "seg.h" 18 #include "conf.h" 19 #include "buf.h" 20 #include "clist.h" 21 #include "malloc.h" 22 #include "protosw.h" 23 #include "reboot.h" 24 #include "../ufs/quota.h" 25 26 #include "machine/reg.h" 27 #include "machine/cpu.h" 28 29 #include "../vm/vm_param.h" 30 #include "../vm/vm_map.h" 31 32 int cmask = CMASK; 33 extern caddr_t proc0paddr; 34 extern int (*mountroot)(); 35 /* 36 * Initialization code. 37 * Called from cold start routine as 38 * soon as a stack and segmentation 39 * have been established. 40 * Functions: 41 * clear and free user core 42 * turn on clock 43 * hand craft 0th process 44 * call all initialization routines 45 * fork - process 0 to schedule 46 * - process 1 execute bootstrap 47 * - process 2 to page out 48 */ 49 main(firstaddr) 50 int firstaddr; 51 { 52 register int i; 53 register struct proc *p; 54 register struct pgrp *pg; 55 int s; 56 57 rqinit(); 58 #if defined(hp300) && defined(DEBUG) 59 /* 60 * Assumes mapping is really on 61 */ 62 find_devs(); 63 cninit(); 64 #endif 65 vm_mem_init(); 66 kmeminit(); 67 startup(firstaddr); 68 69 /* 70 * set up system process 0 (swapper) 71 */ 72 p = &proc[0]; 73 bcopy("swapper", p->p_comm, sizeof ("swapper")); 74 p->p_stat = SRUN; 75 p->p_flag |= SLOAD|SSYS; 76 p->p_nice = NZERO; 77 /* 78 * Allocate a prototype map so we have something to fork 79 */ 80 p->p_map = vm_map_create(pmap_create(0), 81 round_page(VM_MIN_ADDRESS), 82 trunc_page(VM_MAX_ADDRESS), TRUE); 83 p->p_addr = proc0paddr; 84 u.u_procp = p; 85 MALLOC(pgrphash[0], struct pgrp *, sizeof (struct pgrp), 86 M_PGRP, M_NOWAIT); 87 if ((pg = pgrphash[0]) == NULL) 88 panic("no space to craft zero'th process group"); 89 pg->pg_id = 0; 90 pg->pg_hforw = 0; 91 pg->pg_mem = p; 92 pg->pg_jobc = 0; 93 p->p_pgrp = pg; 94 p->p_pgrpnxt = 0; 95 MALLOC(pg->pg_session, struct session *, sizeof (struct session), 96 M_SESSION, M_NOWAIT); 97 if (pg->pg_session == NULL) 98 panic("no space to craft zero'th session"); 99 pg->pg_session->s_count = 1; 100 pg->pg_session->s_leader = NULL; 101 pg->pg_session->s_ttyvp = NULL; 102 pg->pg_session->s_ttyp = NULL; 103 #ifdef KTRACE 104 p->p_tracep = NULL; 105 p->p_traceflag = 0; 106 #endif 107 /* 108 * These assume that the u. area is always mapped 109 * to the same virtual address. Otherwise must be 110 * handled when copying the u. area in newproc(). 111 */ 112 ndinit(&u.u_nd); 113 114 u.u_cmask = cmask; 115 u.u_lastfile = -1; 116 for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++) 117 u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max = 118 RLIM_INFINITY; 119 /* 120 * configure virtual memory system, 121 * set vm rlimits 122 */ 123 vminit(); 124 125 /* 126 * Initialize the file systems. 127 * 128 * Get vnodes for swapdev, argdev, and rootdev. 129 */ 130 vfsinit(); 131 if (bdevvp(swapdev, &swapdev_vp) || 132 bdevvp(argdev, &argdev_vp) || 133 bdevvp(rootdev, &rootvp)) 134 panic("can't setup bdevvp's"); 135 136 /* 137 * Setup credentials 138 */ 139 u.u_cred = crget(); 140 u.u_cred->cr_ngroups = 1; 141 142 startrtclock(); 143 #if defined(vax) 144 #include "kg.h" 145 #if NKG > 0 146 startkgclock(); 147 #endif 148 #endif 149 150 /* 151 * Initialize tables, protocols, and set up well-known inodes. 152 */ 153 mbinit(); 154 cinit(); 155 #ifdef SYSVSHM 156 shminit(); 157 #endif 158 #include "sl.h" 159 #if NSL > 0 160 slattach(); /* XXX */ 161 #endif 162 #include "loop.h" 163 #if NLOOP > 0 164 loattach(); /* XXX */ 165 #endif 166 /* 167 * Block reception of incoming packets 168 * until protocols have been initialized. 169 */ 170 s = splimp(); 171 ifinit(); 172 domaininit(); 173 splx(s); 174 pqinit(); 175 swapinit(); 176 #ifdef GPROF 177 kmstartup(); 178 #endif 179 180 /* kick off timeout driven events by calling first time */ 181 roundrobin(); 182 schedcpu(); 183 184 /* set up the root file system */ 185 if ((*mountroot)()) 186 panic("cannot mount root"); 187 /* 188 * Get vnode for '/'. 189 * Setup rootdir and u.u_cdir to point to it. 190 */ 191 if (VFS_ROOT(rootfs, &rootdir)) 192 panic("cannot find root vnode"); 193 u.u_cdir = rootdir; 194 VREF(u.u_cdir); 195 VOP_UNLOCK(rootdir); 196 u.u_rdir = NULL; 197 boottime = u.u_start = time; 198 199 enablertclock(); /* enable realtime clock interrupts */ 200 /* 201 * make init process 202 */ 203 204 siginit(&proc[0]); 205 if (newproc(0)) { 206 vm_offset_t addr = 0; 207 208 (void) vm_allocate(u.u_procp->p_map, 209 &addr, round_page(szicode), FALSE); 210 if (addr != 0) 211 panic("init: couldn't allocate at zero"); 212 213 /* need just enough stack to exec from */ 214 addr = trunc_page(VM_MAX_ADDRESS - PAGE_SIZE); 215 (void) vm_allocate(u.u_procp->p_map, &addr, PAGE_SIZE, FALSE); 216 u.u_maxsaddr = (caddr_t)addr; 217 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 218 /* 219 * Return goes to loc. 0 of user init 220 * code just copied out. 221 */ 222 return; 223 } 224 /* 225 * Start up pageout daemon (process 2). 226 */ 227 if (newproc(0)) { 228 proc[2].p_flag |= SLOAD|SSYS; 229 bcopy("pagedaemon", proc[2].p_comm, sizeof ("pagedaemon")); 230 vm_pageout(); 231 /*NOTREACHED*/ 232 } 233 234 /* 235 * enter scheduling loop 236 */ 237 sched(); 238 } 239 240 /* 241 * Initialize hash links for buffers. 242 */ 243 bhinit() 244 { 245 register int i; 246 register struct bufhd *bp; 247 248 for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++) 249 bp->b_forw = bp->b_back = (struct buf *)bp; 250 } 251 252 /* 253 * Initialize the buffer I/O system by freeing 254 * all buffers and setting all device buffer lists to empty. 255 */ 256 binit() 257 { 258 register struct buf *bp, *dp; 259 register int i; 260 int base, residual; 261 262 for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) { 263 dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp; 264 dp->b_flags = B_HEAD; 265 } 266 base = bufpages / nbuf; 267 residual = bufpages % nbuf; 268 for (i = 0; i < nbuf; i++) { 269 bp = &buf[i]; 270 bp->b_dev = NODEV; 271 bp->b_bcount = 0; 272 bp->b_rcred = NOCRED; 273 bp->b_wcred = NOCRED; 274 bp->b_dirtyoff = 0; 275 bp->b_dirtyend = 0; 276 bp->b_un.b_addr = buffers + i * MAXBSIZE; 277 if (i < residual) 278 bp->b_bufsize = (base + 1) * CLBYTES; 279 else 280 bp->b_bufsize = base * CLBYTES; 281 binshash(bp, &bfreelist[BQ_AGE]); 282 bp->b_flags = B_BUSY|B_INVAL; 283 brelse(bp); 284 } 285 } 286 287 /* 288 * Set up swap devices. 289 * Initialize linked list of free swap 290 * headers. These do not actually point 291 * to buffers, but rather to pages that 292 * are being swapped in and out. 293 */ 294 swapinit() 295 { 296 register int i; 297 register struct buf *sp = swbuf; 298 struct swdevt *swp; 299 int error; 300 301 /* 302 * Count swap devices, and adjust total swap space available. 303 * Some of this space will not be available until a swapon() 304 * system is issued, usually when the system goes multi-user. 305 */ 306 nswdev = 0; 307 nswap = 0; 308 for (swp = swdevt; swp->sw_dev; swp++) { 309 nswdev++; 310 if (swp->sw_nblks > nswap) 311 nswap = swp->sw_nblks; 312 } 313 if (nswdev == 0) 314 panic("swapinit"); 315 if (nswdev > 1) 316 nswap = ((nswap + dmmax - 1) / dmmax) * dmmax; 317 nswap *= nswdev; 318 if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp)) 319 panic("swapvp"); 320 if (error = swfree(0)) { 321 printf("swfree errno %d\n", error); /* XXX */ 322 panic("swapinit swfree 0"); 323 } 324 325 /* 326 * Now set up swap buffer headers. 327 */ 328 bswlist.av_forw = sp; 329 for (i=0; i<nswbuf-1; i++, sp++) 330 sp->av_forw = sp+1; 331 sp->av_forw = NULL; 332 } 333 334 /* 335 * Initialize clist by freeing all character blocks, then count 336 * number of character devices. (Once-only routine) 337 */ 338 cinit() 339 { 340 register int ccp; 341 register struct cblock *cp; 342 343 ccp = (int)cfree; 344 ccp = (ccp+CROUND) & ~CROUND; 345 for(cp=(struct cblock *)ccp; cp < &cfree[nclist-1]; cp++) { 346 cp->c_next = cfreelist; 347 cfreelist = cp; 348 cfreecount += CBSIZE; 349 } 350 } 351