📄 mkaif.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 + -