home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 2
/
FFMCD02.bin
/
new
/
hard
/
drivr
/
zeusscsi
/
kickload.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-21
|
9KB
|
347 lines
/* KickLoad.c - Manipulate the Exec Kickstart delta list */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <exec/resident.h>
#include <proto/exec.h>
static const char _version[] = "$VER: KickLoad 1.0 (19.10.93)";
struct ExecBase **ExecBase = (struct ExecBase **) 0x000004;
FILE *fp;
char *code;
unsigned long mem_size;
struct MemList *KickMem, *myMemList;
long *KickTag, *myTagPtr;
void clean (char *, char *);
void display_kick (void);
void clear_kick (void);
unsigned long getlong (void);
int load_kick (char *);
int load_image (char *);
main (argc, argv)
int argc;
char *argv[];
{
int i;
if (argc < 2) {
display_kick ();
}
else if (strcmp (argv[1], "-clear") == 0) {
clear_kick ();
}
else for (i = 1; i < argc; ++i)
load_kick (argv[i]);
}
/*
* load_kick (fname) - load an executable image and insert it into the
* Exec KickStart delta list
*
*/
load_kick (fname)
char *fname;
{
fp = fopen (fname, "r");
if (fp == NULL) {
clean ("unable to open %s", fname);
return (-1);
}
if (load_image (fname))
return (-1);
fclose (fp);
fp = NULL;
/* link into ExecBase data */
KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
KickTag = (long *) (*ExecBase)->KickTagPtr;
#if 0
FreeMem (code, mem_size); /* temp */
printf ("KickLoad: %s test load sucessful\n", fname);
#else
Forbid ();
while (KickMem && KickMem->ml_Node.ln_Succ)
KickMem = (struct MemList *) KickMem->ml_Node.ln_Succ;
myMemList->ml_Node.ln_Pred = (struct Node *) KickMem;
if (KickMem)
KickMem->ml_Node.ln_Succ = (struct Node *) myMemList;
else
(*ExecBase)->KickMemPtr = (APTR) myMemList;
/* Todo - add TagPtr to tail of TagPtr list */
if (KickTag)
myTagPtr[1] = ((long) KickTag) | 0x80000000;
(*ExecBase)->KickTagPtr = (APTR) myTagPtr;
(*ExecBase)->KickCheckSum = (APTR) SumKickData ();
Permit ();
printf ("KickLoad: %s sucessfully installed\n", fname);
#endif
code = NULL;
return (0);
}
/*
* load_image (fname) - load an executable image into memory
* fname = path to image file
*
* outputs:
* code - address of executable memory + TagPtr + MemList
* myTagPtr - address of TagPtr table
* myMemList - address of MemList structure
*
* Executable image begins at code; TagPtr is two longwords following
* the executable image; MemList follows the TagPtr. TagPtr points to
* the first RomTag found in the image. MemList contains one entry and
* is the image/TagPtr/MemList data.
* *** only one RomTag is recognized
* *** memory is allocated from Chip memory
* *** [could request DMAable memory for V36 (2.0)
*/
load_image (fname)
char *fname;
{
unsigned long u, getlong ();
int i, j, k;
unsigned long *hunk_table;
unsigned long hunk;
int hunk_type;
char *hunk_ptr;
unsigned long *loc;
unsigned short *res_ptr;
unsigned long code_size;
if (getlong () != 1011) { /* Must be HUNK_HEADER */
clean ("%s is not an image file", fname);
return (-1);
}
if (getlong ()) { /* don't allow resident lib */
clean ("%s Resident library not allowed", fname);
return (-1);
}
u = getlong (); /* Hunk table size */
hunk = getlong (); /* first hunk */
u = getlong (); /* last hunk */
hunk_table = (long *) calloc (u + 1, sizeof (long));
if (hunk_table == NULL) {
clean ("unable to allocate memory for hunk table", NULL);
return (-1);
}
code_size = 0;
for (i = hunk; i <= u; ++i)
code_size += hunk_table[i] = getlong () * 4;
mem_size = code_size + sizeof (struct MemList) + 8 + 8;
#ifdef MEMF_24BITDMA
code = (char *) AllocMem (mem_size, MEMF_CLEAR | MEMF_24BITDMA);
#else
code = (char *) AllocMem (mem_size, MEMF_CLEAR | MEMF_CHIP);
#endif
if (code == NULL) {
clean ("unable to allocate memory for image", NULL);
free (hunk_table);
return (-1);
}
/* Leave 8 byte buffer from beginning of allocated memory
* Memory List
* RomTag pointer array
* resident module data
*/
myMemList = (struct MemList *) (code + 8);
myTagPtr = (unsigned long *) (myMemList + 1);
code = (char *) (myTagPtr + 2);
for (i = hunk, j = 0; i <= u; ++i) {
k = hunk_table[i];
hunk_table[i] = (long) (code + j);
j += k;
}
do {
switch (hunk_type = getlong ()) {
case 1001: /* HUNK_CODE */
case 1002: /* HUNK_DATA */
case 1003: /* HUNK_BSS */
hunk_ptr = (char *) hunk_table[hunk++];
u = getlong (); /* code length */
if (hunk_type != 1003 && u)
fread (hunk_ptr, u, 4, fp);
break;
case 1004: /* HUNK_RELOC32 */
while (i = getlong ()) { /* get # refs */
j = getlong (); /* hunk # */
/* tpdo - validate hunk # */
j = hunk_table[j];
while (i--) {
u = getlong (); /* offset */
loc = (long *) (hunk_ptr + u);
*loc += (unsigned long) j;
}
}
break;
case 1010:
break;
case 0xffffffff:
break;
default:
clean ("Can't handle hunk type %d", (char *) hunk_type);
free (hunk_table);
return (-1);
break;
}
} while (hunk_type != 0xffffffff);
free (hunk_table);
/* make MemList structure and TagPtr table */
res_ptr = (unsigned short *) code; /* search for ROMTAG */
while ((char *) res_ptr < code + code_size) {
if (*res_ptr == RTC_MATCHWORD)
break;
++res_ptr;
}
if (*res_ptr != RTC_MATCHWORD)
res_ptr = 0; /* didn't find ROMTAG */
/* should abort if no ROMTAG found */
/* also should verify ROMTAG: rt_MatchTag == res_ptr,
rt_EndSkip <= code + code_size */
myTagPtr[0] = (unsigned long) res_ptr;
myTagPtr[1] = 0;
myMemList->ml_Node.ln_Succ = NULL;
myMemList->ml_Node.ln_Pred = NULL;
myMemList->ml_Node.ln_Type = NT_MEMORY;
myMemList->ml_Node.ln_Pri = 0;
/* use ROMTAG name as MemList node name */
/* todo - use fname as the MemList node name? */
if (res_ptr)
myMemList->ml_Node.ln_Name = ((struct Resident *) res_ptr)->rt_Name;
myMemList->ml_NumEntries = 1;
myMemList->ml_ME[0].me_Un.meu_Addr = (APTR) ((char *) myMemList - 8);
myMemList->ml_ME[0].me_Length = mem_size;
return (0);
}
unsigned long getlong ()
{
unsigned long u;
if (fread ((char *) &u, 4, 1, fp) != 1)
return (0xffffffff);
return (u);
}
void clean (text, arg)
char *text, *arg;
{
printf ("KickLoad: ");
printf (text, arg);
printf ("\n");
if (fp) {
fclose (fp);
fp = NULL;
}
if (code) {
FreeMem (code, mem_size);
code = NULL;
}
}
/*
* display_kick - display Exec KickStart delta list
*
*/
void display_kick ()
{
int i, l;
struct Resident *res_ptr;
char *start_quote, *end_quote;
KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
KickTag = (long *) (*ExecBase)->KickTagPtr;
printf ("KickMemPtr = $%08x\n", KickMem);
while (KickMem) {
printf (" MemList = $%08x \"%s\"\n", KickMem,
KickMem->ml_Node.ln_Name ? KickMem->ml_Node.ln_Name :
"*unnamed*");
for (i = 0; i < KickMem->ml_NumEntries; ++i) {
printf (" [%d] Addr = $%08x, Length = $%x\n",
i, KickMem->ml_ME[i].me_Un.meu_Addr,
KickMem->ml_ME[i].me_Length);
}
KickMem = (struct MemList *) KickMem->ml_Node.ln_Succ;
}
printf ("KickTagPtr = $%08x\n", KickTag);
while (KickTag) {
printf (" RomTags at $%08x:\n", KickTag);
i = 0;
while (KickTag[i] > 0) {
res_ptr = (struct Resident *) KickTag[i];
printf (" [%d] -> $%08x", i++, res_ptr);
if (res_ptr == NULL) {
printf (" <No ROMTAG>\n");
continue;
}
start_quote = "\"";
end_quote = "\"\n";
if (res_ptr->rt_IdString && (l = strlen (res_ptr->rt_IdString))) {
if (res_ptr->rt_IdString[l-1] == '\n')
start_quote = end_quote = "";
}
printf (" \"%s\" Type=%d Pri=%d Id=%s%s%s",
res_ptr->rt_Name,
res_ptr->rt_Type, res_ptr->rt_Pri,
start_quote, res_ptr->rt_IdString, end_quote);
if (res_ptr->rt_MatchWord != RTC_MATCHWORD)
printf ("\t**** Invalid MatchWord: $%04x\n",
res_ptr->rt_MatchWord);
}
KickTag = (long *) (KickTag[i] & 0x7fffffff);
}
}
/*
*
* clear_kick - remove the Exec Kickstart delta list
*
* Should add optional arguement to specify which entry to remove.
* currently the entire list is removed.
*
*/
void clear_kick ()
{
int i;
KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
KickTag = (long *) (*ExecBase)->KickTagPtr;
printf ("KickMemPt