1: /*
   2:  * Copyright (c) 1986 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	2.5 (2.11BSD GTE) 1997/9/26
   7:  */
   8: 
   9: #include "param.h"
  10: #include "../machine/seg.h"
  11: 
  12: #include "user.h"
  13: #include "fs.h"
  14: #include "mount.h"
  15: #include "map.h"
  16: #include "proc.h"
  17: #include "ioctl.h"
  18: #include "inode.h"
  19: #include "conf.h"
  20: #include "buf.h"
  21: #include "fcntl.h"
  22: #include "vm.h"
  23: #include "clist.h"
  24: #include "uba.h"
  25: #include "reboot.h"
  26: #include "systm.h"
  27: #include "kernel.h"
  28: #include "namei.h"
  29: #include "disklabel.h"
  30: #include "stat.h"
  31: #ifdef QUOTA
  32: #include "quota.h"
  33: #endif
  34: 
  35: int netoff = 1;
  36: int cmask = CMASK;
  37: int securelevel;
  38: 
  39: extern  size_t physmem;
  40: extern  struct  mapent _coremap[];
  41: 
  42: /*
  43:  * Initialization code.
  44:  * Called from cold start routine as
  45:  * soon as a stack and segmentation
  46:  * have been established.
  47:  * Functions:
  48:  *	clear and free user core
  49:  *	turn on clock
  50:  *	hand craft 0th process
  51:  *	call all initialization routines
  52:  *	fork - process 0 to schedule
  53:  *	     - process 1 execute bootstrap
  54:  */
  55: main()
  56: {
  57:     extern dev_t bootdev;
  58:     extern caddr_t bootcsr;
  59:     register struct proc *p;
  60:     register int i;
  61:     register struct fs *fs;
  62:     time_t  toytime, toyclk();
  63:     daddr_t swsize;
  64:     int (*ioctl)();
  65:     struct  partinfo dpart;
  66: 
  67:     startup();
  68: 
  69:     /*
  70: 	 * set up system process 0 (swapper)
  71: 	 */
  72:     p = &proc[0];
  73:     p->p_addr = *ka6;
  74:     p->p_stat = SRUN;
  75:     p->p_flag |= SLOAD|SSYS;
  76:     p->p_nice = NZERO;
  77: 
  78:     u.u_procp = p;          /* init user structure */
  79:     u.u_ap = u.u_arg;
  80:     u.u_cmask = cmask;
  81:     u.u_lastfile = -1;
  82:     for (i = 1; i < NGROUPS; i++)
  83:         u.u_groups[i] = NOGROUP;
  84:     for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++)
  85:         u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max =
  86:             RLIM_INFINITY;
  87:     bcopy("root", u.u_login, sizeof ("root"));
  88: 
  89:     /* Initialize signal state for process 0 */
  90:     siginit(p);
  91: 
  92:     /*
  93: 	 * Initialize tables, protocols, and set up well-known inodes.
  94: 	 */
  95:     cinit();
  96:     pqinit();
  97:     xinit();
  98:     ihinit();
  99:     bhinit();
 100:     binit();
 101:     ubinit();
 102: #ifdef QUOTA
 103:     QUOTAMAP();
 104:     qtinit();
 105:     u.u_quota = getquota(0, 0, Q_NDQ);
 106:     QUOTAUNMAP();
 107: #endif
 108:     nchinit();
 109:     clkstart();
 110: 
 111: /*
 112:  * If the kernel is configured for the boot/load device AND the use of the
 113:  * compiled in 'bootdev' has not been overridden (by turning on RB_DFLTROOT,
 114:  * see conf/boot.c for details) THEN switch 'rootdev', 'swapdev' and 'pipedev'
 115:  * over to the boot/load device.  Set 'pipedev' to be 'rootdev'.
 116:  *
 117:  * The &077 removes the controller number (bits 6 and 7) - those bits are
 118:  * passed thru from /boot but would only greatly confuse the rest of the kernel.
 119: */
 120:     i = major(bootdev);
 121:     if  ((bdevsw[i].d_strategy != nodev) && !(boothowto & RB_DFLTROOT))
 122:         {
 123:         rootdev = makedev(i, minor(bootdev) & 077);
 124:         swapdev = rootdev | 1;  /* partition 'b' */
 125:         pipedev = rootdev;
 126: /*
 127:  * We check that the dump device is the same as the boot device.  If it is
 128:  * different then it is likely that crashdumps go to a tape device rather than
 129:  * the swap area.  In that case do not switch the dump device.
 130: */
 131:         if  ((dumpdev != NODEV) && major(dumpdev) == i)
 132:             dumpdev = swapdev;
 133:         }
 134: 
 135: /*
 136:  * Need to attach the root device.  The CSR is passed thru because this
 137:  * may be a 2nd or 3rd controller rather than the 1st.  NOTE: This poses
 138:  * a big problem if 'swapdev' is not on the same controller as 'rootdev'
 139:  * _or_ if 'swapdev' itself is on a 2nd or 3rd controller.  Short of moving
 140:  * autconfigure back in to the kernel it is not known what can be done about
 141:  * this.
 142:  *
 143:  * One solution (for now) is to call swapdev's attach routine with a zero
 144:  * address.  The MSCP driver treats the 0 as a signal to perform the
 145:  * old (fixed address) attach.  Drivers (all the rest at this point) which
 146:  * do not support alternate controller booting always attach the first
 147:  * (primary) CSR and do not expect an argument to be passed.
 148: */
 149:     (void)(*bdevsw[major(bootdev)].d_root)(bootcsr);
 150:     (void)(*bdevsw[major(swapdev)].d_root)((caddr_t) 0);    /* XXX */
 151: 
 152: /*
 153:  * Now we find out how much swap space is available.  Since 'nswap' is
 154:  * a "u_int" we have to restrict the amount of swap to 65535 sectors (~32mb).
 155:  * Considering that 4mb is the maximum physical memory capacity of a pdp-11
 156:  * 32mb swap should be enough ;-)
 157:  *
 158:  * The initialization of the swap map was moved here from machdep2.c because
 159:  * 'nswap' was no longer statically defined and this is where the swap dev
 160:  * is opened/initialized.
 161:  *
 162:  * Also, we toss away/ignore .5kb (1 sector) of swap space (because a 0 value
 163:  * can not be placed in a resource map).
 164:  *
 165:  * 'swplo' was a hack which has _finally_ gone away!  It was never anything
 166:  * but 0 and caused a number of double word adds in the kernel.
 167: */
 168:     (*bdevsw[major(swapdev)].d_open)(swapdev, FREAD|FWRITE, S_IFBLK);
 169:     swsize = (*bdevsw[major(swapdev)].d_psize)(swapdev);
 170:     if  (swsize <= 0)
 171:         panic("swsiz");     /* don't want to panic, but what ? */
 172: 
 173: /*
 174:  * Next we make sure that we do not swap on a partition unless it is of
 175:  * type FS_SWAP.  If the driver does not have an ioctl entry point or if
 176:  * retrieving the partition information fails then the driver does not
 177:  * support labels and we proceed normally, otherwise the partition must be
 178:  * a swap partition (so that we do not swap on top of a filesystem by mistake).
 179: */
 180:     ioctl = cdevsw[blktochr(swapdev)].d_ioctl;
 181:     if  (ioctl && !(*ioctl)(swapdev, DIOCGPART, (caddr_t)&dpart, FREAD))
 182:         {
 183:         if  (dpart.part->p_fstype != FS_SWAP)
 184:             panic("swtyp");
 185:         }
 186:     if  (swsize > (daddr_t)65535)
 187:         swsize = 65535;
 188:     nswap = swsize;
 189:     mfree(swapmap, --nswap, 1);
 190: 
 191:     fs = mountfs(rootdev, boothowto & RB_RDONLY ? MNT_RDONLY : 0,
 192:             (struct inode *)0);
 193:     if (!fs)
 194:         panic("iinit");
 195:     mount[0].m_inodp = (struct inode *)1;   /* XXX */
 196:     mount_updname(fs, "/", "root", 1, 4);
 197:     time.tv_sec = fs->fs_time;
 198:     if  (toytime = toyclk())
 199:         time.tv_sec = toytime;
 200:     boottime = time;
 201: 
 202: /* kick off timeout driven events by calling first time */
 203:     schedcpu();
 204: 
 205: /* set up the root file system */
 206:     rootdir = iget(rootdev, &mount[0].m_filsys, (ino_t)ROOTINO);
 207:     iunlock(rootdir);
 208:     u.u_cdir = iget(rootdev, &mount[0].m_filsys, (ino_t)ROOTINO);
 209:     iunlock(u.u_cdir);
 210:     u.u_rdir = NULL;
 211: 
 212: #ifdef INET
 213:     if (netoff = netinit())
 214:         printf("netinit failed\n");
 215:     else
 216:         {
 217:         NETSETHZ();
 218:         NETSTART();
 219:         }
 220: #endif
 221: 
 222: /*
 223:  * This came from pdp/machdep2.c because the memory available statements
 224:  * were being made _before_ memory for the networking code was allocated.
 225:  * A side effect of moving this code is that network "attach" and MSCP
 226:  * "online" messages can appear before the memory sizes.  The (currently
 227:  * safe) assumption is made that no 'free' calls are made so that the
 228:  * size in the first entry of the core map is correct.
 229: */
 230:     printf("\nphys mem  = %D\n", ctob((long)physmem));
 231:     printf("avail mem = %D\n", ctob((long)_coremap[0].m_size));
 232:     maxmem = MAXMEM;
 233:     printf("user mem  = %D\n", ctob((long)MAXMEM));
 234: #if NRAM > 0
 235:     printf("ram disk  = %D\n", ctob((long)ramsize));
 236: #endif
 237:     printf("\n");
 238: 
 239:     /*
 240: 	 * make init process
 241: 	 */
 242:     if (newproc(0)) {
 243:         expand((int)btoc(szicode), S_DATA);
 244:         expand((int)1, S_STACK);    /* one click of stack */
 245:         estabur((u_int)0, (u_int)btoc(szicode), (u_int)1, 0, RO);
 246:         copyout((caddr_t)icode, (caddr_t)0, szicode);
 247:         /*
 248: 		 * return goes to location 0 of user init code
 249: 		 * just copied out.
 250: 		 */
 251:         return;
 252:     }
 253:     else
 254:         sched();
 255: }
 256: 
 257: /*
 258:  * Initialize hash links for buffers.
 259:  */
 260: static
 261: bhinit()
 262: {
 263:     register int i;
 264:     register struct bufhd *bp;
 265: 
 266:     for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++)
 267:         bp->b_forw = bp->b_back = (struct buf *)bp;
 268: }
 269: 
 270: memaddr bpaddr;     /* physical click-address of buffers */
 271: /*
 272:  * Initialize the buffer I/O system by freeing
 273:  * all buffers and setting all device buffer lists to empty.
 274:  */
 275: static
 276: binit()
 277: {
 278:     register struct buf *bp;
 279:     register int i;
 280:     long paddr;
 281: 
 282:     for (bp = bfreelist; bp < &bfreelist[BQUEUES]; bp++)
 283:         bp->b_forw = bp->b_back = bp->av_forw = bp->av_back = bp;
 284:     paddr = ((long)bpaddr) << 6;
 285:     for (i = 0; i < nbuf; i++, paddr += MAXBSIZE) {
 286:         bp = &buf[i];
 287:         bp->b_dev = NODEV;
 288:         bp->b_bcount = 0;
 289:         bp->b_un.b_addr = (caddr_t)loint(paddr);
 290:         bp->b_xmem = hiint(paddr);
 291:         binshash(bp, &bfreelist[BQ_AGE]);
 292:         bp->b_flags = B_BUSY|B_INVAL;
 293:         brelse(bp);
 294:     }
 295: }
 296: 
 297: /*
 298:  * Initialize clist by freeing all character blocks, then count
 299:  * number of character devices. (Once-only routine)
 300:  */
 301: static
 302: cinit()
 303: {
 304:     register int ccp;
 305:     register struct cblock *cp;
 306: 
 307:     ccp = (int)cfree;
 308: #ifdef UCB_CLIST
 309:     mapseg5(clststrt, clstdesc);    /* don't save, we know it's normal */
 310: #else
 311:     ccp = (ccp + CROUND) & ~CROUND;
 312: #endif
 313:     for (cp = (struct cblock *)ccp; cp <= &cfree[nclist - 1]; cp++) {
 314:         cp->c_next = cfreelist;
 315:         cfreelist = cp;
 316:         cfreecount += CBSIZE;
 317:     }
 318: #ifdef UCB_CLIST
 319:     normalseg5();
 320: #endif
 321: }
 322: 
 323: #ifdef INET
 324: memaddr netdata;        /* click address of start of net data */
 325: 
 326: /*
 327:  * We are called here after all the other init routines (clist, inode,
 328:  * unibusmap, etc...) have been called.  Open the
 329:  * file NETNIX and read the a.out header, based on that go allocate
 330:  * memory and read the text+data into the memory.  Set up supervisor page
 331:  * registers, SDSA6 and SDSA7 have already been set up in mch_start.s.
 332:  */
 333: 
 334: static char NETNIX[] = "/netnix";
 335: 
 336: static
 337: netinit()
 338: {
 339:     register u_short *ap, *dp;
 340:     register int i;
 341:     struct exec ex;
 342:     struct inode *ip;
 343:     memaddr nettext;
 344:     long lsize;
 345:     off_t   off;
 346:     int initdata, netdsize, nettsize, ret, err, resid;
 347:     char oneclick[ctob(1)];
 348:     struct  nameidata nd;
 349:     register struct nameidata *ndp = &nd;
 350: 
 351:     ret = 1;
 352:     NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, NETNIX);
 353:     if (!(ip = namei(ndp))) {
 354:         printf("%s not found\n", NETNIX);
 355:         goto leave;
 356:     }
 357:     if ((ip->i_mode & IFMT) != IFREG || !ip->i_size) {
 358:         printf("%s bad inode\n", NETNIX);
 359:         goto leave;
 360:     }
 361:     err = rdwri(UIO_READ, ip, &ex, sizeof (ex), (off_t)0, UIO_SYSSPACE,
 362:             IO_UNIT, &resid);
 363:     if (err || resid) {
 364:         printf("%s header %d\n", NETNIX, ret);
 365:         goto leave;
 366:     }
 367:     if (ex.a_magic != A_MAGIC3) {
 368:         printf("%s bad magic %o\n", NETNIX, ex.a_magic);
 369:         goto leave;
 370:     }
 371:     lsize = (long)ex.a_data + (long)ex.a_bss;
 372:     if (lsize > 48L * 1024L) {
 373:         printf("%s 2big %ld\n", NETNIX, lsize);
 374:         goto leave;
 375:     }
 376:     nettsize = btoc(ex.a_text);
 377:     nettext = (memaddr)malloc(coremap, nettsize);
 378:     netdsize = btoc(ex.a_data + ex.a_bss);
 379:     netdata = (memaddr)malloc(coremap, netdsize);
 380:     initdata = ex.a_data >> 6;
 381:     off = sizeof (ex);
 382:     for (i = 0; i < nettsize; i++) {
 383:         err = rdwri(UIO_READ, ip, oneclick, ctob(1), off, UIO_SYSSPACE,
 384:                 IO_UNIT, &resid);
 385:         if (err || resid)
 386:             goto release;
 387:         mapseg5(nettext + i, 077406);
 388:         bcopy(oneclick, SEG5, ctob(1));
 389:         off += ctob(1);
 390:         normalseg5();
 391:     }
 392:     for (i = 0; i < initdata; i++) {
 393:         err = rdwri(UIO_READ, ip, oneclick, ctob(1), off, UIO_SYSSPACE,
 394:                 IO_UNIT, &resid);
 395:         if (err || resid)
 396:             goto release;
 397:         mapseg5(netdata + i, 077406);
 398:         bcopy(oneclick, SEG5, ctob(1));
 399:         normalseg5();
 400:         off += ctob(1);
 401:     }
 402:     if (ex.a_data & 077) {
 403:         err = rdwri(UIO_READ, ip, oneclick, ex.a_data & 077, off,
 404:                 UIO_SYSSPACE, IO_UNIT, &resid);
 405:         if (err || resid) {
 406: release:        printf("%s err %d\n", NETNIX, err);
 407:             mfree(coremap, nettsize, nettext);
 408:             mfree(coremap, netdsize, netdata);
 409:             nettsize = netdsize = 0;
 410:             netdata = nettext = 0;
 411:             goto leave;
 412:         }
 413:         mapseg5(netdata + i, 077406);   /* i is set from above loop */
 414:         bcopy(oneclick, SEG5, ex.a_data & 077);
 415:         normalseg5();
 416:     }
 417:     for (i = 0, ap = SISA0, dp = SISD0; i < nettsize; i += stoc(1)) {
 418:         *ap++ = nettext + i;
 419:         *dp++ = ((stoc(1) - 1) << 8) | RO;
 420:     }
 421:     /* might have over run the length on the last one, patch it now */
 422:     if (i > nettsize)
 423:         *--dp -= ((i - nettsize) << 8);
 424:     for (i = 0, ap = SDSA0, dp = SDSD0; i < netdsize; i += stoc(1)) {
 425:         *ap++ = netdata + i;
 426:         *dp++ = ((stoc(1) - 1) << 8) | RW;
 427:     }
 428:     if (i > netdsize)
 429:         *--dp -= ((i - netdsize) << 8);
 430:     ret = 0;
 431: leave:  if (ip)
 432:         iput(ip);
 433:     u.u_error = 0;
 434:     return(ret);
 435: }
 436: #endif

Defined functions

bhinit defined in line 260; used 1 times
  • in line 99
binit defined in line 275; used 1 times
cinit defined in line 301; used 1 times
  • in line 95
main defined in line 55; never used
netinit defined in line 336; used 1 times

Defined variables

NETNIX defined in line 334; used 7 times
bpaddr defined in line 270; used 1 times
cmask defined in line 36; used 1 times
  • in line 80
netdata defined in line 324; used 6 times
netoff defined in line 35; used 16 times
Last modified: 1997-09-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4606
Valid CSS Valid XHTML 1.0 Strict