⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkaif.c

📁 开源的BIOS启动软件
💻 C
字号:
/* mkaif.c * * By Russel King * * Adapted (hacked ?) for ELF by Benjamin Herrenschmidt * * ToDo: Option to add FMU header automatically for use *       when flashing via JTAG * * */#include <errno.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/fcntl.h>#include <linux/types.h>#include <unistd.h>#include <endian.h>#include <elf.h>#ifdef __GLIBC__typedef unsigned int u32;#endifstruct exec{	__u32 a_info;	/* Use macros N_MAGIC, etc for access */	__u32 a_text;	/* length of text, in bytes */	__u32 a_data;	/* length of data, in bytes */	__u32 a_bss;	/* length of uninitialized data area for file, in bytes */	__u32 a_syms;	/* length of symbol table data in file, in bytes */	__u32 a_entry;	/* start address */	__u32 a_trsize;	/* length of relocation info for text, in bytes */	__u32 a_drsize;	/* length of relocation info for data, in bytes */};#define N_MAGIC(exec) (SWAP32((exec).a_info) & 0xffff)/* Code indicating object file or impure executable.  */#define OMAGIC 0407/* Code indicating pure executable.  */#define NMAGIC 0410/* Code indicating demand-paged executable.  */#define ZMAGIC 0413/* This indicates a demand-paged executable with the header in the text.   The first page is unmapped to help trap NULL pointer references */#define QMAGIC 0314struct aif {	__u32	decomp_code;	__u32	reloc_code;	__u32	init_code;	__u32	entry_code;	__u32	exit_code;	__u32	text_size;	__u32	data_size;	__u32	dbg_size;	__u32	bss_size;	__u32	dbg_type;	__u32	image_base;	__u32	workspace;	__u32	reserved[4];	__u32	unused[16];};#if BYTE_ORDER == BIG_ENDIAN#define SWAP16(x)	bswap_16(x)#define SWAP32(x)	bswap_32(x)#else#define SWAP16(x)	(x)#define SWAP32(x)	(x)#endif#define MAX_PHDRS	10char buffer[8192];static int	copy_bytes(int file_from, int file_to, int from_offset, int total);int main(int argc, char *argv[]){	struct exec exec;	struct aif aifhdr;	int infile, aif, bytes, i, total;	Elf32_Ehdr elf_head;	Elf32_Phdr p_head[MAX_PHDRS];	int data_phead, text_phead;	int is_elf = 0;	if (argc != 3) {		fprintf(stderr, "Usage: %s a.out|file.elf aif_file\n", argv[0]);		exit (1);	}	infile = open(argv[1], O_RDONLY);	if (infile < 0) {		fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));		exit (1);	}	if (lseek(infile, 0, SEEK_SET) < 0) {		fprintf(stderr, "%s: unable to lseek: %s\n", argv[1], strerror(errno));		exit (1);	}	bytes = read(infile, &exec, sizeof(exec));	if (bytes < 0) {		fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));		exit (1);	} else if (bytes != sizeof(exec)) {		fprintf(stderr, "%s: file truncated\n", argv[1]);		exit (1);	}	/* May be an ELF file */	if (N_MAGIC(exec) != OMAGIC) {		if (lseek(infile, 0, SEEK_SET) < 0) {			fprintf(stderr, "%s: unable to lseek: %s\n", argv[1], strerror(errno));			exit (1);		}		bytes = read(infile, &elf_head, sizeof(elf_head));		if (bytes < 0) {			fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));			exit (1);		} else if (bytes != sizeof(elf_head)) {			fprintf(stderr, "%s: file truncated\n", argv[1]);			exit (1);		}		if ((elf_head.e_ident[EI_MAG0] != ELFMAG0)			|| (elf_head.e_ident[EI_MAG1] != ELFMAG1)			|| (elf_head.e_ident[EI_MAG2] != ELFMAG2)			|| (elf_head.e_ident[EI_MAG3] != ELFMAG3)) {			fprintf(stderr, "%s: file is not a supported format\n", argv[1]);			exit (1);		}		is_elf = 1;	}	printf("mkaif: Input file is %s format\n", is_elf ? "elf" : "a.out");	if (is_elf) {	 	if (lseek(infile, SWAP32(elf_head.e_phoff), SEEK_SET) < 0) {			fprintf(stderr, "%s: unable to lseek: %s\n", argv[1], strerror(errno));			exit (1);		}		bytes = read(infile, &p_head, SWAP16(elf_head.e_phnum) * sizeof(Elf32_Phdr));		/* Scan through the program header */		data_phead = text_phead = -1;		for (i = 0; i < SWAP16(elf_head.e_phnum); ++i) {			printf("-- section %d -- \n", i);			printf(" p_type          : 0x%08x\n", SWAP32(p_head[i].p_type));			printf(" p_flags         : 0x%08x\n", SWAP32(p_head[i].p_flags));			printf(" p_offset        : 0x%08x\n", SWAP32(p_head[i].p_offset));			printf(" p_vaddr         : 0x%08x\n", SWAP32(p_head[i].p_vaddr));			printf(" p_paddr         : 0x%08x\n", SWAP32(p_head[i].p_paddr));			printf(" p_filesz        : 0x%08x\n", SWAP32(p_head[i].p_filesz));			printf(" p_memsz         : 0x%08x\n", SWAP32(p_head[i].p_memsz));			printf(" p_align         : 0x%08x\n", SWAP32(p_head[i].p_align));			if (SWAP32(p_head[i].p_type) == PT_LOAD) {				if (SWAP32(p_head[i].p_flags) & PF_X) {					if (p_head[i].p_vaddr != elf_head.e_entry)						printf("entry not matching in text section !\n");					else {						if (text_phead != -1)							printf("too many text sections !\n");						else							text_phead = i;					}				} else {					if (data_phead != -1)						printf("too many text sections !\n");					else						data_phead = i;				}			}		}		if (text_phead == -1) {			printf("missing text section !\n");			close(infile);			exit(1);		}		if (data_phead == -1) {			printf("missing data section !\n");			close(infile);			exit(1);		}	  			printf("Bios size: %d bytes (fsz: %d) text at 0x%X, %d bytes data, %d bytes bss\n",			SWAP32(p_head[text_phead].p_memsz),			SWAP32(p_head[text_phead].p_filesz),			SWAP32(p_head[text_phead].p_vaddr),			SWAP32(p_head[data_phead].p_filesz),			SWAP32(p_head[data_phead].p_memsz) - SWAP32(p_head[data_phead].p_filesz));		memset(&aifhdr, 0, sizeof(aifhdr));		aifhdr.decomp_code	= SWAP32(0xe1a00000);		/* nop */		aifhdr.reloc_code 	= SWAP32(0xe1a00000);		/* nop */		aifhdr.init_code  	= SWAP32(0xe1a00000);		/* nop */		aifhdr.entry_code 	= SWAP32(0xeb00001b);		/* bl entry */		aifhdr.exit_code  	= SWAP32(0xeafffffe);		aifhdr.text_size  	= p_head[text_phead].p_memsz;	/* Mem size since we append stuffs */		aifhdr.data_size  	= p_head[data_phead].p_memsz;	/* Mem size (excludes bss) */		aifhdr.bss_size   	= SWAP32(SWAP32(p_head[data_phead].p_memsz) - SWAP32(p_head[data_phead].p_filesz));		aifhdr.image_base	= SWAP32(SWAP32(p_head[text_phead].p_vaddr) - 128);		aif = open(argv[2], O_WRONLY | O_CREAT, 0666);		if (aif < 0) {			fprintf(stderr, "%s: %s\n", argv[2], strerror(errno));			exit(1);		}		if (lseek(aif, 0, SEEK_SET) < 0) {			fprintf(stderr, "%s: unable to lseek: %s\n", argv[2], strerror(errno));			exit(1);		}		bytes = write(aif, &aifhdr, sizeof(aifhdr));		if (bytes < 0) {			fprintf(stderr, "%s: %s\n", argv[2], strerror(errno));			exit (1);		} else if (bytes != sizeof(aifhdr)) {			fprintf(stderr, "%s: file truncated\n", argv[2]);			exit (1);		}		if (!copy_bytes(infile, aif, SWAP32(p_head[text_phead].p_offset), SWAP32(p_head[text_phead].p_filesz))) {			close(aif);			close(infile);			unlink(argv[2]);			exit(1);		}		if (!copy_bytes(infile, aif, SWAP32(p_head[data_phead].p_offset), SWAP32(p_head[data_phead].p_filesz))) {			close(aif);			close(infile);			unlink(argv[2]);			exit(1);		}	} else {				/* Here, we handle a.out files */				printf("Bios size: %d bytes text at 0x%X, %d bytes data, %d bytes bss\n",			SWAP32(exec.a_text),			SWAP32(exec.a_entry),			SWAP32(exec.a_data),			SWAP32(exec.a_bss));		memset(&aifhdr, 0, sizeof(aifhdr));		aifhdr.decomp_code	= SWAP32(0xe1a00000);		/* nop */		aifhdr.reloc_code 	= SWAP32(0xe1a00000);		/* nop */		aifhdr.init_code  	= SWAP32(0xe1a00000);		/* nop */		aifhdr.entry_code 	= SWAP32(0xeb00001b);		/* bl entry */		aifhdr.exit_code  	= SWAP32(0xeafffffe);		aifhdr.text_size  	= exec.a_text;		aifhdr.data_size  	= exec.a_data;		aifhdr.bss_size   	= exec.a_bss;		aifhdr.image_base 	= SWAP32(SWAP32(exec.a_entry) - 128);		total = SWAP32(exec.a_text) + SWAP32(exec.a_data);		aif = open(argv[2], O_WRONLY | O_CREAT, 0666);		if (aif < 0) {			fprintf(stderr, "%s: %s\n", argv[2], strerror(errno));			exit(1);		}		if (lseek(aif, 0, SEEK_SET) < 0) {			fprintf(stderr, "%s: unable to lseek: %s\n", argv[2], strerror(errno));			exit(1);		}		bytes = write(aif, &aifhdr, sizeof(aifhdr));		if (bytes < 0) {			fprintf(stderr, "%s: %s\n", argv[2], strerror(errno));			exit (1);		} else if (bytes != sizeof(aifhdr)) {			fprintf(stderr, "%s: file truncated\n", argv[2]);			exit (1);		}		if (!copy_bytes(infile, aif, sizeof(exec), total)) {			close(aif);			unlink(argv[2]);			exit(1);		}	}		close(aif);	close(infile);		return 0;}static intcopy_bytes(int file_from, int file_to, int from_offset, int total){	int bytes;	if (lseek(file_from, from_offset, SEEK_SET) < 0) {		fprintf(stderr, "copy_bytes: unable to lseek: %s\n", strerror(errno));		return 0;	}	do {		bytes = total;		if (bytes > sizeof(buffer))			bytes = sizeof(buffer);		bytes = read(file_from, buffer, bytes);		if (bytes > 0)			bytes = write(file_to, buffer, bytes);		if (bytes < 0) {			fprintf(stderr, "unable to copy: %s\n", strerror(errno));			return 0;		}		total -= bytes;	} while (total);	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -