uldspload.cpp
来自「网友写的一个PCI卡,基于PCI总线的驱动」· C++ 代码 · 共 271 行
CPP
271 行
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <sys/stat.h>
#include "vDsp.h"
#define IRAM_BASE 0x00000000
#define SDRAM_BASE 0x80000000
#define COFF_MAGIC_2 0302
#define ISCOFF(x) ((x) == COFF_MAGIC_2)
#define COFF_SECTYPE_TEXT 0x0020
#define COFF_SECTYPE_DATA 0x0040
#define COFF_SECTYPE_BSS 0x0080
#define COFF_SECTYPE_COPY 0x0050
#pragma pack(push)//保存对齐状态
#pragma pack(2) //设置为2字节对齐
typedef struct _coff_filehdr coff_filehdr;
struct _coff_filehdr {
UINT16 f_magic; /* magic number */
UINT16 f_nscns; /* number of sections */
INT32 f_timdat; /* time & date stamp */
INT32 f_symptr; /* file pointer to symtab */
INT32 f_nsyms; /* number of symtab entries */
UINT16 f_opthdr; /* sizeof(optional hdr) */
UINT16 f_flags; /* flags */
UINT16 f_target_id; /* target architecture id */
};
typedef struct _coff_aouthdr coff_aouthdr;
struct _coff_aouthdr {
INT16 magic; /* optional file header magic number */
INT16 vstamp; /* version stamp */
INT32 tsize; /* text size in bytes, padded to FW bdry*/
INT32 dsize; /* initialized data " " */
INT32 bsize; /* uninitialized data " " */
INT32 entrypt; /* entry pt. */
INT32 text_start; /* base of text used for this file */
INT32 data_start; /* base of data used for this file */
};
typedef struct _coff_scnhdr coff_scnhdr;
struct _coff_scnhdr {
char s_name[8]; /* old COFF version name fld */
INT32 s_paddr; /* physical address */
INT32 s_vaddr; /* virtual address */
INT32 s_size; /* section size */
INT32 s_scnptr; /* file ptr to raw data for section */
INT32 s_relptr; /* file ptr to relocation */
INT32 s_lnnoptr; /* file ptr to line numbers */
UINT32 s_nreloc; /* number of relocation entries */
UINT32 s_nlnno; /* number of line number entries */
UINT32 s_flags; /* flags */
INT16 s_reserved; /* reserved 2 bytes */
UINT16 s_page; /* memory page id */
};
#pragma pack(pop)//恢复对齐状态
void
swap2byte(UINT16 *addr)
{
UINT16 tmp = *addr;
UINT16 tmp1, tmp2;
tmp1 = tmp & 0xff;
tmp2 = (tmp >> 8) & 0xff;
*addr = (tmp1 << 8) | (tmp2);
}
void
swap4byte(UINT32 *addr)
{
UINT32 tmp = *addr;
UINT32 tmp1, tmp2, tmp3, tmp4;
tmp1 = tmp & 0xff;
tmp2 = (tmp >> 8) & 0xff;
tmp3 = (tmp >> 16) & 0xff;
tmp4 = (tmp >> 24) & 0xff;
*addr = (tmp1 << 24) | (tmp2 << 16) | (tmp3 << 8) | (tmp4);
}
/*load coff file into DSP memory, return the entry point address*/
UINT32
ulDspLoad(char *fname)
{
int i,j;
coff_filehdr *fhdr;
coff_aouthdr *ahdr;
coff_scnhdr *shdr;
coff_scnhdr shdr2;
struct stat filestat;
FILE *fp;
char *fbuf;
char *fileptr, *fileptr_saved;
char byte_swapped = 0;
/* stat the file and figure out it's size */
if (stat(fname, &filestat) != 0) {
printf("unable to open target binary `%s' for getting file size.\n", fname);
return 0;
}
/* open the program for reading */
fp = fopen(fname, "r");
if (!fp) {
printf("unable to open target binary '%s' for reading", fname);
return 0;
}
/* about 1k more than reqd is malloced to read file into memory */
fbuf = (char *) malloc((filestat.st_size + 0x200) & ~(0x200));
/* load the program into memory */
if (fread(fbuf, 1, filestat.st_size, fp) < 1) {
printf("unable to read from target binary '%s'", fname);
return 0;
}
/* done with the executable, close it */
if (fclose(fp)) {
printf("unable to close target binary '%s'", fname);
return 0;
}
printf("target binary '%s' read in %ld bytes\n", fname, filestat.st_size);
/* start of file ptrs */
fileptr = fbuf;
fileptr_saved = fbuf;
/* goto the file header */
fhdr = (coff_filehdr *) fileptr;
fileptr = fileptr + 22;
/* check magic number */
if (!ISCOFF(fhdr->f_magic)) {
swap2byte(&(fhdr->f_magic));
if (!ISCOFF(fhdr->f_magic)) {
printf("bad magic number %d in target binary `%s' (not an executable)", fhdr->f_magic, fname);
return 0;
}
byte_swapped = 1;
/* swap the rest of the header */
swap2byte((UINT16 *)&(fhdr->f_nscns));
swap4byte((UINT32 *)&(fhdr->f_timdat));
swap4byte((UINT32 *)&(fhdr->f_symptr));
swap4byte((UINT32 *)&(fhdr->f_nsyms));
swap2byte((UINT16 *)&(fhdr->f_opthdr));
swap2byte((UINT16 *)&(fhdr->f_flags));
swap2byte((UINT16 *)&(fhdr->f_target_id));
}
/* goto aout header */
ahdr = (coff_aouthdr *) fileptr;
fileptr = fileptr + sizeof(coff_aouthdr);
/* swap bytes in the aouthdr if necessary */
if (byte_swapped == 1) {
swap2byte((UINT16 *)&(ahdr->magic));
swap2byte((UINT16 *)&(ahdr->vstamp));
swap4byte((UINT32 *)&(ahdr->tsize));
swap4byte((UINT32 *)&(ahdr->dsize));
swap4byte((UINT32 *)&(ahdr->bsize));
swap4byte((UINT32 *)&(ahdr->entrypt));
swap4byte((UINT32 *)&(ahdr->text_start));
swap4byte((UINT32 *)&(ahdr->data_start));
}
printf("processing %d sections\n", fhdr->f_nscns);
/* loop through the section headers and then the sections */
fileptr_saved = fileptr;
for (i = 0; i < fhdr->f_nscns; i++) {
fileptr = fileptr_saved;
shdr = (coff_scnhdr *) fileptr;
memcpy (&shdr2, fileptr, sizeof (coff_scnhdr));
fileptr += sizeof(coff_scnhdr);
fileptr_saved = fileptr;
/* swap bytes in the scnhdr if necessary, except s_name */
if (byte_swapped == 1) {
swap4byte((UINT32 *)&(shdr->s_paddr));
swap4byte((UINT32 *)&(shdr->s_vaddr));
swap4byte((UINT32 *)&(shdr->s_size));
swap4byte((UINT32 *)&(shdr->s_scnptr));
swap4byte((UINT32 *)&(shdr->s_relptr));
swap4byte((UINT32 *)&(shdr->s_lnnoptr));
swap4byte((UINT32 *)&(shdr->s_nreloc));
swap4byte((UINT32 *)&(shdr->s_nlnno));
swap4byte((UINT32 *)&(shdr->s_flags));
swap2byte((UINT16 *)&(shdr->s_reserved));
swap2byte((UINT16 *)&(shdr->s_page));
}
if (shdr->s_flags == COFF_SECTYPE_COPY) { /*skip copy section?*/
printf("copy section '%s', flag: 0x%xh, ignored\n", shdr->s_name, shdr->s_flags);
} else if (shdr->s_flags & COFF_SECTYPE_TEXT) {/*load text section*/
printf("text section '%s', flag: 0x%xh, starting at 0x%08x with %d bytes\n", shdr->s_name, shdr->s_flags, shdr->s_vaddr, shdr->s_size);
fileptr = fbuf + shdr->s_scnptr;
FILE *fp2;
fp2 = fopen ("test.txt", "w+");
for (j = 0; j < shdr->s_size; j+=4) {
UINT8 a, b, c, d;
UINT32 data, data2;
a = *(fileptr+j);
b = *(fileptr+j+1);
c = *(fileptr+j+2);
d = *(fileptr+j+3);
data = (d << 24) | (c << 16) | (b << 8) | (a);
vDspMemoryWrite(shdr->s_vaddr + j, 1, (PULONG)&data);
vDspMemoryRead(shdr->s_vaddr + j, 1, (PULONG)&data2);
if (data != data2)
printf ("%08X %08X\r\n", data, data2);
fprintf (fp2, "%08X %08X\n", j, data);
}
fclose (fp2);
}
else if (shdr->s_flags & COFF_SECTYPE_DATA) {/*load data section*/
if (shdr->s_size > 0) {
printf("data section '%s', flag: 0x%xh, starting at 0x%08x with %d bytes\n", shdr->s_name, shdr->s_flags, shdr->s_vaddr, shdr->s_size);
fileptr = fbuf + shdr->s_scnptr;
for (j = 0; j < shdr->s_size; j+=4) {
UINT8 a, b, c, d;
UINT32 data, data2;
a = *(fileptr+j);
b = *(fileptr+j+1);
c = *(fileptr+j+2);
d = *(fileptr+j+3);
data = (d << 24) | (c << 16) | (b << 8) | (a);
vDspMemoryWrite(shdr->s_vaddr + j, 1, (PULONG)&data);
vDspMemoryRead(shdr->s_vaddr + j, 1, (PULONG)&data2);
if (data != data2)
printf ("%08X %08X\r\n", data, data2);
}
} else
printf("section '%s' size equal to zero\n", shdr->s_name);
} else if (shdr->s_flags & COFF_SECTYPE_BSS) { /*skip bss section*/
if (shdr->s_size > 0) {
printf("bss section '%s' starting at 0x%08x with %d bytes, ignored\n", shdr->s_name, shdr->s_vaddr, shdr->s_size);
fileptr = fbuf + shdr->s_scnptr;
for (j = 0; j < shdr->s_size; j+=4) {
UINT8 a, b, c, d;
UINT32 data, data2;
a = *(fileptr+j);
b = *(fileptr+j+1);
c = *(fileptr+j+2);
d = *(fileptr+j+3);
data = (d << 24) | (c << 16) | (b << 8) | (a);
vDspMemoryWrite(shdr->s_vaddr + j, 1, (PULONG)&data);
vDspMemoryRead(shdr->s_vaddr + j, 1, (PULONG)&data2);
if (data != data2)
printf ("%08X %08X\r\n", data, data2);
}
} else
printf("section '%s' size equal to zero\n", shdr->s_name);
} else
printf("unknown section '%s', flag: 0x%xh, starting at 0x%08x, ignored\n", shdr->s_name, shdr->s_scnptr, shdr->s_flags);
}
free(fbuf);
fclose(fp);
return (ahdr->entrypt);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?