本文转载自:http://eric-gao.iteye.com/blog/2160622
制作arm-linux交叉编译工具链一般通过crosstool工具或者crosstool-NG,前者使用方便,但是制作会受到一些限制,使用crosstool最多只能编译gcc4.1.1、glibc2.x的版本,无法编译版本高于2.6.29的linux内核。crosstool-NG是新的用来建立交叉编译工具链的工具,它是crosstool的替代者。crosstool-NG有更好的定制性,并且一直保持着更新,对新版本的编译工具链的支持比较好,当然也带来了一些麻烦,它并不是下载下来就可以使用的,必须先配置安装。我们这里选用crosstool-NG来制作编译工具链。
本文使用的系统是Ubuntu Kylin(3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux),建议都使用Ubuntu系统,安装软件比较方便。
一、安装crosstool-NG
1、建立arm-linux-tools目录,并进入该目录
- $ mkdir arm-linux-tools
- $ cd arm-linux-tools
2、获取crosstool-NG的源码
- $ wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.20.0.tar.bz2
3、解压crosstool-NG的源码
- $ tar xvjf crosstool-ng-1.20.0.tar.bz2
考虑到后续将要使用到的各种目录,在这里先建立好后续所需的目录。
- $ mkdir crosstool-build crosstool-install src
4、配置并进行依赖检测
- $ cd crosstool-ng-1.20.0
- $ ./configure --prefix /home/eric/arm-linux-tools/crosstool-install/
在配置之前,需要确保以下软件已经安装
1)gperf
2)bison
3)flex
4)texinfo
5)gawk
6)libtool
7)automake
8)libncurses5-dev
9)g++
在进行配置时,会进行依赖检测,如果存在包缺失的现象,安装好之后再执行配置即可。
成功配置之后会自动创建我们需要的Makefile文件。
5、编译并安装
- $ make
- $ make install
6、配置环境变量
- $ export PATH=$PATH:/home/eric/arm-linux-tools/crosstool-install/bin/
7、检查crosstool-NG是否安装成功
- $ ct-ng -v
二、配置交叉编译工具链
在crosstool-NG中有很多已经做好的默认配置(位于crosstool-ng-1.20.0/samples目录下),这里只需要进行修改就可以了。因为是制作arm-linux的交叉编译工具链,所以选择arm-unknown-linux-gnueabi进行配置。
1、将arm-unknown-linux-gnueabi文件夹复制到crosstool-build目录下
- $ cd samples
- $ cp -r arm-unknown-linux-gnueabi/ ../../crosstool-build/
2、将默认配置文件拷贝到crosstool-build目录下并改名为.config
- $ cd ~/arm-linux-tools/crosstool-build
- $ cp arm-unknown-linux-gnueabi/crosstool.config .config
3、执行ct-ng menuconfig进入配置界面进行配置
- $ ct-ng menuconfig
配置界面如下图所示:
(1)设定源码包路径和交叉编译器的安装路径
1)源码包路径:设置Paths and misc options下的Local tarballs directory为/home/eric/arm-linux-tools/src
2)交叉编译器的安装路径:设置Paths and misc options下的Prefix directory为/home/eric/arm-linux-tools/x-tools/${CT_TARGET}
(2)修改交叉编译器针对的架构
1)设置Target options下的Architecture level为armv4t
2)设置Target options下的Emit assembly for CPU为arm9tdmi
3)设置Target options下的Tune for CPU为arm920t
以上这几个参数是如何得出来的,可以参考gcc的man手册。你可以在下载的gcc-4.9.1.tar.bz2解压后的文件夹中找到(gcc-4.9.1/gcc/doc/gcc.1)
执行以下命令打开gcc.1
- $ man ./gcc.1
你可以在其中看到下面这段:
- ......
- ARM Options
- ......
- -march=name
- This specifies the name of the target ARM architecture. GCC uses
- this name to determine what kind of instructions it can emit when
- generating assembly code. This option can be used in conjunction
- with or instead of the -mcpu= option. Permissible names are:
- armv2, armv2a, armv3, armv3m, armv4, armv4t, armv5, armv5t, armv5e,
- armv5te, armv6, armv6j, armv6t2, armv6z, armv6zk, armv6-m, armv7,
- armv7-a, armv7-r, armv7-m, armv7e-m, armv7ve, armv8-a, armv8-a+crc,
- iwmmxt, iwmmxt2, ep9312.
- -mtune=name
- This option specifies the name of the target ARM processor for
- which GCC should tune the performance of the code. For some ARM
- implementations better performance can be obtained by using this
- option. Permissible names are: arm2, arm250, arm3, arm6, arm60,
- arm600, arm610, arm620, arm7, arm7m, arm7d, arm7dm, arm7di,
- arm7dmi, arm70, arm700, arm700i, arm710, arm710c, arm7100, arm720,
- arm7500, arm7500fe, arm7tdmi, arm7tdmi-s, arm710t, arm720t,
- arm740t, strongarm, strongarm110, strongarm1100, strongarm1110,
- arm8, arm810, arm9, arm9e, arm920, arm920t, arm922t, arm946e-s,
- arm966e-s, arm968e-s, arm926ej-s, arm940t, arm9tdmi, arm10tdmi,
- arm1020t, arm1026ej-s, arm10e, arm1020e, arm1022e, arm1136j-s,
- arm1136jf-s, mpcore, mpcorenovfp, arm1156t2-s, arm1156t2f-s,
- arm1176jz-s, arm1176jzf-s, cortex-a5, cortex-a7, cortex-a8,
- cortex-a9, cortex-a12, cortex-a15, cortex-a53, cortex-a57,
- cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-m4, cortex-m3,
- cortex-m1, cortex-m0, cortex-m0plus, marvell-pj4, xscale, iwmmxt,
- iwmmxt2, ep9312, fa526, fa626, fa606te, fa626te, fmp626, fa726te.
- Additionally, this option can specify that GCC should tune the
- performance of the code for a big.LITTLE system. Permissible names
- are: cortex-a15.cortex-a7, cortex-a57.cortex-a53.
- -mcpu=name
- This specifies the name of the target ARM processor. GCC uses this
- name to derive the name of the target ARM architecture (as if
- specified by -march) and the ARM processor type for which to tune
- for performance (as if specified by -mtune). Where this option is
- used in conjunction with -march or -mtune, those options take
- precedence over the appropriate part of this option.
- Permissible names for this option are the same as those for -mtune.
- -mcpu=generic-arch is also permissible, and is equivalent to
- -march=arch -mtune=generic-arch. See -mtune for more information.
- -mcpu=native causes the compiler to auto-detect the CPU of the
- build computer. At present, this feature is only supported on
- Linux, and not all architectures are recognized. If the auto-
- detect is unsuccessful the option has no effect.
- ......
-march=name对应Architecture level
-mtune=name对应Tune for CPU
-mcpu=name对应Emit assembly for CPU
(3)设置编译时的并行进程数
1)设置Paths and misc options下的Number of parallel jobs为4
这个数值不宜过大,应该为CPU核心数量的两倍。
(4)设置编译器前缀
1)设置Toolchain options下的Tuple's vendor string为S3C2440,这样生成的编译器的前缀就是arm-S3C2440-linux-gnueabi-
4、安装termcap
- $ cd /tmp
- $ wget ftp://ftp.gnu.org/gnu/termcap/termcap-1.3.1.tar.gz
- $ tar xvzf termcap-1.3.1.tar.gz
- $ cd termcap-1.3.1
- $ ./configure --prefix=/usr
- $ make
- $ make install
5、编译
在crosstool-build目录下执行以下命令进行编译
- $ ct-ng build.4
整个编译过程时间比较长,crosstool-ng会自动下载相应的包和内核文件,然后解压、配置、编译、链接,但有个别包在自动下载过程中会出错,例如duma_2_5_15和expat-2.1.0,需要手动下载这两个包放入Local tarballs directory指定的目录(这里为/home/eric/arm-linux-tools/src),然后再重新执行编译即可。
编译过程中,在安装到cross-gdb时,出现configure: error: expat is missing or unusable的错误,安装libexpat1-dev即可。
编译过程中,出现g++: Internal error: Killed (program cc1plus)的错误,尝试着将可用内存加大。
如下图所示,代表安装成功了。
6、配置环境变量
- $ echo "PATH=$PATH:/home/eric/arm-linux-tools/x-tools/arm-S3C2440-linux-gnueabi/bin" >> ~/.bashrc
- $ source ~/.bashrc
7、确认安装完成
- $ arm-S3C2440-linux-gnueabi-gcc -v
8、编译成功后的交叉编译器路径
(1)编译器路径:/home/eric/arm-linux-tools/x-tools/arm-S3C2440-linux-gnueabi/bin
(2)库文件路径:/home/eric/arm-linux-tools/x-tools/arm-S3C2440-linux-gnueabi/arm-S3C2440-linux-gnueabi/lib
三、编译测试
1、写一个简单的C程序:Hello, World
- #include <stdio.h>
- int main() {
- printf("Hello, World ");
- return 0;
- }
2、编译
- $ arm-S3C2440-linux-gnueabi-gcc -o hello hello.c
3、上传至目标板并执行
- $ chmod +x ./hello
- $ ./hello
如上图所示,创建的交叉编译链可以成功编译成目标板能够识别的指令。
关于crosstool-ng的详细介绍和使用,请参考:http://www.crifan.com/files/doc/docbook/crosstool_ng/release/htmls/index.html
需要的依赖包下载:http://download.csdn.net/detail/jsntghf/8198753
编译后的交叉编译工具链下载:http://download.csdn.net/detail/jsntghf/8206693