常用的可执行文件包含两类:原始二进制文件(bin)和可加载执行的二进制文件,在linux中可加载执行的二进制文件为elf文件。
BIN文件是直接的二进制文件,内部没有地址标记。bin文件内部数据按照代码段或者数据段的物理空间地址来排列。一般用编程器烧写时从00开始,而如果下载运行,则下载到编译时的地址即可。
在Linux OS上,为了运行可执行文件,他们是遵循ELF格式的,通常gcc -o test test.c,生成的test文件就是ELF格式的。执行elf文件时内核会使用加载器来解析elf文件并执行。
ELF文件格式是一个开放标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型:
可重定位的目标文件(Relocatable,或者Object File)
可执行文件(Executable)
共享库(Shared Object,或者Shared Library)
$ file sum.o sub.o test.o libsub.so test sum.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped sub.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped test.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped libsub.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped 结果很清楚的告诉我们他们都属于哪一个类别。比方 sum.o 是应用在x86架构上的可重定位文件。这个结果也间接的告诉我们,x86是小端模式(LSB)的32位结构。
那对于 file 命令来说,它又能如何知道这些信息?答案是在ELF对象文件的最前面有一个ELF文件头,里面记载了所适用的处理器、对象文件类型等各种信息。
ELF格式提供了两种不同的视角,链接器把ELF文件看成是Section的集合,而加载器把ELF文件看成是Segment的集合。
在Embedded中,如果上电开始运行,没有OS系统,如果将ELF格式的文件烧写进去, 包含一些ELF文件的符号表字符表之类的section,运行碰到这些,就会导致失败,如果用objcopy生成纯粹的二进制文件,去除掉符号表之类的 section,只将代码段数据段保留下来,程序就可以一步一步运行。elf文件里面包含了符号表等。BIN文件是将elf文件中的代码段,数据段,还有一些自定义的段抽取出来做成的一个内存的镜像。并且elf文件中代码段数据段的位置并不是它实际的物理位置,实际物理位置是在表中标记出来的。
FILE *fp = fopen("vmlinux.bin", "rb"); fread(VMLINUX_START, 1, VMLINUX_SIZE, fp); ((void (*)(void))VMLINUX_START)();
CC=ppc-gcc LD=ppc-ld OBJCOPY=ppc-objcopy $(CC) -g $(CFLAG) -c boot.S #先将boot.S文件生成boot.o $(LD) -g -Bstatic -T$(LDFILE) -Ttext 0x12345600 boot.o --start-group -Map boot.map -o boot.elf #再将boot.o生成boot.elf $(OBJCOPY) -O binary -R .note -R .comment -S boot.elf boot.bin #接着将 boot.elf 转换为 boot.bin #使用 -O binary (或--out-target=binary) 输出为原始的二进制文件 #使用 -R .note (或--remove-section) 输出文件中不要.note这个section,缩小了文件尺寸 #使用 -S (或 --strip-all) 输出文件中不要重定位信息和符号信息,缩小了文件尺寸
nm elf文件 #得到符号表
objdump -D elf文件 #反汇编,且汇编代码与源码混排
objdump -b binary -m powerpc uboot.bin
此外还有工具:readelf,objcopy,ldd,file等。
原文:http://www.cnblogs.com/embedded-linux/p/7237189.html