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 + -
显示快捷键?