0%

交叉编译工具链的使用

交叉编译简介

交叉编译,是一个和本地编译相对应的概念,交叉编译通俗地讲就是一种平台上编译出的程序能够运行在不同体系结构的平台上,比如在PC平台(X86 CPU)上编译出能运行在ARM CPU的程序。

使用交叉编译的原因

主要原因是:嵌入式系统中的资源太少。具体的解释就是:所要运行的目标环境中,各种资源,都相对有限,所以很难进行直接的本地编译。嵌入式开发板的CPU、RAM、Falsh等硬件资源相对比较紧张,在已经运行了嵌入式Linux的前提下,没法方便的进行本地编译。因为编译,开发,都需要相对比较多的CPU,内存,硬盘等资源,而嵌入式开发上的资源,只够嵌入式(Linux)系统运行的,没太多剩余的资源,供你本地编译。

交叉编译工具链组成

常用交叉编译工具有交叉编译器、交叉连接器、交叉解释器还有交叉ELF文件工具、交叉反汇编器等工具。交叉编译工具链主要由binutils、gcc和glibc三个部分组成。有时出于减小 libc 库大小的考虑,也可以用别的 c 库来代替 glibc,例如 uClibc、dietlibc 和 newlib。

编译器能将我们编写的语言转成计算机可以识别的机器语言,解释器能够执行用其他计算机语言编写的程序的系统软件,它是一种翻译程序,转换一行,运行一行,再转换一行,再运行一行。解释性语言:Python,JavaScript,编译性语言:Java,c,c++。

交叉工具链命名规则

交叉编译工具链的命名规则为:arch - vendor - os - (gnu)eabi

arch – 体系架构,如ARM,MIPS,表示该编译器用于编译哪个目标平台的程序
vendor – 工具链提供商,通常是把vendor写成体系架构的值,比如cortex_a8
os – 运行编译产生的程序的目标操作系统,一般用linux表示有操作系统,none表示裸系统,uboot编译无os
eabi – 嵌入式应用二进制接口(Embedded Application Binary Interface),abi是计算机上的

编译工具使用(持续更新)

交叉编译工具使用方法与本地编译工具链基本一样,只是命名不同。

gcc

Linux系统下的GCC编译器实际上是GNU编译工具链中的一款软件,可以用它来调用其他不同的工具进行诸如预处理、编译、汇编和链接这样的工作。gcc编译器从拿到一个c源文件到生成一个可执行程序,中间一共经历了四个步骤:

220522-交叉编译工具链-1.jpg

ld

ld是GNU操作系统上的连接器,把二进制文件连接成可执行文件。ELF文件可用于程序的链接,重定位目标文件。用于链接的ELF文件格式:

220522-交叉编译工具链-2.jpg

从编译和链接角度看ELF文件ELF头,每个ELF文件都必须存在一个ELF_Header,这里存放了很多重要的信息用来描述整个文件的组织,如:版本信息、入口信息、偏移信息等,程序执行也必须依靠其提供的信息。

段头表,存放的是所有不同段将在内存中的位置。代码段.text section,存放已编译程序的机器代码,一般是只读的。只读数据段.rodata section,此段的数据不可修改,存放常量。数据段.data section,存放已初始化的全局变量。.bss section,未初始化全局变量,仅是占位符,不占据任何实际磁盘空间,目标文件格式区分初始化和非初始化是为了空间效率。

符号表.symtab section,它存放在程序中定义和引用的函数和全局变量的信息。.text节的重定位信息.rel.txt section,用于重新修改代码段的指令中的地址信息。.data节的重定位信息.rel.data section,用于对被模块使用或定义的全局变量进行重定位的信息。调试用的符号表.debug section。.strtab section,包含symtab和debug节中符号及节名。.line section,存储调试的行号信息,描述源代码和机器码之间的对应关系。

ELF(Executable and Linkable Format)的完整描述,可以参考这个文档 - 这里

size

220522-交叉编译工具链-3.jpg

用于显示二进制文件各节的大小。

text段最终是存放在FLASH存储器中的,text段不仅包含函数,还有常量。

data段是用于初始化数据(全局/外部),既有初始化值的数据。

bss段包含着所有未初始化(或初始化值为0)的数据(全局/外部)。

dec(decimal的缩写,即十进制数)是text,data和bss的算术和。

objcopy

220522-交叉编译工具链-4.jpg

把一种目标文件中的内容复制到另一种类型的目标文件中。

objcopy -O ihex xxxxxx.elf xxxxxx.hex 将编译生成的elf文件转换为hex格式的文件。

objcopy -O srec xxxxxx.elf xxxxxx.srec 将编译生成的elf文件转换为srec格式的文件。