# 2.11BSD#431 - /usr/src/sys/pdpstand/boot.c

##### Functions

    arg               X
    bootflags         X
    btoc              X
    checkunix         X
    copyunix          X
    dobootopts        X
    main              X
    setregs           X
    setup             X

##### Variables

    bootdebug         X
    exec              X
    load407           X
    load410           X
    load411           X
    load430           X
    load431           X
    loadtable         X
    module            X
    overlaid          X
    ovlhdr            X
    pdrproto          X

##### Macros

    BOOTDEBUG         X
    BOOTFLAGS         X
    KB                X
    KDSA0             X
    KDSD0             X
    KISA0             X
    KISA3             X
    KISD0             X
    KISD3             X
    SEG_DATA          X
    SEG_OVLY          X
    SEG_TEXT          X

##### struct's

    loadmap           X
    loadtable         X

       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

- in line 678, 686

bootflags defined in line 696; used 2 times

- in line 211, 687

btoc defined in line 607; never used
checkunix defined in line 269; used 1 times

- in line 221

copyunix defined in line 374; used 1 times

- in line 369

dobootopts defined in line 669; used 1 times

- in line 185

main defined in line 125; never used
setregs defined in line 458; used 1 times

- in line 370

setup defined in line 235; used 2 times

- in line 130, 221

#### Defined variables

bootdebug defined in line 50; used 2 times

- in line 679-681(2)

exec defined in line 48; used 31 times

- in line 241-244(4), 256(2), 263-265(2), 283(2), 303-314(7), 323-324(2), 351, 395-413(6), 419, 438, 444-445(2), 474

load407 defined in line 62; used 1 times

- in line 118

load410 defined in line 66; used 1 times

- in line 119

load411 defined in line 71; used 1 times

- in line 120

load430 defined in line 76; used 1 times

- in line 121

load431 defined in line 96; used 1 times

- in line 122

loadtable defined in line 117; used 3 times

- in line 262-264(3)

module defined in line 45; used 2 times

- in line 156, 232

overlaid defined in line 46; used 5 times

- in line 257, 409, 494, 532, 603

ovlhdr defined in line 49; used 6 times

- in line 258-260(2), 328, 411, 418-421(2)

pdrproto defined in line 47; used 4 times

- in line 448, 518, 559, 586

#### Defined struct's

loadmap defined in line 53; used 18 times

- in line 59-76(10), 96(2), 275(2), 385(2), 466(2)

loadtable defined in line 57; used 18 times

- in line 117(2), 130(2), 235(2), 262-270(6), 277(2), 376(2), 459(2)

#### Defined macros

BOOTDEBUG defined in line 667; used 2 times

- in line 674-676(2)

BOOTFLAGS defined in line 666; used 2 times

- in line 673, 684

KB defined in line 16; used 47 times

- in line 63-114(44), 353, 359, 559

KDSA0 defined in line 24; used 3 times

- in line 487, 542, 597

KDSD0 defined in line 20; used 4 times

- in line 488, 502, 543, 598

KISA0 defined in line 22; used 5 times

- in line 21, 480, 526, 545, 600

KISA3 defined in line 23; never used
KISD0 defined in line 18; used 5 times

- in line 481, 504, 527, 546, 601

KISD3 defined in line 19; never used
SEG_DATA defined in line 26; used 6 times

- in line 63-72(3), 79, 97, 443

SEG_OVLY defined in line 28; used 32 times

- in line 78-93(15), 99-113(15), 344, 560

SEG_TEXT defined in line 27; used 6 times

- in line 67, 73-77(2), 98, 350, 565

Last modified: 1996-05-10 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2556 |