一套完整的ARM交叉编译环境的搭建过程
扫描二维码
随时随地手机看文章
在网上查看了不少资料,参考别人的,在加上一些自己遇到的问题结合的,内容直接转载过来了,给和我一样,刚
入门ARM的新手的。虽然网上很多现成的,但是自己动手做作,还是很好的。
编译环境:
内核名称:Linux
内核发行版: 3.3.0-4.fc16.x86_64
内核版本:#1 SMP Tue Mar 20 18:05:40 UTC 2012
硬件架构名称: x86_64
硬件平台:x86_64
操作系统:GNU/Linux
当前系统gcc版本号:4.6.3
在Linux中建立整个ARM交叉编译环境的整体过程为:
1、下载源码包放在/mnt/hgfs/Document/
2、建立编译目录并设置环境变量
3、安装内核头文件
4、安装二进制工具(binutils)
5、建立初始编译器工具链(简版gcc)
6、建立glibc库
7、建立全套编译器工具链(full gcc)
8、验证
一、下载源码包
GNU的所有源码文件都可以到这个地址下载:http://ftp.gnu.org/gnu/
Linux Kernel源代码可以去这里下载:http://www.kernel.org
mpc可以去这里下载:http://www.multiprecision.org
下载的源码包如下:
binutils-2.22.tar
gcc-4.6.3.tar
glibc-2.13.tar
glibc-linuxthreads-2.3.6.tar
glibc-ports-2.13.tar
gmp-5.0.4.tar
linux-3.2.12.tar
mpc-0.9.tar
mpfr-2.4.2.tar.gz
注:mpfr不建议使用3.0.0版本。mpfr-3.0.0有Bug,会导致gcc编译不过。
C 库我试用了很多的版本,只有这套组合才能编译成功
在后面编译的过程中会提示缺少头文件,去内核中找到cp里就可以了。
二、建立编译目录并设置环境变量
选定自己的工作目录,如我选择/opt/embedded作为自己的工作目录。然后再embedded中建立build-tools、kernel、tools
三个文件夹。实例:
root@fedora:/opt/ming# cd /opt/
root@fedora:/opt# mkdir embedded
root@fedora:/opt# cd embedded/
root@fedora:/opt/embedded# mkdir build-tools kernel tools
root@fedora:/opt/embedded# cd build-tools/
root@fedora:/opt/embedded/build-tools# mkdir build-binutils build-boot-gcc build-glibc build-gcc
各文件夹的作用如下:
/opt/embedded:交叉编译环境的主目录
/opt/embedded/build-tools:存放binutils、gcc、glibc等GNU源码和用来编译这些源代码的目录
/opt/embedded/kernel:用来存放Linux内核源代码
/opt/embedded/tools:用来存放编译好的交叉编译工具和库文件
/opt/embedded/build-tools/build-binutils:编译binutils的目录
/opt/embedded/build-tools/build-boot-gcc:编译gcc启动部分的目录
/opt/embedded/build-tools/build-glibc:编译glibc的目录
/opt/embedded/build-tools/build-gcc:编译整个gcc的目录
建立好编译目录之后便是设置环境变量(建议直接在~/.bashrc中修改,注意修改之后要重新运行Terminal)。如下:
export PRJROOT=/opt/embedded
export TARGET=arm-linux
export PREFIX=$PRJROOT/tools
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PREFIX/bin:$PATH
各个环境变量的意义如下:
PRJROOT:整个交叉编译环境的根目录
TARGET:目标文件对应的architecture,arm-linux表示编译出来的target只能在arm architecture中运行
PREFIX:目标文件夹的路径前缀
TARGET_PREFIX:目标文件夹的路径前缀路径
PATH:可执行文件路径,这里主要指定编译工具等
三、安装内核头文件
将Linux内核源码解压至$PRJROOT/kernel目录,然后建立几个文件的符号链接,最后生成version.h文件。实例:
首先解压Linux内核源文件
root@fedora:/opt/embedded/kernel# cp /mnt/hgfs/Document/linux-3.2.12.tar .
root@fedora:/opt/embedded/kernel# tar -xvf linux-3.2.12.tar
root@fedora:/opt/embedded/kernel# mkdir /opt/embedded/tools/arm-linux
root@fedora:/opt/embedded/kernel# mkdir /opt/embedded/tools/arm-linux/include
root@fedora:/opt/embedded/kernel# ln -s /opt/embedded/kernel/linux-3.2.12/include/linux /opt/embedded/tools/arm-linux/include/linux
root@fedora:/opt/embedded/kernel# ln -s /opt/embedded/kernel/linux-3.2.12/include/asm-generic /opt/embedded/tools/arm-linux/include/asm-generic
root@fedora:/opt/embedded/kernel# ln -s /opt/embedded/kernel/linux-3.2.12/arch/arm/include/asm /opt/embedded/tools/arm-
linux/include/asm (也可能是是asm-arm,示内核版本而定)
下面检查上面创建的符号链接是否正确。实例:
root@fedora:/opt/embedded/kernel# cd /opt/embedded/tools/arm-linux/include/
root@fedora:/opt/embedded/tools/arm-linux/include# ll
asm -> /opt/embedded/kernel/linux-3.2.12/arch/arm/include/asm/
asm-generic -> /opt/embedded/kernel/linux-3.2.12/include/asm-generic/
linux -> /opt/embedded/kernel/linux-3.2.12/include/linux/
有如上结果表示符号链接创建正确。
root@fedora:/opt/embedded/kernel/linux-3.2.12#make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig*配置(注
意:arm-linux- 与menuconfig之间有一个空格)*
//在随后出现的文本菜单进行配置、配置完退出并保存。若要设置某个选项,可将光标定位在该项上,按回车键。对
于前面有[]或者<>的,可以按空格键显示所包含的子选项。
注意在选项System Types中选择正确的硬件类型。配置完退出并保存(Exit Yes)。
最后生成version.h文件。实例:
root@fedora:/opt/embedded/kernel/linux-3.2.12# cd /opt/embedded/kernel/linux-3.2.12/
root@fedora:/opt/embedded/kernel/linux-3.2.12# make include/linux/version.h
CHK include/linux/version.h
UPD include/linux/version.h
接着进入相应目录查看version.h文件是否建立成功。
注:上述的做法理论上没什么问题,但实际操作时,如果用其他版本的linux内核可能会出现头文件包含不全的情况,
这会直接导致后面编译glibc时出现未定义、未声明、缺少头文件(如asm/unistd.h)的错误。如果可能的话,建议按上
述操作直接copy好用的其他交叉编译工具链中的asm-arm、asm-generic、linux目录。
四、安装二进制工具(binutils)
Binutils是一些二进制工具集合,其中包含了常用的一些命令。首先将binutils-2.22.tar.bz2解压至build-tools,然后进入
build-binutils目录,配置并编译binutils,最后使用make install进行安装。实例:
root@fedora:/opt/embedded/build-tools# cd /opt/embedded/build-tools/
root@fedora:/opt/embedded/build-tools# cp /mnt/hgfs/Document/binutils-2.22.tar.bz2 .
root@fedora:/opt/embedded/build-tools# tar -xjf binutils-2.22.tar.bz2
root@fedora:/opt/embedded/build-tools# cd build-binutils/
root@fedora:/opt/embedded/build-tools/build-binutils#../binutils-2.22/configure --target=$TARGET --prefix=$PREFIX
root@fedora:/opt/embedded/build-tools/build-binutils# make
root@fedora:/opt/embedded/build-tools/build-binutils# make install
完成后,去$PREFIX中检查一下生成的工具。实例:
root@fedora:/opt/embedded/build-tools/build-binutils# cd /opt/embedded/tools/bin
root@fedora:/opt/embedded/tools/bin# ll
有如下文件:
arm-linux-addr2line*
arm-linux-ar*
arm-linux-as*
arm-linux-c++filt*
arm-linux-elfedit*
arm-linux-gprof*
arm-linux-ld*
arm-linux-ld.bfd*
arm-linux-nm*
arm-linux-objcopy*
arm-linux-objdump*
arm-linux-ranlib*
arm-linux-readelf*
arm-linux-size*
arm-linux-strings*
arm-linux-strip*
这些生成的文件的作用分别为:
arm-linux-addr2line:将你要找的地址转成文件和行号,它要使用 debug 信息
arm-linux-ar:产生、修改和解开一个存档文件
arm-linux-as:GNU的汇编器
arm-linux-c++filt:C++ 和 java 中有一种重载函数,所用的重载函数最后会被编译转化成汇编的标,c++filt 就是实现
这种反向的转化,根据标号得到函数名
arm-linux-elfedit:用途暂时未知
arm-linux-gprof:GNU汇编器预编译器
arm-linux-ld:GNU的连接器
arm-linux-ld.bfd:用途暂时未知
arm-linux-nm:列出目标文件的符号和对应的地址
arm-linux-objcopy:将某种格式的目标文件转化成另外格式的目标文件
arm-linux-objdump:显示目标文件的信息
arm-linux-ranlib:为一个存档文件产生一个索引,并将这个索引存入存档文件中
arm-linux-readelf:显示 elf 格式的目标文件的信息
arm-linux-size:显示目标文件各个节的大小和目标文件的大小
arm-linux-strings:打印出目标文件中可以打印的字符串,有个默认的长度,为4
arm-linux-strip:剥掉目标文件的所有的符号信息
注:编译过程中有可能出现的错误:
gcc -DHAVE_CONFIG_H -I.-I. -I. -I../bfd -I./config -I./../include -I./.. -I./../bfd -
DLOCALEDIR=""/tools/cross/share/locale""-W -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror -g -O2 -MT tc-
arm.o -MD -MP -MF .deps/tc-arm.Tpo -c -o tc-arm.o `test -f 'config/tc-arm.c' || echo './'`config/tc-arm.c
cc1: warnings being treated as errors
config/tc-arm.c: In function ‘make_mapping_symbol’:
config/tc-arm.c:2489: 警告:if 语句体为空
make[4]: *** [tc-arm.o] 错误 1// 排错要充分利用报错信息。
make[4]: Leaving directory `/root/build/binutils-2.20_cross/gas'
make[3]: *** [all-recursive] 错误 1
make[3]: Leaving directory `/root/build/binutils-2.20_cross/gas'
make[2]: *** [all] 错误 2
make[2]: Leaving directory `/root/build/binutils-2.20_cross/gas'
make[1]: *** [all-gas] 错误 2
make[1]: Leaving directory `/root/build/binutils-2.20_cross'
make: *** [all] 错误 2
解决方案:
1)网上说的在tc-arm.c中加个括号,没研究,可能好用;
2)在make这一步中,可能会在编译../binutils-2.22/gas/config/tc-arm.c出现gcc把警告当成错误的错误,其原因在于编译
该文件时使用了-Werror选项,解决办法是修改../binutils-2.22/gas/configure文件第10624行,把
ERROR_ON_WARNING=yes改为ERROR_ON_WARNING=no,保存退出,重新执行make即可。
3)在配置时,关闭Warning报错,也可以编译成功:(我用的是这种)
[root@localhost binutils-2.20_cross_no_2]# ./configure --target=arm-linux --disable-werror && make
参考:http://hi.baidu.com/thinke365/bl ... 1f095af819b853.html
五、建立初始编译器(简版 gcc)
Gcc是最主要的编译器。首先将gcc-4.6.3.ta解压至build-tools,然后将gmp-5.0.2.tar.bz2、mpfr-2.4.2.tar.gz、mpc-0.9.tar.gz