home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / hard / drivr / zeusscsi / kickload.c < prev    next >
C/C++ Source or Header  |  1993-12-21  |  9KB  |  347 lines

  1. /*    KickLoad.c - Manipulate the Exec Kickstart delta list    */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <exec/types.h>
  7. #include <exec/execbase.h>
  8. #include <exec/memory.h>
  9. #include <exec/resident.h>
  10. #include <proto/exec.h>
  11.  
  12. static const char _version[] = "$VER: KickLoad 1.0 (19.10.93)";
  13.  
  14. struct ExecBase **ExecBase = (struct ExecBase **) 0x000004;
  15.  
  16. FILE    *fp;
  17. char    *code;
  18. unsigned long mem_size;
  19.  
  20. struct MemList    *KickMem, *myMemList;
  21. long    *KickTag, *myTagPtr;
  22.  
  23. void clean (char *, char *);
  24. void display_kick (void);
  25. void clear_kick (void);
  26. unsigned long getlong (void);
  27. int    load_kick (char *);
  28. int    load_image (char *);
  29.  
  30. main (argc, argv)
  31. int    argc;
  32. char    *argv[];
  33. {
  34.     int    i;
  35.  
  36.     if (argc < 2) {
  37.         display_kick ();
  38.     }
  39.     else if (strcmp (argv[1], "-clear") == 0) {
  40.         clear_kick ();
  41.     }
  42.     else for (i = 1; i < argc; ++i)
  43.         load_kick (argv[i]);
  44. }
  45.  
  46. /*
  47.  *    load_kick (fname) - load an executable image and insert it into the
  48.  *    Exec KickStart delta list
  49.  *
  50.  */
  51.  
  52. load_kick (fname)
  53. char *fname;
  54. {
  55.     fp = fopen (fname, "r");
  56.     if (fp == NULL) {
  57.         clean ("unable to open %s", fname);
  58.         return (-1);
  59.     }
  60.     if (load_image (fname))
  61.         return (-1);
  62.     fclose (fp);
  63.     fp = NULL;
  64.     /* link into ExecBase data */
  65.     KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
  66.     KickTag = (long *) (*ExecBase)->KickTagPtr;
  67. #if 0
  68.     FreeMem (code, mem_size);    /* temp */
  69.     printf ("KickLoad:  %s test load sucessful\n", fname);
  70. #else
  71.     Forbid ();
  72.     while (KickMem && KickMem->ml_Node.ln_Succ)
  73.         KickMem = (struct MemList *) KickMem->ml_Node.ln_Succ;
  74.     myMemList->ml_Node.ln_Pred = (struct Node *) KickMem;
  75.     if (KickMem)
  76.         KickMem->ml_Node.ln_Succ = (struct Node *) myMemList;
  77.     else
  78.         (*ExecBase)->KickMemPtr = (APTR) myMemList;
  79.     /* Todo - add TagPtr to tail of TagPtr list */
  80.     if (KickTag)
  81.         myTagPtr[1] = ((long) KickTag) | 0x80000000;
  82.     (*ExecBase)->KickTagPtr = (APTR) myTagPtr;
  83.     (*ExecBase)->KickCheckSum = (APTR) SumKickData ();
  84.     Permit ();
  85.     printf ("KickLoad:  %s sucessfully installed\n", fname);
  86. #endif
  87.     code = NULL;
  88.     return (0);
  89. }
  90.  
  91. /*
  92.  *  load_image (fname) - load an executable image into memory
  93.  *    fname = path to image file
  94.  *
  95.  *    outputs:
  96.  *        code - address of executable memory + TagPtr + MemList
  97.  *        myTagPtr - address of TagPtr table
  98.  *        myMemList - address of MemList structure
  99.  *
  100.  *    Executable image begins at code;  TagPtr is two longwords following
  101.  *    the executable image;  MemList follows the TagPtr.  TagPtr points to
  102.  *    the first RomTag found in the image.  MemList contains one entry and
  103.  *    is the image/TagPtr/MemList data.
  104.  *    *** only one RomTag is recognized
  105.  *    *** memory is allocated from Chip memory
  106.  *    *** [could request DMAable memory for V36 (2.0)
  107.  */
  108.  
  109. load_image (fname)
  110. char    *fname;
  111. {
  112.     unsigned long u, getlong ();
  113.     int    i, j, k;
  114.     unsigned long *hunk_table;
  115.     unsigned long hunk;
  116.     int hunk_type;
  117.     char *hunk_ptr;
  118.     unsigned long *loc;
  119.     unsigned short *res_ptr;
  120.     unsigned long code_size;
  121.  
  122.     if (getlong () != 1011) {        /* Must be HUNK_HEADER */
  123.         clean ("%s is not an image file", fname);
  124.         return (-1);
  125.     }
  126.     if (getlong ()) {            /* don't allow resident lib */
  127.         clean ("%s Resident library not allowed", fname);
  128.         return (-1);
  129.     }
  130.     u = getlong ();                /* Hunk table size */
  131.     hunk = getlong ();            /* first hunk */
  132.     u = getlong ();                /* last hunk */
  133.     hunk_table = (long *) calloc (u + 1, sizeof (long));
  134.     if (hunk_table == NULL) {
  135.         clean ("unable to allocate memory for hunk table", NULL);
  136.         return (-1);
  137.     }
  138.     code_size = 0;
  139.     for (i = hunk; i <= u; ++i)
  140.         code_size += hunk_table[i] = getlong () * 4;
  141.     mem_size = code_size + sizeof (struct MemList) + 8 + 8;
  142. #ifdef MEMF_24BITDMA
  143.     code = (char *) AllocMem (mem_size, MEMF_CLEAR | MEMF_24BITDMA);
  144. #else
  145.     code = (char *) AllocMem (mem_size, MEMF_CLEAR | MEMF_CHIP);
  146. #endif
  147.     if (code == NULL) {
  148.         clean ("unable to allocate memory for image", NULL);
  149.         free (hunk_table);
  150.         return (-1);
  151.     }
  152.     /* Leave 8 byte buffer from beginning of allocated memory
  153.      * Memory List
  154.      * RomTag pointer array
  155.      * resident module data
  156.      */
  157.     myMemList = (struct MemList *) (code + 8);
  158.     myTagPtr = (unsigned long *) (myMemList + 1);
  159.     code = (char *) (myTagPtr + 2);
  160.     for (i = hunk, j = 0; i <= u; ++i) {
  161.         k = hunk_table[i];
  162.         hunk_table[i] = (long) (code + j);
  163.         j += k;
  164.     }
  165.     do {
  166.         switch (hunk_type = getlong ()) {
  167.         case 1001:            /* HUNK_CODE */
  168.         case 1002:            /* HUNK_DATA */
  169.         case 1003:            /* HUNK_BSS */
  170.             hunk_ptr = (char *) hunk_table[hunk++];
  171.             u = getlong ();        /* code length */
  172.             if (hunk_type != 1003 && u)
  173.                 fread (hunk_ptr, u, 4, fp);
  174.             break;
  175.         case 1004:            /* HUNK_RELOC32 */
  176.             while (i = getlong ()) {    /* get # refs */
  177.                 j = getlong ();        /* hunk # */
  178.                 /* tpdo - validate hunk # */
  179.                 j = hunk_table[j];
  180.                 while (i--) {
  181.                     u = getlong ();    /* offset */
  182.                     loc = (long *) (hunk_ptr + u);
  183.                     *loc += (unsigned long) j;
  184.                 }
  185.             }
  186.             break;
  187.         case 1010:
  188.             break;
  189.         case 0xffffffff:
  190.             break;
  191.         default:
  192.             clean ("Can't handle hunk type %d", (char *) hunk_type);
  193.             free (hunk_table);
  194.             return (-1);
  195.             break;
  196.         }
  197.     } while (hunk_type != 0xffffffff);
  198.     free (hunk_table);
  199.     /* make MemList structure and TagPtr table */
  200.     res_ptr = (unsigned short *) code;    /* search for ROMTAG */
  201.     while ((char *) res_ptr < code + code_size) {
  202.         if (*res_ptr == RTC_MATCHWORD)
  203.             break;
  204.         ++res_ptr;
  205.     }
  206.     if (*res_ptr != RTC_MATCHWORD)
  207.         res_ptr = 0;            /* didn't find ROMTAG */
  208.     /* should abort if no ROMTAG found */
  209.     /* also should verify ROMTAG:  rt_MatchTag == res_ptr,
  210.        rt_EndSkip <= code + code_size */
  211.     myTagPtr[0] = (unsigned long) res_ptr;
  212.     myTagPtr[1] = 0;
  213.     myMemList->ml_Node.ln_Succ = NULL;
  214.     myMemList->ml_Node.ln_Pred = NULL;
  215.     myMemList->ml_Node.ln_Type = NT_MEMORY;
  216.     myMemList->ml_Node.ln_Pri = 0;
  217.     /* use ROMTAG name as MemList node name */
  218.     /* todo - use fname as the MemList node name? */
  219.     if (res_ptr)
  220.         myMemList->ml_Node.ln_Name = ((struct Resident *) res_ptr)->rt_Name;
  221.     myMemList->ml_NumEntries = 1;
  222.     myMemList->ml_ME[0].me_Un.meu_Addr = (APTR) ((char *) myMemList - 8);
  223.     myMemList->ml_ME[0].me_Length = mem_size;
  224.     return (0);
  225. }
  226.  
  227. unsigned long getlong ()
  228. {
  229.     unsigned long u;
  230.  
  231.     if (fread ((char *) &u, 4, 1, fp) != 1)
  232.         return (0xffffffff);
  233.     return (u);
  234. }
  235.  
  236. void clean (text, arg)
  237. char    *text, *arg;
  238. {
  239.     printf ("KickLoad: ");
  240.     printf (text, arg);
  241.     printf ("\n");
  242.     if (fp) {
  243.         fclose (fp);
  244.         fp = NULL;
  245.     }
  246.     if (code) {
  247.         FreeMem (code, mem_size);
  248.         code = NULL;
  249.     }
  250. }
  251.  
  252. /*
  253.  *  display_kick - display Exec KickStart delta list
  254.  *
  255.  */
  256.  
  257. void display_kick ()
  258. {
  259.     int    i, l;
  260.     struct Resident *res_ptr;
  261.     char *start_quote, *end_quote;
  262.  
  263.     KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
  264.     KickTag = (long *) (*ExecBase)->KickTagPtr;
  265.     printf ("KickMemPtr = $%08x\n", KickMem);
  266.     while (KickMem) {
  267.         printf ("  MemList = $%08x \"%s\"\n", KickMem,
  268.             KickMem->ml_Node.ln_Name ? KickMem->ml_Node.ln_Name :
  269.             "*unnamed*");
  270.         for (i = 0; i < KickMem->ml_NumEntries; ++i) {
  271.             printf ("    [%d] Addr = $%08x, Length = $%x\n",
  272.                 i, KickMem->ml_ME[i].me_Un.meu_Addr,
  273.                 KickMem->ml_ME[i].me_Length);
  274.         }
  275.         KickMem = (struct MemList *) KickMem->ml_Node.ln_Succ;
  276.     }
  277.     printf ("KickTagPtr = $%08x\n", KickTag);
  278.     while (KickTag) {
  279.         printf ("  RomTags at $%08x:\n", KickTag);
  280.         i = 0;
  281.         while (KickTag[i] > 0) {
  282.             res_ptr = (struct Resident *) KickTag[i];
  283.             printf ("  [%d] -> $%08x", i++, res_ptr);
  284.             if (res_ptr == NULL) {
  285.                 printf (" <No ROMTAG>\n");
  286.                 continue;
  287.             }
  288.             start_quote = "\"";
  289.             end_quote = "\"\n";
  290.             if (res_ptr->rt_IdString && (l = strlen (res_ptr->rt_IdString))) {
  291.                 if (res_ptr->rt_IdString[l-1] == '\n')
  292.                     start_quote = end_quote = "";
  293.             }
  294.             printf ("  \"%s\" Type=%d Pri=%d Id=%s%s%s",
  295.                 res_ptr->rt_Name,
  296.                 res_ptr->rt_Type, res_ptr->rt_Pri,
  297.                 start_quote, res_ptr->rt_IdString, end_quote);
  298.             if (res_ptr->rt_MatchWord != RTC_MATCHWORD)
  299.                 printf ("\t**** Invalid MatchWord: $%04x\n",
  300.                     res_ptr->rt_MatchWord);
  301.         }
  302.         KickTag = (long *) (KickTag[i] & 0x7fffffff);
  303.     }
  304. }
  305.  
  306. /*
  307.  *
  308.  *  clear_kick - remove the Exec Kickstart delta list
  309.  *
  310.  *  Should add optional arguement to specify which entry to remove.
  311.  *  currently the entire list is removed.
  312.  *
  313.  */
  314.  
  315. void clear_kick ()
  316. {
  317.     int    i;
  318.  
  319.     KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
  320.     KickTag = (long *) (*ExecBase)->KickTagPtr;
  321.     printf ("KickMemPt