一.介绍
1.1何谓交叉编译器
交叉编译通俗地讲就是在一种平台上编译出能运行在体系结构不同的另一种平台上。这种方法在异平台移植和嵌入式开发时用得非常普遍,相对与交叉编译,我们平常做的编译就叫本地编译,也就是在当前平台编译,编译得到的程序也是在本地执行。
用来编译这种程序的编译器就叫交叉编译器,相对来说,用来做本地编译的就叫本地编译器,一般用的都是gcc。但这种gcc跟本地的gcc编译器是不一样的,需要在编译gcc时用特定的configure参数才能得到支持交叉编译的gcc。为了不跟本地编译器混淆,交叉编译器的名字一般都有前缀,比如sparc-xxxx-linux-gnu-gcc,sparc-xxxx-linux-gnu-g++ 等等。
1.2交叉编译器的使用方法
使用方法跟本地的gcc差不多,但有一点特殊的是:必须用-L和-I参数指定编译器用sparc系统的库和头文件,不能用本地(X86)的库(头文件有时可以用本地的),原因是本地编译器使用的架构和交叉编译器使用的架构不同,自然所调用的库应该是各自架构编译所生成的,否则不兼容的。
如:
sparc-xxxx-linux-gnu-gcc test.c -L/path/to/sparcLib -I/path/to/sparcInclude
1.3交叉编译链的一些工具作用介绍
以某款arm交叉编译器为例
1.3.1arm-linux-gnueabihf-gcc 编译器
比如有一个led.c文件
arm-linux-gnueabihf-gcc -c led.c -o led
一个工程中所有的 C 文件和汇编文件(如果有)都会编译生成对应的.o 文件,我们需要将这些.o 文件链接起来组合成可执行文件。
1.3.2arm-linux-gnueabihf-ld 链接文件
arm-linux-gnueabihf-ld 用来将众多的.o 文件链接到一个指定的链接位置。
例如:
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
上述命令中-Ttext 就是指定链接地址,“-o”选项指定链接生成的 elf 文件名,这里我们命名 为 led.elf。上述命令执行完以后就会在工程目录下多一个 led.elf 文件。led.elf 文件也不是我们最终烧写到 SD 卡中的可执行文件,我们要烧写的.bin 文件,因此还 需要将 led.elf 文件转换为.bin 文件,这里我们就需要用到 arm-linux-gnueabihf-objcopy 这个工具了。
1.3.3arm-linux-gnueabihf-objcopy格式转换
arm-linux-gnueabihf-objcopy 更像一个格式转换工具,我们需要用它将 led.elf 文件转换为led.bin 文件,
命令如下:
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
上述命令中,“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出, 选项“-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试 信息。至此我们终于等到了想要的东西—led.bin 文件。
1.3.4arm-linux-gnueabihf-objdump 反汇编
大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令:
arm-linux-gnueabihf-objdump -D led.elf > led.dis
上述代码中的“-D”选项表示反汇编所有的段,反汇编完成以后就会在当前目录下出现一个名为 led.dis 文件。
1.4对linux下可执行文件和bin文件区别的说明
常用的可执行文件包含两类:原始二进制文件(bin)和可加载执行的二进制文件,在linux中可加载执行的二进制文件为elf文件。
在Linux 上,为了运行可执行文件,他们是遵循ELF格式的,通常gcc -o test test.c,生成的test文件就是ELF格式的。执行elf文件时内核会使用加载器来解析elf文件并执行。
ELF文件格式是一个开放标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型:
- 可重定位的目标文件(Relocatable,或者Object File)
- 可执行文件(Executable)
- 共享库(Shared Object,或者Shared Library)
区别:
1.BIN文件是 raw binary 文件,这种文件只包含机器码,执行raw binary很简单,只需要将程序加载到其起始地址,就可以执行。
2.ELF文件除了机器码外,还包含其它额外的信息,如段的加载地址,运行地址,重定位表,符号表等,所以ELF文件的体积比对应的BIN文件要大,我们调试一般都是使用elf文件。