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:  *	@(#)boot.c	3.0 (2.11BSD) 1996/5/9
   7:  */
   8: #include "../h/param.h"
   9: #include "../machine/seg.h"
  10: #include "../machine/koverlay.h"
  11: #include "../h/reboot.h"
  12: #include "saio.h"
  13: #include <a.out.h>
  14: 
  15: #undef  btoc            /* to save space */
  16: #define KB  * 1024L
  17: 
  18: #define KISD0   ((u_short *) 0172300)
  19: #define KISD3   ((u_short *) 0172306)
  20: #define KDSD0   ((u_short *) 0172320)
  21: #undef  KISA0
  22: #define KISA0   ((u_short *) 0172340)
  23: #define KISA3   ((u_short *) 0172346)
  24: #define KDSA0   ((u_short *) 0172360)
  25: 
  26: #define SEG_DATA    01
  27: #define SEG_TEXT    02
  28: #define SEG_OVLY    04
  29: 
  30: extern  caddr_t *bootcsr;   /* csr of boot controller */
  31: extern  int bootctlr;   /* boot controller number */
  32: extern  int bootopts;   /* boot options from previous incarnation */
  33: extern  int bootdev;    /* makedev(major,unit) booted from */
  34: extern  int checkword;  /* one's complements of bootopts */
  35: extern  int cputype;    /* 24, 40, 44, 45, 70, or 73 */
  36: extern  bool_t  ksep;       /* is kernel mode currently separated */
  37: extern  bool_t  sep_id;     /* does the cpu support separate I/D? */
  38: extern  int ndevsw;     /* number of devices in devsw[] */
  39: extern  char    ADJcsr[];   /* adjustments for ROM csr addresses */
  40: extern  char    *itoa();
  41: extern  char    *index();
  42: extern  struct  devsw devsw[];  /* device table */
  43: extern  struct  iob iob[];  /* I/O descriptor table */
  44: 
  45: char        module[] = "Boot"; /* this program's name (used by trap) */
  46: bool_t      overlaid = 0;
  47: u_short     pdrproto[16 + NOVL] = {0};
  48: struct exec exec;
  49: struct ovlhdr   ovlhdr;
  50: int     bootdebug;
  51: unsigned    btoc();
  52: 
  53: struct  loadmap {
  54:     int seg_type;
  55:     long    seg_len;
  56: };
  57: struct  loadtable {
  58:     short   lt_magic;
  59:     struct  loadmap *lt_map;
  60: };
  61: 
  62: struct  loadmap load407[] = {
  63:     SEG_DATA,   56 KB,
  64:     0,      0  KB
  65: };
  66: struct  loadmap load410[] = {
  67:     SEG_TEXT,   48 KB,
  68:     SEG_DATA,   56 KB,
  69:     0,      0  KB
  70: };
  71: struct  loadmap load411[] = {
  72:     SEG_DATA,   56 KB,
  73:     SEG_TEXT,   64 KB,
  74:     0,      0  KB
  75: };
  76: struct  loadmap load430[] = {
  77:     SEG_TEXT,   16 KB,          /* minumum, 8 KB + 1 */
  78:     SEG_OVLY,   8  KB,  /*  1 */
  79:     SEG_DATA,   24 KB,
  80:     SEG_OVLY,   8  KB,  /*  2 */
  81:     SEG_OVLY,   8  KB,  /*  3 */
  82:     SEG_OVLY,   8  KB,  /*  4 */
  83:     SEG_OVLY,   8  KB,  /*  5 */
  84:     SEG_OVLY,   8  KB,  /*  6 */
  85:     SEG_OVLY,   8  KB,  /*  7 */
  86:     SEG_OVLY,   8  KB,  /*  8 */
  87:     SEG_OVLY,   8  KB,  /*  9 */
  88:     SEG_OVLY,   8  KB,  /* 10 */
  89:     SEG_OVLY,   8  KB,  /* 11 */
  90:     SEG_OVLY,   8  KB,  /* 12 */
  91:     SEG_OVLY,   8  KB,  /* 13 */
  92:     SEG_OVLY,   8  KB,  /* 14 */
  93:     SEG_OVLY,   8  KB,  /* 15 */
  94:     0,      0  KB
  95: };
  96: struct  loadmap load431[] = {
  97:     SEG_DATA,   56 KB,          /* minumum, 48 KB + 1 */
  98:     SEG_TEXT,   56 KB,
  99:     SEG_OVLY,   8  KB,  /*  1 */
 100:     SEG_OVLY,   8  KB,  /*  2 */
 101:     SEG_OVLY,   8  KB,  /*  3 */
 102:     SEG_OVLY,   8  KB,  /*  4 */
 103:     SEG_OVLY,   8  KB,  /*  5 */
 104:     SEG_OVLY,   8  KB,  /*  6 */
 105:     SEG_OVLY,   8  KB,  /*  7 */
 106:     SEG_OVLY,   8  KB,  /*  8 */
 107:     SEG_OVLY,   8  KB,  /*  9 */
 108:     SEG_OVLY,   8  KB,  /* 10 */
 109:     SEG_OVLY,   8  KB,  /* 11 */
 110:     SEG_OVLY,   8  KB,  /* 12 */
 111:     SEG_OVLY,   8  KB,  /* 13 */
 112:     SEG_OVLY,   8  KB,  /* 14 */
 113:     SEG_OVLY,   8  KB,  /* 15 */
 114:     0,      0  KB
 115: };
 116: 
 117: struct  loadtable   loadtable[] = {
 118:     A_MAGIC1,   load407,
 119:     A_MAGIC2,   load410,
 120:     A_MAGIC3,   load411,
 121:     A_MAGIC5,   load430,
 122:     A_MAGIC6,   load431
 123: };
 124: 
 125: main()
 126: {
 127:     register int i, j, maj;
 128:     int retry = 0, unit, part;
 129:     caddr_t *adjcsr;
 130:     struct loadtable *setup();
 131:     struct iob *file;
 132:     char    *cp, *defname = "unix", line[64], defdev[64];
 133: 
 134:     maj = major(bootdev);
 135:     if (maj >= ndevsw)
 136:         _stop("bad major");     /* can't happen */
 137:     adjcsr = (caddr_t *)((short)bootcsr - ADJcsr[maj]);
 138: 
 139:     for (i = 0; devsw[maj].dv_csr != (caddr_t) -1; i++) {
 140:         if (adjcsr == devsw[maj].dv_csr[i])
 141:             break;
 142:         if (devsw[maj].dv_csr[i] == 0) {
 143:             devsw[maj].dv_csr[i] = adjcsr;
 144:             break;
 145:         }
 146:     }
 147: 
 148:     if (devsw[maj].dv_csr[i] == (caddr_t *) -1)
 149:         _stop("no free csr slots");
 150:     bootdev &= ~(3 << 6);
 151:     bootdev |= (i << 6);    /* controller # to bits 6&7 */
 152:     bootctlr = i;
 153:     unit = (minor(bootdev) >> 3) & 7;
 154:     part = minor(bootdev) & 7;
 155: 
 156:     printf("\n%d%s from %s(%d,%d,%d) at 0%o\n", cputype, module,
 157:         devsw[major(bootdev)].dv_name, bootctlr, unit, part, bootcsr);
 158: 
 159:     strcpy(defdev, devsw[major(bootdev)].dv_name);
 160:     strcat(defdev, "(");
 161:     strcat(defdev, itoa(bootctlr));
 162:     strcat(defdev, ",");
 163:     strcat(defdev, itoa(unit));
 164:     strcat(defdev, ",");
 165:     strcat(defdev, itoa(part));
 166:     strcat(defdev, ")");
 167: 
 168:     /*
 169: 	 * The machine language will have gotten the bootopts
 170: 	 * if we're an autoboot and will pass them along.
 171: 	 * If r2 (checkword) was the complement of bootopts,
 172: 	 * this is an automatic reboot, otherwise do it the hard way.
 173: 	 */
 174:     if (checkword != ~bootopts)
 175:         bootopts = RB_SINGLE | RB_ASKNAME;
 176:     j = -1;
 177:     do {
 178:         if (bootopts & RB_ASKNAME) {
 179: another:
 180:             printf(": ");
 181:             gets(line);
 182:             cp = line;
 183:             if  (*cp == '-')
 184:                 {
 185:                 dobootopts(cp, &bootopts);
 186:                 goto another;
 187:                 }
 188:         } else {
 189:             strcpy(line, defdev);
 190:             strcat(line, defname);
 191:             printf(": %s\n", line);
 192:         }
 193:         if (line[0] == '\0') {
 194:             strcpy(line, defdev);
 195:             strcat(line, defname);
 196:             printf(": %s\n", line);
 197:         }
 198: /*
 199:  * If a plain filename (/unix) is entered then prepend the default
 200:  * device, e.g. ra(0,1,0) to the filename.
 201: */
 202:         cp = index(line, ')');
 203:         if  (!cp)
 204:             {
 205:             bcopy(line, line + strlen(defdev), strlen(line) + 1);
 206:             bcopy(defdev, line, strlen(defdev));
 207:             }
 208:         j = -1;
 209:         if  (cp = index(line, ' '))
 210:             {
 211:             if  ((bootflags(cp, &bootopts, "bootfile")) == -1)
 212:                 {
 213:                 bootopts |= RB_ASKNAME;
 214:                 continue;
 215:                 }
 216:             *cp = '\0';
 217:             }
 218:         i = open(line, 0);
 219:         if (i >= 0) {
 220:             file = &iob[i - 3]; /* -3 for pseudo stdin/o/e */
 221:             j = checkunix(i, setup(i));
 222:             (void) close(i);
 223:         }
 224:         if (++retry > 2)
 225:             bootopts = RB_SINGLE | RB_ASKNAME;
 226:     } while (j < 0);
 227:     i = file->i_ino.i_dev;
 228:     bootdev = makedev(i,
 229:         ((file->i_ctlr << 6) | (file->i_unit << 3) | file->i_part));
 230:     bootcsr = devsw[i].dv_csr[file->i_ctlr];
 231:     bootcsr = (caddr_t *)((short)bootcsr + ADJcsr[i]);
 232:     printf("%s: bootdev=0%o bootcsr=0%o\n", module, bootdev, bootcsr);
 233: }
 234: 
 235: struct loadtable *
 236: setup(io)
 237:     register io;
 238: {
 239:     register i;
 240: 
 241:     exec.a_magic = getw(io);
 242:     exec.a_text = (unsigned) getw(io);
 243:     exec.a_data = (unsigned) getw(io);
 244:     exec.a_bss = (unsigned) getw(io);
 245: 
 246:     /*
 247: 	 * Space over the remainder of the exec header.  We do this
 248: 	 * instead of seeking because the input might be a tape which
 249: 	 * doesn't know how to seek.
 250: 	 */
 251:     getw(io); getw(io); getw(io); getw(io);
 252: 
 253:     /*
 254: 	 * If overlaid, get overlay header.
 255: 	 */
 256:     if (exec.a_magic == A_MAGIC5 || exec.a_magic == A_MAGIC6) {
 257:         overlaid++;
 258:         ovlhdr.max_ovl = getw(io);
 259:         for (i = 0; i < NOVL; i++)
 260:             ovlhdr.ov_siz[i] = (unsigned) getw(io);
 261:     }
 262:     for (i = 0; i < sizeof(loadtable) / sizeof(struct loadtable); i++)
 263:         if (loadtable[i].lt_magic == exec.a_magic)
 264:             return(&loadtable[i]);
 265:     printf("Bad magic # 0%o\n", exec.a_magic);
 266:     return((struct loadtable *) NULL);
 267: }
 268: 
 269: checkunix(io, lt)
 270:     struct loadtable *lt;
 271: {
 272:     char *segname, *toosmall = "Base too small, %dK min\n";
 273:     register int ovseg, segtype;
 274:     register unsigned seglen;
 275:     struct loadmap *lm = lt->lt_map;
 276: 
 277:     if (lt == (struct loadtable *) NULL)
 278:         return(-1);
 279: 
 280:     /*
 281: 	 * Check and set I & D space requirements.
 282: 	 */
 283:     if (exec.a_magic == A_MAGIC3 || exec.a_magic == A_MAGIC6)
 284:         if (!sep_id) {
 285:             printf("Can't load split I&D files\n");
 286:             return(-1);
 287:         } else
 288:             setsep();
 289:     else
 290:         if (sep_id)
 291:             setnosep();
 292: 
 293:     /*
 294: 	 * Check the sizes of each segment.
 295: 	 */
 296:     ovseg = 0;
 297:     while (segtype = lm->seg_type) {
 298:         switch (segtype) {
 299:             case SEG_TEXT:
 300:                 /*
 301: 				 * Round text size to nearest page.
 302: 				 */
 303:                 if (exec.a_magic == A_MAGIC2)
 304:                     seglen = ctob(stoc(ctos(btoc(exec.a_text))));
 305:                 else
 306:                     seglen = exec.a_text;
 307:                 segname = "Text";
 308:                 break;
 309: 
 310:             case SEG_DATA:
 311:                 seglen = exec.a_data + exec.a_bss;
 312:                 segname = "Data";
 313:                 if (exec.a_magic == A_MAGIC1)
 314:                     seglen += exec.a_text;
 315:                 else
 316:                     /*
 317: 					 * Force a complaint if the file
 318: 					 * won't fit.  It's here instead
 319: 					 * of in the SEG_TEXT case above
 320: 					 * because it's more likely to be
 321: 					 * a data overflow problem.
 322: 					 */
 323:                     if (exec.a_magic == A_MAGIC2)
 324:                         seglen += ctob(stoc(ctos(btoc(exec.a_text))));
 325:                 break;
 326: 
 327:             case SEG_OVLY:
 328:                 seglen = ovlhdr.ov_siz[ovseg];
 329:                 segname = "Overlay";
 330:                 ovseg++;
 331:                 break;
 332: 
 333:             default:
 334:                 /*
 335: 				 * This ``cannot happen.''
 336: 				 */
 337:                 printf("seg type botch: %d\n", segtype);
 338:                 return(-1);
 339:                 /*NOTREACHED*/
 340:         }
 341: 
 342:         seglen = ctob(btoc(seglen));
 343:         if (((long) seglen) > lm->seg_len) {
 344:             if (segtype == SEG_OVLY)
 345:                 printf("%s %d over by %D bytes", segname, ovseg, lm->seg_len -((long) seglen));
 346:             else
 347:                 printf("%s over by %D bytes", segname, lm->seg_len -((long) seglen));
 348:             return(-1);
 349:         }
 350:         if (segtype == SEG_TEXT)
 351:             switch (exec.a_magic) {
 352:             case A_MAGIC5:
 353:                 if (seglen <= 8 KB) {
 354:                 printf(toosmall, 8);
 355:                 return(-1);
 356:                 }
 357:                 break;
 358:             case A_MAGIC6:
 359:                 if (seglen <= 48 KB) {
 360:                 printf(toosmall, 48);
 361:                 return(-1);
 362:                 }
 363:                 break;
 364:             default:
 365:                 break;
 366:             }
 367:             lm++;
 368:     }
 369:     copyunix(io, lt);
 370:     setregs(lt);
 371:     return(0);
 372: }
 373: 
 374: copyunix(io, lt)
 375:     register io;
 376:     struct loadtable *lt;
 377: {
 378:     int i;
 379:     bool_t donedata = 0;
 380:     register int addr;
 381:     register unsigned seglen;
 382:     off_t segoff;
 383:     int segtype;
 384:     int nseg, phys, ovseg;
 385:     struct loadmap *lm = lt->lt_map;
 386: 
 387:     /*
 388: 	 * Load the segments and set up prototype PDRs.
 389: 	 */
 390:     nseg = 0;
 391:     phys = 0;
 392:     ovseg = 0;
 393:     lm = lt->lt_map;
 394:     while (segtype = lm++->seg_type) {
 395:         segoff = (off_t) N_TXTOFF(exec);
 396:         switch (segtype) {
 397:             case SEG_TEXT:
 398:                 seglen = exec.a_text;
 399:                 break;
 400: 
 401:             case SEG_DATA:
 402:                 seglen = exec.a_data;
 403:                 /*
 404: 				 * If this is a 0407 style object, the text
 405: 				 * and data are loaded together.
 406: 				 */
 407:                 if (exec.a_magic != A_MAGIC1) {
 408:                     segoff += (off_t) exec.a_text;
 409:                     if (overlaid)
 410:                         for (i = 0; i < NOVL; i++)
 411:                             segoff += (off_t) ovlhdr.ov_siz[i];
 412:                 } else
 413:                     seglen += exec.a_text;
 414:                 donedata++;
 415:                 break;
 416: 
 417:             case SEG_OVLY:
 418:                 seglen = ovlhdr.ov_siz[ovseg];
 419:                 segoff += (off_t) exec.a_text;
 420:                 for (i = 0; i < ovseg; i++)
 421:                     segoff += (off_t) ovlhdr.ov_siz[i];
 422:                 ovseg++;
 423:                 break;
 424:             default:
 425:                 printf("copyunix: bad seg type %d\n", segtype);
 426:                 seglen=0;
 427:                 break;
 428:         }
 429: 
 430:         if (!seglen)
 431:             continue;
 432:         setseg(phys);
 433: /*
 434:  * ARGH!  Despite (or in spite of) the earlier cautions against seeking and
 435:  * tape devices here is an 'lseek' that caused problems loading split I/D
 436:  * images from tape!
 437: */
 438:         if (exec.a_magic != A_MAGIC1)
 439:             (void) lseek(io, segoff, 0);
 440:         for (addr = 0; addr < seglen; addr += 2)
 441:             mtpi(getw(io), addr);
 442: 
 443:         if (segtype == SEG_DATA) {
 444:             clrseg(addr, exec.a_bss);
 445:             seglen += exec.a_bss;
 446:         }
 447: 
 448:         pdrproto[nseg++] = btoc(seglen);
 449:         if (!donedata)
 450:             seglen = ctob(stoc(ctos(btoc(seglen))));
 451:         phys += btoc(seglen);
 452:     }
 453: }
 454: 
 455: /*
 456:  * Set the real segmentation registers.
 457:  */
 458: setregs(lt)
 459:     struct loadtable *lt;
 460: {
 461:     register i;
 462:     register u_short *par_base, *pdr_base;
 463:     bool_t donedata = 0;
 464:     int phys, segtype;
 465:     int nseg, ntextpgs, novlypgs, npages, pagelen;
 466:     struct loadmap *lm = lt->lt_map;
 467: 
 468:     nseg = 0;
 469:     phys = 0;
 470:     ntextpgs = 0;
 471:     novlypgs = 0;
 472: 
 473:     setseg(0);
 474:     if (exec.a_magic == A_MAGIC1)
 475:         return;
 476: 
 477:     /*
 478: 	 * First deny access to all except I/O page.
 479: 	 */
 480:     par_base = KISA0;
 481:     pdr_base = KISD0;
 482:     for (i = 0; i <(ksep ?  8 : 7); i++) {
 483:         *par_base++ = 0;
 484:         *pdr_base++ = NOACC;
 485:     }
 486:     if (ksep) {
 487:         par_base = KDSA0;
 488:         pdr_base = KDSD0;
 489:         for (i = 0; i < 7; i++) {
 490:             *par_base++ = 0;
 491:             *pdr_base++ = NOACC;
 492:         }
 493:     }
 494:     if (overlaid) {
 495:         /*
 496: 		 * We must write the prototype overlay register table.
 497: 		 * N.B.:  we assume that the table lies in the first 8k
 498: 		 * of kernel virtual space, and the appropriate page lies
 499: 		 * at physical 0.
 500: 		 */
 501:         if (ksep)
 502:             *KDSD0 = ((128 -1) << 8) | RW;
 503:         else
 504:             *KISD0 = ((128 -1) << 8) | RW;
 505:         par_base = &(((u_short *) OVLY_TABLE_BASE)[0]);
 506:         pdr_base = &(((u_short *) OVLY_TABLE_BASE)[1 + NOVL]);
 507:         for (i = 0; i < NOVL; i++) {
 508:             mtpd(0, par_base++);
 509:             mtpd(NOACC, pdr_base++);
 510:         }
 511:     }
 512: 
 513:     /*
 514: 	 * Now set all registers which should be nonzero.
 515: 	 */
 516:     lm = lt->lt_map;
 517:     while (segtype = lm++->seg_type) {
 518:         if (!(npages = ctos(pdrproto[nseg])))
 519:             continue;
 520: 
 521:         switch (segtype) {
 522:             case SEG_TEXT:
 523:                 /*
 524: 				 * Text always starts at KI0;
 525: 				 */
 526:                 par_base = KISA0;
 527:                 pdr_base = KISD0;
 528:                 ntextpgs += npages;
 529:                 break;
 530: 
 531:             case SEG_DATA:
 532:                 if (overlaid)
 533:                     if (ksep) {
 534:                         par_base = I_DATA_PAR_BASE;
 535:                         pdr_base = I_DATA_PDR_BASE;
 536:                     } else {
 537:                         par_base = N_DATA_PAR_BASE;
 538:                         pdr_base = N_DATA_PDR_BASE;
 539:                     }
 540:                 else
 541:                     if (ksep) {
 542:                         par_base = KDSA0;
 543:                         pdr_base = KDSD0;
 544:                     } else {
 545:                         par_base = &KISA0[ntextpgs + novlypgs];
 546:                         pdr_base = &KISD0[ntextpgs + novlypgs];
 547:                     }
 548:                 donedata++;
 549:                 break;
 550: 
 551:             case SEG_OVLY:
 552:                 par_base = &(((u_short *) OVLY_TABLE_BASE)[1 + novlypgs]);
 553:                 pdr_base = &(((u_short *) OVLY_TABLE_BASE)[1 + NOVL + 1 + novlypgs]);
 554:                 novlypgs += npages;
 555:                 break;
 556:         }
 557: 
 558:         for (i = 0; i < npages; i++) {
 559:             pagelen = MIN(btoc((int)(8 KB)), pdrproto[nseg]);
 560:             if (segtype == SEG_OVLY) {
 561:                 mtpd(phys, par_base);
 562:                 mtpd(((pagelen - 1) << 8) | RO, pdr_base);
 563:             } else {
 564:                 *par_base = phys;
 565:                 if (segtype == SEG_TEXT)
 566:                     if (ksep)
 567:                         *pdr_base = ((pagelen - 1) << 8) | RO;
 568:                     else
 569:                         /*
 570: 						 * Nonseparate kernels will
 571: 						 * write into text page 0
 572: 						 * when first booted.
 573: 						 */
 574:                         if (i == 0)
 575:                             *pdr_base = ((pagelen - 1) << 8) | RW;
 576:                         else
 577:                             *pdr_base = ((pagelen - 1) << 8) | RO;
 578:                 else
 579:                     *pdr_base = ((pagelen - 1) << 8) | RW;
 580:             }
 581:             par_base++, pdr_base++;
 582:             if (donedata)
 583:                 phys += pagelen;
 584:             else
 585:                 phys += stoc(ctos(pagelen));
 586:             pdrproto[nseg] -= pagelen;
 587:         }
 588:         nseg++;
 589:     }
 590: 
 591:     /*
 592: 	 * Phys now contains the address of the start of
 593: 	 * free memory.  We set K[ID]6 now or systrap to
 594: 	 * kernel mode will clobber text at 0140000.
 595: 	 */
 596:     if (ksep) {
 597:         KDSA0[6] = phys;
 598:         KDSD0[6] = (stoc(1) - 1) << 8 | RW;
 599:     } else {
 600:         KISA0[6] = phys;
 601:         KISD0[6] = (stoc(1) - 1) << 8 | RW;
 602:     }
 603:     if (overlaid)
 604:         mtpd(phys, &(((u_short *) OVLY_TABLE_BASE)[1 + NOVL + 1 + NOVL]));
 605: }
 606: 
 607: unsigned
 608: btoc(nclicks)
 609:     register unsigned nclicks;
 610: {
 611:     return((unsigned)(((((long) nclicks) + ((long) 63)) >> 6)));
 612: }
 613: 
 614: /*
 615:  * Couldn't use getopt(3) for a couple reasons:  1) because that would end up
 616:  * dragging in way too much of libc.a, and 2) the code to build argc
 617:  * and argv would be almost as large as the parsing routines themselves.
 618: */
 619: 
 620: char *
 621: arg(cp)
 622:     register char *cp;
 623:     {
 624: 
 625:     if  ((cp = index(cp, ' ')) == NULL)
 626:         return(NULL);
 627:     while   (*cp == ' ' || *cp == '\t')
 628:         cp++;
 629:     if  (*cp == '\0')
 630:         return(NULL);
 631:     return(cp);
 632:     }
 633: 
 634: /*
 635:  * Flags to boot may be present in two places.  1) At the ': ' prompt enter
 636:  * a line starting with "-bootflags".  2) After the filename.  For example,
 637:  * to turn on the autoconfig debug flag:
 638:  *
 639:  * : -bootflags -D
 640:  *
 641:  * To force the kernel to use the compiled in root device (which also affects
 642:  * swapdev, pipedev and possibly dumpdev):
 643:  *
 644:  * : -bootflags -R
 645:  *
 646:  * To specify flags on the filename line place the options after the filename:
 647:  *
 648:  * : ra(0,0)unix -D -s
 649:  *
 650:  * will cause the kernel to use the compiled in root device (rather than auto
 651:  * matically switching to the load device) and enter single user mode.
 652:  *
 653:  * Bootflags may also be specified as a decimal number (you will need the
 654:  * sys/reboot.h file to look up the RB_* flags in).  Turning all bootflags off
 655:  * is the special case:
 656:  *
 657:  * : -bootflags 0
 658:  *
 659:  * There is a general purpose 'debug' flag word ("bootdebug") which can be
 660:  * set to any arbitrary 16 bit value.  This can be used when debugging a
 661:  * driver for example.
 662:  *
 663:  * : -bootdebug 16
 664: */
 665: 
 666: #define BOOTFLAGS   "-bootflags"
 667: #define BOOTDEBUG   "-bootdebug"
 668: 
 669: dobootopts(cp, opt)
 670:     register char *cp;
 671:     int *opt;
 672:     {
 673:     char    *bflags = BOOTFLAGS;
 674:     char    *bdebug = BOOTDEBUG;
 675: 
 676:     if  (strncmp(cp, bdebug, sizeof (BOOTDEBUG) - 1) == 0)
 677:         {
 678:         if  (cp = arg(cp))
 679:             bootdebug = atoi(cp);
 680:         else
 681:             printf("%s = %u\n", bdebug, bootdebug);
 682:         return(0);
 683:         }
 684:     if  (strncmp(cp, bflags, sizeof (BOOTFLAGS) - 1) == 0)
 685:         {
 686:         if  (cp = arg(cp))
 687:             (void) bootflags(cp, &bootopts, bflags);
 688:         else
 689:             printf("%s = %u\n", bflags, bootopts);
 690:         return(0);
 691:         }
 692:     printf("bad cmd: %s\n", cp);
 693:     return(0);
 694:     }
 695: 
 696: bootflags(cp, pflags, tag)
 697:     register char *cp;
 698:     int *pflags;
 699:     char *tag;
 700:     {
 701:     int first = 1;
 702:     int flags = 0;
 703: 
 704:     while   (*cp)
 705:         {
 706:         while   (*cp == ' ')
 707:             cp++;
 708:         if  (*cp == '\0')
 709:             break;
 710:         if  (*cp == '-')
 711:             {
 712:             first = 0;
 713:             while   (*++cp)
 714:                 switch  (*cp)
 715:                     {
 716:                     case    ' ':
 717:                         goto nextarg;
 718:                     case    'a':
 719:                         flags |= RB_ASKNAME;
 720:                         break;
 721:                     case    'D':
 722:                         flags |= RB_AUTODEBUG;
 723:                         break;
 724:                     case    'r':
 725:                         flags |= RB_RDONLY;
 726:                         break;
 727:                     case    'R':
 728:                         flags |= RB_DFLTROOT;
 729:                         break;
 730:                     case    's':
 731:                         flags |= RB_SINGLE;
 732:                         break;
 733:                     default:
 734:                         goto usage;
 735:                     }
 736:                 continue;
 737:             }
 738:         if  (first && *cp >= '0' && *cp <= '9')
 739:             {
 740:             *pflags = atoi(cp);
 741:             return(0);
 742:             }
 743:         goto usage;
 744: 
 745: nextarg:    ;
 746:         }
 747:     if  (first == 0)
 748:         *pflags = flags;
 749:     return(0);
 750: usage:
 751:     printf("usage: %s [ -aDrRs ]\n", tag);
 752:     return(-1);
 753:     }

Defined functions

arg defined in line 620; used 2 times
bootflags defined in line 696; used 2 times
btoc defined in line 607; never used
checkunix defined in line 269; used 1 times
copyunix defined in line 374; used 1 times
dobootopts defined in line 669; used 1 times
main defined in line 125; never used
setregs defined in line 458; used 1 times
setup defined in line 235; used 2 times

Defined variables

bootdebug defined in line 50; used 2 times
exec defined in line 48; used 31 times
load407 defined in line 62; used 1 times
load410 defined in line 66; used 1 times
load411 defined in line 71; used 1 times
load430 defined in line 76; used 1 times
load431 defined in line 96; used 1 times
loadtable defined in line 117; used 3 times
module defined in line 45; used 2 times
overlaid defined in line 46; used 5 times
ovlhdr defined in line 49; used 6 times
pdrproto defined in line 47; used 4 times

Defined struct's

loadmap defined in line 53; used 18 times
loadtable defined in line 57; used 18 times

Defined macros

BOOTDEBUG defined in line 667; used 2 times
BOOTFLAGS defined in line 666; used 2 times
KB defined in line 16; used 47 times
KDSA0 defined in line 24; used 3 times
KDSD0 defined in line 20; used 4 times
KISA0 defined in line 22; used 5 times
KISA3 defined in line 23; never used
KISD0 defined in line 18; used 5 times
KISD3 defined in line 19; never used
SEG_DATA defined in line 26; used 6 times
SEG_OVLY defined in line 28; used 32 times
SEG_TEXT defined in line 27; used 6 times
Last modified: 1996-05-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6851
Valid CSS Valid XHTML 1.0 Strict