home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / 2.9-derivatives / 2.9-pro350 / stand / boot.c next >
Encoding:
C/C++ Source or Header  |  1985-02-26  |  11.6 KB  |  591 lines

  1. /*
  2.  *    SCCS id    @(#)boot.c    2.1 (Berkeley)    8/5/83
  3.  */
  4.  
  5. #include    <sys/param.h>
  6. #include    <sys/seg.h>
  7. #include    <sys/ino.h>
  8. #include    <sys/inode.h>
  9. #include    <sys/filsys.h>
  10. #include    <sys/dir.h>
  11. #include    <sys/reboot.h>
  12. #include    <sys/koverlay.h>
  13. #include    <a.out.h>
  14. #include    "../saio.h"
  15.  
  16. #undef    btoc
  17. #define    KB    * 1024L
  18.  
  19. #define    KISD0    ((u_short *) 0172300)
  20. #define    KISD3    ((u_short *) 0172306)
  21. #define    KDSD0    ((u_short *) 0172320)
  22. #undef    KISA0
  23. #define    KISA0    ((u_short *) 0172340)
  24. #define    KISA3    ((u_short *) 0172346)
  25. #define    KDSA0    ((u_short *) 0172360)
  26.  
  27. #define    SEG_DATA    01
  28. #define    SEG_TEXT    02
  29. #define    SEG_OVLY    04
  30.  
  31. extern    int    cputype;
  32. extern    bool_t    ksep;            /* Is kernel mode currently separated */
  33. extern    bool_t    sep_id;            /* Does the cpu support separate I/D? */
  34. extern    int    bootopts, bootdev, checkword;
  35. #ifdef    BIGKOV
  36. int    bigkov = 0;
  37. #endif
  38. #ifdef GOO
  39. extern    char quietflg;
  40. #endif GOO
  41. char    module[]    = "Boot";    /* This program's name (used by trap) */
  42. char    line[100]    = RB_DEFNAME;
  43. bool_t    overlaid    = 0;
  44. u_short    pdrproto[16 + NOVL]    = {0};
  45. struct    exec    exec;
  46. struct    ovlhdr    ovlhdr;
  47. unsigned    btoc();
  48.  
  49. struct    loadmap    {
  50.     int    seg_type;
  51.     long    seg_len;
  52. };
  53. struct    loadtable    {
  54.     short    lt_magic;
  55.     struct    loadmap    *lt_map;
  56. };
  57.  
  58. struct    loadmap    load407[]    =    {
  59.     SEG_DATA,    56 KB,
  60.     0,        0  KB
  61.     };
  62. struct    loadmap    load410[]    =    {
  63.     SEG_TEXT,    48 KB,
  64.     SEG_DATA,    56 KB,
  65.     0,        0  KB
  66.     };
  67. struct    loadmap    load411[]    =    {
  68.     SEG_DATA,    56 KB,
  69.     SEG_TEXT,    64 KB,
  70.     0,        0  KB
  71.     };
  72. struct    loadmap    load430[]    =    {
  73.     SEG_TEXT,    16 KB,            /* minumum, 8 KB + 1 */
  74.     SEG_OVLY,    8  KB,
  75.     SEG_DATA,    24 KB,
  76.     SEG_OVLY,    8  KB,
  77.     SEG_OVLY,    8  KB,
  78.     SEG_OVLY,    8  KB,
  79.     SEG_OVLY,    8  KB,
  80.     SEG_OVLY,    8  KB,
  81.     SEG_OVLY,    8  KB,
  82.     0,        0  KB
  83.     };
  84. #ifdef    BIGKOV
  85. struct    loadmap big430[]    =    {
  86.     SEG_TEXT,    8 KB,            /* minumum, 8 KB + 1 */
  87.     SEG_OVLY,    16  KB,
  88.     SEG_DATA,    24 KB,
  89.     SEG_OVLY,    16  KB,
  90.     SEG_OVLY,    16  KB,
  91.     SEG_OVLY,    16  KB,
  92.     SEG_OVLY,    16  KB,
  93.     SEG_OVLY,    16  KB,
  94.     SEG_OVLY,    16  KB,
  95.     0,        0   KB
  96. };
  97. #endif
  98. struct    loadmap    load431[]    =    {
  99.     SEG_DATA,    56 KB,            /* minumum, 48 KB + 1 */
  100.     SEG_TEXT,    56 KB,
  101.     SEG_OVLY,    8  KB,
  102.     SEG_OVLY,    8  KB,
  103.     SEG_OVLY,    8  KB,
  104.     SEG_OVLY,    8  KB,
  105.     SEG_OVLY,    8  KB,
  106.     SEG_OVLY,    8  KB,
  107.     SEG_OVLY,    8  KB,
  108.     0,        0  KB
  109.     };
  110.  
  111. struct    loadtable    loadtable[]    =    {
  112.     A_MAGIC1,    load407,
  113.     A_MAGIC2,    load410,
  114.     A_MAGIC3,    load411,
  115.     A_MAGIC5,    load430,
  116.     A_MAGIC6,    load431
  117.     };
  118.  
  119. main ()
  120. {
  121.     int i, j;
  122.     int retry    = 0;
  123.     struct    loadtable    *setup ();
  124.  
  125.     segflag    = 3;            /* device drivers care about this */
  126. #ifndef GOO
  127.     printf ("\n%d%s\n", cputype, module);
  128. #endif GOO
  129.  
  130. #ifdef  UCB_AUTOBOOT
  131.     /*
  132.      *    The machine language will have gotten the bootopts
  133.      *    if we're an autoboot and will pass them along.
  134.      *    If r2 (checkword) was the complement of bootopts,
  135.      *    this is an automatic reboot, otherwise do it the hard way.
  136.      */
  137.     if (checkword != ~bootopts)
  138. #endif
  139.         bootopts    = RB_SINGLE | RB_ASKNAME;
  140. #ifdef GOO
  141.     if (bootopts & RB_QUIET)
  142.         quietflg = 1;
  143.     printf ("\n%d%s\n", cputype, module);
  144. #endif GOO
  145.     do    {
  146.         if (bootopts & RB_ASKNAME)    {
  147.             printf (": ");
  148.             gets (line);
  149.         }
  150.         else
  151.             printf (": %s\n", line);
  152.         if (line[0] == '\0')    {
  153.             printf (": %s\n", RB_DEFNAME);
  154.             i    = open (RB_DEFNAME, 0);
  155.         }
  156.         else
  157.             i    = open (line, 0);
  158.         j = -1;
  159.         if (i >= 0)    {
  160.             j    = checkunix (i, setup (i));
  161.             (void) close (i);
  162.             }
  163.         if (++retry > 2)
  164.             bootopts    = RB_SINGLE | RB_ASKNAME;
  165.     }    while (j < 0);
  166.  
  167. }
  168.  
  169. struct    loadtable    *
  170. setup (io)
  171. register io;
  172. {
  173.     register    i;
  174.  
  175.     exec.a_magic    = getw (io);
  176.     exec.a_text    = (unsigned) getw (io);
  177.     exec.a_data    = (unsigned) getw (io);
  178.     exec.a_bss    = (unsigned) getw (io);
  179.  
  180.     /*
  181.      *    Space over the remainder of the exec header.  We do this
  182.      *    instead of seeking because the input might be a tape which
  183.      *    doesn't know how to seek.
  184.      */
  185.     getw (io); getw (io); getw (io); getw (io);
  186.  
  187.     /*
  188.      *    If overlaid, get overlay header.
  189.      */
  190.     if (exec.a_magic == A_MAGIC5 || exec.a_magic == A_MAGIC6)    {
  191.         overlaid++;
  192.         ovlhdr.max_ovl    = getw (io);
  193.         for (i = 0; i < NOVL; i++)
  194.             ovlhdr.ov_siz[i]    = (unsigned) getw (io);
  195.         }
  196. #ifdef    BIGKOV
  197.     if (exec.a_magic == A_MAGIC5 && exec.a_text <= 8192)
  198.         bigkov = 1;
  199. #endif
  200.     
  201.     for (i = 0; i < sizeof (loadtable) / sizeof (struct loadtable); i++)
  202.         if (loadtable[i].lt_magic == exec.a_magic) {
  203. #ifdef    BIGKOV
  204.             if (exec.a_magic == A_MAGIC5 && bigkov)
  205.                 loadtable[i].lt_map = big430;
  206. #endif
  207.             return (&loadtable[i]);
  208.         }
  209.  
  210.     printf ("Bad magic number 0%o\n", exec.a_magic);
  211.     return ((struct loadtable *) NULL);
  212. }
  213.  
  214.  
  215. checkunix (io, lt)
  216. struct    loadtable    *lt;
  217. {
  218.     char    *segname;
  219.     register    ovseg, segtype;
  220.     register unsigned        seglen;
  221.     struct    loadmap    *lm    = lt->lt_map;
  222.  
  223.     if (lt == (struct loadtable *) NULL)
  224.         return (-1);
  225.  
  226.     /*
  227.      *    Check and set I & D space requirements.
  228.      */
  229.     if (exec.a_magic == A_MAGIC3 || exec.a_magic == A_MAGIC6)
  230.         if (!sep_id)    {
  231.             printf ("Cannot load separate I & D object files\n");
  232.             return (-1);
  233.             }
  234.         else
  235.             setsep ();
  236.     else
  237.         if (sep_id)
  238.             setnosep ();
  239.  
  240.     /*
  241.      *    Check the sizes of each segment.
  242.      */
  243.     ovseg    = 0;
  244.     while (segtype = lm->seg_type)    {
  245.         switch (segtype)    {
  246.             case SEG_TEXT:
  247.                 /*
  248.                  *    Round text size to nearest page.
  249.                  */
  250.                 if (exec.a_magic == A_MAGIC2)
  251.                     seglen    = ctob (stoc (ctos (btoc (exec.a_text))));
  252.                 else
  253.                     seglen    = exec.a_text;
  254.                 segname    = "Text";
  255.                 break;
  256.  
  257.             case SEG_DATA:
  258.                 seglen    = exec.a_data + exec.a_bss;
  259.                 segname    = "Data";
  260.                 if (exec.a_magic == A_MAGIC1)
  261.                     seglen    += exec.a_text;
  262.                 else
  263.                     /*
  264.                      *    Force a complaint if the file
  265.                      *    won't fit.  It's here instead
  266.                      *    of in the SEG_TEXT case above
  267.                      *    because it's more likely to be
  268.                      *    a data overflow problem.
  269.                      */
  270.                     if (exec.a_magic == A_MAGIC2)
  271.                         seglen    += ctob (stoc (ctos (btoc (exec.a_text))));
  272.                 break;
  273.  
  274.             case SEG_OVLY:
  275.                 seglen    = ovlhdr.ov_siz[ovseg];
  276.                 segname    = "Overlay";
  277.                 ovseg++;
  278.                 break;
  279.  
  280.             default:
  281.                 /*
  282.                  *    This ``cannot happen.''
  283.                  */
  284.                 printf ("Unknown segment type in load table:  %d\n", segtype);
  285.                 return (-1);
  286.                 /*NOTREACHED*/
  287.             }
  288.  
  289.         seglen    = ctob (btoc (seglen));
  290.         if (((long) seglen) > lm->seg_len)    {
  291.             if (segtype == SEG_OVLY)
  292.                 printf ("%s %d too large by %D bytes", segname, ovseg, lm->seg_len - ((long) seglen));
  293.             else
  294.                 printf ("%s too large by %D bytes", segname, lm->seg_len - ((long) seglen));
  295.             return (-1);
  296.             }
  297.         if (segtype == SEG_TEXT)
  298.             switch (exec.a_magic) {
  299.             case A_MAGIC5:
  300. #ifdef    BIGKOV
  301.                 if (seglen <= 8 KB && bigkov == 0) {
  302. #else
  303.                 if (seglen <= 8 KB) {
  304. #endif
  305.                 printf("Base segment too small, 8K minimum\n");
  306.                 return(-1);
  307.                 }
  308.                 break;
  309.             case A_MAGIC6:
  310.                 if (seglen <= 48 KB) {
  311.                 printf("Base segment too small, 48K minimum\n");
  312.                 return(-1);
  313.                 }
  314.                 break;
  315.             default:
  316.                 break;
  317.         }
  318.  
  319.         lm++;
  320.         }
  321.  
  322.     copyunix (io, lt);
  323.     setregs (lt);
  324.     return (0);
  325. }
  326.  
  327. copyunix (io, lt)
  328. register    io;
  329. struct    loadtable    *lt;
  330. {
  331.     int    i;
  332.     bool_t    donedata = 0;
  333.     register    addr;
  334.     register unsigned    seglen;
  335.     off_t    segoff;
  336.     int    segtype;
  337.     int    nseg, phys, ovseg;
  338.     struct    loadmap    *lm    = lt->lt_map;
  339.  
  340.     /*
  341.      *    Load the segments and set up prototype PDRs.
  342.      */
  343.     nseg    = 0;
  344.     phys    = 0;
  345.     ovseg    = 0;
  346.     lm    = lt->lt_map;
  347.     while (segtype = lm++->seg_type)    {
  348.  
  349.         segoff    = (off_t) N_TXTOFF(exec);
  350.  
  351.         switch (segtype)    {
  352.             case SEG_TEXT:
  353.                 seglen    = exec.a_text;
  354.                 break;
  355.  
  356.             case SEG_DATA:
  357.                 seglen    = exec.a_data;
  358.                 if (exec.a_magic != A_MAGIC1)    {
  359.                     segoff    += (off_t) exec.a_text;
  360.                     if (overlaid)
  361.                         for (i = 0; i < NOVL; i++)
  362.                             segoff    += (off_t) ovlhdr.ov_siz[i];
  363.                     }
  364.                 else
  365.                     seglen    += exec.a_text;
  366.                 donedata++;
  367.                 break;
  368.  
  369.             case SEG_OVLY:
  370.                 seglen    = ovlhdr.ov_siz[ovseg];
  371.                 segoff    += exec.a_text;
  372.                 for (i = 0; i < ovseg; i++)
  373.                     segoff    += (off_t) ovlhdr.ov_siz[i];
  374.                 ovseg++;
  375.                 break;
  376.  
  377.             }
  378.  
  379.         if (!seglen)
  380.             continue;
  381.         setseg (phys);
  382.         if (exec.a_magic != A_MAGIC1)
  383.             (void) lseek (io, segoff, 0);
  384.         for (addr = 0; addr < seglen; addr += 2)
  385.             mtpi (getw (io), addr);
  386.  
  387.         if (segtype == SEG_DATA)    {
  388.             clrseg (addr, exec.a_bss);
  389.             seglen    += exec.a_bss;
  390.             }
  391.  
  392.         pdrproto[nseg++]    = btoc (seglen);
  393.         if (!donedata)
  394.             seglen    = ctob (stoc (ctos (btoc (seglen))));
  395.         phys    += btoc (seglen);
  396.         }
  397. }
  398.  
  399. /*
  400.  *    Set the real segmentation registers.
  401.  */
  402. setregs (lt)
  403. struct    loadtable    *lt;
  404. {
  405.     register    i;
  406.     register u_short    *par_base, *pdr_base;
  407.     bool_t    donedata = 0;
  408.     int    phys, segtype;
  409.     int    nseg, ntextpgs, novlypgs, npages, pagelen;
  410.     struct    loadmap    *lm    = lt->lt_map;
  411.  
  412.     nseg    = 0;
  413.     phys    = 0;
  414.     ntextpgs    = 0;
  415.     novlypgs    = 0;
  416.  
  417.     setseg (0);
  418.     if (exec.a_magic == A_MAGIC1)
  419.         return;
  420.  
  421.     /*
  422.      *    First deny access to all except I/O page.
  423.      */
  424.     par_base    = KISA0;
  425.     pdr_base    = KISD0;
  426.     for (i = 0; i < (ksep ?  8 : 7); i++)    {
  427.         *par_base++    = 0;
  428.         *pdr_base++    = NOACC;
  429.         }
  430.     if (ksep)    {
  431.         par_base    = KDSA0;
  432.         pdr_base    = KDSD0;
  433.         for (i = 0; i < 7; i++)    {
  434.             *par_base++    = 0;
  435.             *pdr_base++    = NOACC;
  436.             }
  437.         }
  438.     
  439.     if (overlaid)    {
  440.         /*
  441.          *    We must write the prototype overlay register table.
  442.          *    N.B.:  we assume that
  443.          *        the table lies in the first 8k of kernel virtual
  444.          *        space, and
  445.          *
  446.          *        the appropriate page lies at physical 0.
  447.          */
  448.         if (ksep)
  449.             *KDSD0    =    ((128 -1) << 8) | RW;
  450.         else
  451.             *KISD0    =    ((128 -1) << 8) | RW;
  452.         par_base    = &(((u_short *) OVLY_TABLE_BASE)[0]);
  453.         pdr_base    = &(((u_short *) OVLY_TABLE_BASE)[1 + NOVL]);
  454.         for (i = 0; i < NOVL; i++)    {
  455. #ifdef    BIGKOV
  456.              if (bigkov) {
  457.             mtpd (0, (par_base+16));
  458.             mtpd (NOACC, (pdr_base+16));
  459.              }
  460. #endif    BIGKOV
  461.             mtpd (0, par_base++);
  462.             mtpd (NOACC, pdr_base++);
  463.             }
  464.         }
  465.  
  466.     /*
  467.      *    Now set all registers which should be nonzero.
  468.      */
  469.     lm    = lt->lt_map;
  470.     while (segtype = lm++->seg_type)    {
  471.         if (!(npages = ctos (pdrproto[nseg])))
  472.             continue;
  473.  
  474.         switch (segtype)    {
  475.             case SEG_TEXT:
  476.                 /*
  477.                  *    Text always starts at KI0;
  478.                  */
  479.                 par_base    = KISA0;
  480.                 pdr_base    = KISD0;
  481.                 ntextpgs    += npages;
  482.                 break;
  483.  
  484.             case SEG_DATA:
  485.                 if (overlaid)
  486.                     if (ksep)    {
  487.                         par_base    = I_DATA_PAR_BASE;
  488.                         pdr_base    = I_DATA_PDR_BASE;
  489.                         }
  490.                     else
  491.                         {
  492.                         par_base    = N_DATA_PAR_BASE;
  493.                         pdr_base    = N_DATA_PDR_BASE;
  494.                         }
  495.                 else
  496.                     if (ksep)    {
  497.                         par_base    = KDSA0;
  498.                         pdr_base    = KDSD0;
  499.                         }
  500.                     else
  501.                         {
  502.                         par_base    = &KISA0[ntextpgs + novlypgs];
  503.                         pdr_base    = &KISD0[ntextpgs + novlypgs];
  504.                         }
  505.                 donedata++;
  506.                 break;
  507.  
  508.             case SEG_OVLY:
  509.                 par_base    = &(((u_short *) OVLY_TABLE_BASE)[1 + novlypgs]);
  510.                 pdr_base    = &(((u_short *) OVLY_TABLE_BASE)[1 + NOVL + 1 + novlypgs]);
  511.                 novlypgs    += 1;
  512.                 break;
  513.  
  514.             }
  515.  
  516.         for (i = 0; i < npages; i++)    {
  517.             pagelen    = MIN (btoc ((int) (8 KB)), pdrproto[nseg]);
  518.             if (segtype == SEG_OVLY)    {
  519.                 mtpd (phys, par_base);
  520.                 mtpd (((pagelen - 1) << 8) | RO, pdr_base);
  521.                 }
  522.             else
  523.                 {
  524.                 *par_base    = phys;
  525.                 if (segtype == SEG_TEXT)
  526.                     if (ksep)
  527.                         *pdr_base    = ((pagelen - 1) << 8) | RO;
  528.                     else
  529.                         /*
  530.                          *    Nonseparate kernels will
  531.                          *    write into text page 0
  532.                          *    when first booted.
  533.                          */
  534.                         if (i == 0)
  535.                             *pdr_base    = ((pagelen - 1) << 8) | RW;
  536.                         else
  537.                             *pdr_base    = ((pagelen - 1) << 8) | RO;
  538.                 else
  539.                     *pdr_base    = ((pagelen - 1) << 8) | RW;
  540.                 }
  541. #ifdef    BIGKOV
  542.             if (segtype == SEG_OVLY && bigkov) {
  543.                 par_base += 16;
  544.                 pdr_base += 16;
  545.             } else {
  546. #endif    BIGKOV
  547.             par_base++, pdr_base++;
  548. #ifdef    BIGKOV
  549.             }
  550. #endif    BIGKOV
  551.             if (donedata)
  552.                 phys    += pagelen;
  553.             else
  554.                 phys    += stoc (ctos (pagelen));
  555.             pdrproto[nseg]    -= pagelen;
  556.             }
  557.  
  558.         nseg++;
  559.         }
  560.  
  561.     /*
  562.      *    Phys now contains the address of the start of
  563.      *    free memory.  We set K[ID]6 now or systrap to
  564.      *    kernel mode will clobber text at 0140000.
  565.      */
  566.     if (ksep)    {
  567.         KDSA0[6]    = phys;
  568.         KDSD0[6]    = (stoc(1) - 1) << 8 | RW;
  569.         }
  570.     else
  571.         {
  572.         KISA0[6]    = phys;
  573.         KISD0[6]    = (stoc(1) - 1) << 8 | RW;
  574.         }
  575.  
  576.     if (overlaid)
  577. #ifdef    BIGKOV
  578.         if (bigkov)
  579.         mtpd (phys, &(((u_short *) OVLY_TABLE_BASE)[32]));
  580.         else
  581. #endif
  582.         mtpd (phys, &(((u_short *) OVLY_TABLE_BASE)[1 + NOVL + 1 + NOVL]));
  583. }
  584.  
  585. unsigned
  586. btoc (nclicks)
  587. unsigned nclicks;
  588. {
  589.     return ((unsigned) (((((long) nclicks) + ((long) 63)) >> 6)));
  590. }
  591.