一、交叉编译
1. 编译原理
机器码(二进制)是处理器能直接识别的语言,不同的机器码代表不同的运算指令,处理器能够识别哪些机器码是由处理器的硬件设计所决定的,不同的处理器机器码不同,所以机器码不可移植
汇编语言是机器码的符号化,即汇编就是用一个符号来代替一条机器码,所以不同的处理器汇编也不一样,即汇编语言也不可移植
C语言在编译时我们可以使用不同的编译器将C源码编译成不同架构处理器的汇编,所以C语言可以移植
2. GCC编译原理
3. 交叉编译
程序的编译和运行不在同一台机器上
4. 交叉编译工具链
交叉编译工具链的获取:
- 官网获取(不推荐,需要自己进行复杂配置与编译)
http://ftp.gnu.org/gnu/gcc/ - BSP板级开发支持包(推荐)
samsung、全志…
交叉编译工具链的内容
- 交叉编译工具
gcc/readelf/size/nm/strip/objcopy/objdump/addr2line - 库
ARM架构的库
二、ELF文件格式
1. ELF文件格式
ELF格式是Linux平台上应用最广泛的二进制工业标准之一
ELF格式的文件内包含了很多个段不同的段存储了不同的信息;因为ELF格式的文件要通过Linux系统的加载和管理才能运行,所以除了最基本的代码段和数据段之外,其中还存储了很多其它的信息,如符号表、调试信息等
ELF文件相关命令
file
file + 文件名 查看文件的详细信息
readelf
readelf -h + 文件名 列出elf文件的头部信息readelf -a + 文件名 列出elf文件的所有信息
2. BIN格式文件
BIN文件一般是直接运行在CPU之上的可执行文件,文件内只包含了CPU能够直接识别和运行的指令和数据,不包含其它系统相关的信息
三、交叉编译工具链常用工具
size 列出目标文件每一段的大小以及总体的大小
size + 文件名
size a.out
查看是CPU可直接执行的段字节大小
ll a.out
查看的是ELF格式文件所有的字节大小
- 文本段(Text Segment)
也称为代码段。
存储程序的机器指令,即编译后的可执行代码。
这些指令在程序运行时被加载到内存中,并由处理器执行。 - 数据段(Data Segment):
存储已经初始化的全局变量、静态变量和常量。
这些变量在程序编译时就被赋予了初值,存储在这个段中。
这部分数据在程序加载时就会被读取到内存中。 - BSS段(Block Started by Symbol):
存储未初始化的全局变量和静态变量。
这些变量在编译时没有被初始化,因此在内存中只分配了空间而没有赋初值。
当程序加载时,这部分内存会被清零或设置为默认值(通常是0)。 - dec(Decimal):
这个数字表示整个可执行文件的大小(文本段 + 数据段 + BSS段)。
以十进制形式表示。 - hex(Hexadecimal):
这个数字表示整个可执行文件的大小的十六进制形式。
nm 列出目标文件中的符号表(标示符)
nm + 文件名
strip 丢弃目标文件中的符号
strip + 文件名 注:对于嵌入式开发,这个命令很重要(也可以称为瘦身命令)
objdump 从目标文件中显示信息
eg: objdump -d + 文件名 将目标文件反汇编(机器码->汇编)
objcopy 对目标文件进行复制和转换
eg:objcopy --gap-fill=0xff -O binary a.out a.bin
将目标文件转换为bin格式