Board logo

标题: ARM linux交叉编译 [打印本页]

作者: 苹果也疯狂    时间: 2014-6-16 13:00     标题: ARM linux交叉编译

建立ARM-Linux交叉编译环境


当然你可以下载现成的crosstool。



要进行交叉编译,用户需要在主机平台上安装对应的交叉编译工具链(cross compilation tool chain),然后用这个交叉编译工具链编译用户的源代码,最终生成可在目标平台上运行的代码.
交叉编译工具链可以从网上下载,也可以自己制作.但编译器不是万能的,受版本限制,编译某些程序时会报错.常见的交叉编译工具链有:

  
(1)Cross -2.95.3 tar:
该版本较早,除了编译vivi外一般不使用.

   (2)arm920t-eabi.tgz:
4.1.2版本的编译器,支持eabi,可以编译TX2440A开发板上的所有程序.

   (3)arm-linux-gcc:
4.3.2版本的编译器,支持eabi,是最常见的交叉工具链。

如果我们下好arm-linux-gcc加压安装以后。设置对应的环境变量就可以使用它来编译内核了。
export PATH=$PATH:/usr/local/arm/2.95.3/bin


总之照着这个搞就行了


http://blog.csdn.net/hailin0716/article/details/17578417


arm-linux-gcc-3.4.1一般用来编译2.6以上的内核版本




用上面的工具来移植系统系统

最 常用的编译版本是arm-linux-gcc-3.4.1 和 arm-linux-3.3.2 的,现在的嵌入式开发基本上用的是这些,3.4.1的用于编译2.6的内核,而3.3.2的常用于编译busybox,和bootloader(u- boot),编译的版本配合不好的话就会出错,所以要选择好编译版本,如果这个版本不行的话,可以试试其他的版本,在uclinux上用的多的就是 arm-elf-tools-20030314
关于arm-linux- toolchain,arm-elf-toochain的区别,主要是编译过程中所用的C库的不同,arm-linux用的是glibc,arm-elf 用的是newlibc,ulibc等,具体的可以去网上搜集,一般编译arm+linux的用arm-linux-,而编译uclinux则用arm- elf-
#cd /crosstool/linux2.6.1
解开内核源代码
#tar -xvzf linux-2.6.、1.tar.gz

编译内核生成头文件
修改 linux-2.6.1 的 Makefile 文件以对你的平台进行配置:
运行配置命令根据你的系统进行相关的配置
#make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-


配置完退出并保存,检查一下的内核目录中的
/crosstool/linux-2.6.1/linux-2.6.1/include/linux 下是否生成了
autoconf.h 和 version.h 这是编译 glibc 是要用到的,version.h 和
autoconf.h 文件的存在,也说明了你生成了正确的头文件。
然后执行:
#make dep



用它来编译一个很简单的程序 helloworld.c
#vi helloworld.c
#include  
int main(void)
{
printf("hello world\n");
return 0;
}
#arm-linux-gcc helloworld.c -o helloworld
#file helloworld
helloworld: ELF 32-bit LSB executable, ARM, version 1,
dynamically linked (uses shared libs), not stripped
上面的输出说明我们编译了一个能在 arm 体系结构下运行的 helloworld,证明
我们的编译工具做成功了。


























如果要自己搞,按照下面做


首先百度搜索一个  《ARM-Linux交叉编译环境的创建》PDF根据里面做,说的很好。要的东西我都下好了。东西在下面这两个网站都可以下下来。
https://www.kernel.org/
ftp://ftp.gnu.org/gnu/

在进行嵌入式Linux系统开发之前,首先要建立一个ARM-Linux交叉编译
环境,这就像在Windows下安装各类嵌入式开发的编译器一样(如Keil uvision2 ,
IAR-EWARM , ICC-AVR , ADS1.2 ,MPLAB7.11等 )。这也是一套由编译器、链
接器和libc 库等组成的开发环境。
任何一个编译器的简单编译都要经过如下几个步骤:
1、  预处理
2、  编译(语法、词义分析、生成中间代码)
3、  汇编(生成.o目标文件)
4、  链接(将库文件与中间代码链接到一起生成可执行文件)
我们的交叉编译工具需要由binutils、GCC 和glibc 几个部分组成。简单
介绍一下这几个工具的作用:
binutils:是一套用来构造和使用二进制的工具集。由下面几个部分组成:
as GNU汇编器:来将汇编语言编写的程序转换成二进制形式的目标代码。
Linux的标准汇编器是GAS,它只能编译X86的汇编语言。
ld GNU 接器:多个目标文件链接成为可执行程序。
add2line:地址转换为文件名或行号对,以便调试程序。
ar:文件中创建、修改、扩展文件。
gasp:汇编宏处理器。
nm :从目标代码文件中列举所有的变量(包括变量值和变量类型),如果
没有指定目标文件,则默认为a.out文件。
objcopy:该工具使用GNU BSD库,它可以把目标文件的内容从一种文件
格式复制到另一种格式的目标文件中。
obdump:显示目标文件信息。
readelf:显示elf目标文件的信息。
ranlib:生成索引以加快对归档文件的访问,并将其保存到这个归档文件中。
size:列出目标模块或文件的代码大小。
strings:打印可打印的目标代码字符(至少4字符)。
strip:放弃所有符号连接。
c++filt:链接器ld 使用该命令可以过滤C++符号和Java符号,防止重载函
数冲突。
gprof:显示程序调用段的各种数据。
GCC:GCC是一组编译工具的总称,按其类型,主要有以下分类:
C编译器:cc,cc1,cc1plus,gcc
C++编译器:c++,cc1plus,g++
源代码处理程序:cpp,cpp0
库文件:libgcc.a ,libgcc_eh.a , libgcc_s.so , libiberty.a , libstdc++.a ,
libstdc++.so , libsupc++.a
ARM-Linux交叉编译环境的创建

glibc:glibc内是gcc要使用的函数库,这里对库函数就不介绍了,大家可
以查阅相关资料。
实例:
下面我们将以建立针对arm的交叉编译开发环境为例来解说整个过程,其他
的体系结构与这个相类似,只要作一些对应的改动。我的开发环境是,宿主机
ix86-Redhat-9.0,目标机ARM-S3C44B0-B2开发板。
这个过程所需要的步骤如下:
1. 下载源文件、补丁和建立编译的目录
2. 建立内核头文件
3. 建立二进制工具(binutils)
4. 建立初始编译器(bootstrap gcc)
5. 建立c库(glibc)
6. 建立全套编译器(full gcc)
7.制作交叉编译器
1、下载源文件、补丁和建立编译的目录
1. 选定软件版本号
选择软件版本号时,先看看glibc源代码中的INSTALL文件。那里列举了该版本
的glibc编译时所需的binutils 和gcc的版本号。例如在glibc-2.2.3/INSTALL 文
件中推荐gcc 用2.95以上,binutils 用2.10.1 以上版本。
我选的各个软件的版本是:
linux-2.4.21.tar.gz
ftp://ftp.kernle.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz
patch-2.4.21-rmk1.gz
ftp://ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.4/patch-2.4.21-rmk1.gz
binutils-2.14.tar.gz  ftp://ftp.gnu.org/gnu/binutils/binutils-2.14.tar.gz
gcc-core-2.95.3.tar.gz  ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz
gcc-g++-2.95.3.tar.gz  ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz
gcc-2.95.3-2.patch
gcc-2.95.3-no-fixinc.patch
gcc-2.95.3-returntype-fix.patch
glibc-2.2.4.tar.gz  ftp://ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz
glibc-linuxthreads-2.2.4 ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz
gdb-6.0.tar.bz2  
ftp://ftp.gnu.org/gnu/gdb/gdb-6.0.tar.bz2
在编译glibc时,要用到Linux 内核中的include  目录的内核头文件。如果
你发现有变量没有定义而导致编译失败,你就改变你的内核版本号。例如我开始
用linux-2.4.25+vrs2,编译glibc-2.2.3 时报BUS_ISA 没定义,后来发现在
2.4.23 开始它的名字被改为CTL_BUS_ISA。如果你没有完全的把握保证你改
的内核改完全了,就不要动内核,而是把你的Linux 内核的版本号降低或升高,
ARM-Linux交叉编译环境的创建
来适应glibc。
Gcc 的版本号,推荐用gcc-2.95 以上的。太老的版本编译可能会出问题。
Gcc-2.95.3 是一个比较稳定的版本,也是内核开发人员推荐用的一个gcc 版
本。
如果你发现无法编译过去,有可能是你选用的软件中有的加入了一些新的特性
而其他所选软件不支持的原因,就相应降低该软件的版本号。例如我开始用
gcc-3.3.2,发现编译不过,报as、ld  等版本太老,我就把gcc 降为2.95.3。
太新的版本大多没经过大量的测试,建议不要选用。
2. 建立工作目录
首先,我们建立几个用来工作的目录:
我们在根目录下建立一个 crosstool 的文件夹
#pwd
/home
#cd ..
#mkdir crosstool
再在这个项目目录 crosstool 下建立 6 个目录 linux-2.4.21,binutils, gcc,
glibc ,gdb。
$cd crosstool
$mkdir linux-2.4.21 binutils gcc glibc gdb
我们把下载的源代码的压缩文件放入对应的文件夹。放好之后,各文件夹的内容
如下:
/crosstool/linux-2.4.21:linux-2.4.21.tar.gz、patch-2.4.21-rmk1.gz
/crosstool/binutils: binutils-2.14.tar.gz
/crosstool/gcc:  gcc-core-2.95.3.tar.gz 、gcc-g++-2.95.3.tar.gz 、gcc-2.95.3-2.patch、
gcc-2.95.3-no-fixinc.patch 、gcc-2.95.3-returntype-fix.patch
/crosstool/glibc: glibc-2.2.4.tar.gz 、glibc-linuxthreads-2.2.4
/crosstool/gdb:  gdb-6.0.tar.bz2
ARM-Linux交叉编译环境的创建

2.建立内核头文件
#cd /crosstool/linux2.4.21
解开内核源代码
#tar -xvzf linux-2.4.21.tar.gz
给Linux 内核打上你的补丁
#tar –xvzf patch-2.4.21-rmk1.gz
#cd linux-2.4.21
#patch -p1 < ../patch-2.4.21-rmk1
编译内核生成头文件
修改 linux-2.4.21 的 Makefile 文件以对你的平台进行配置:
#vi Makefile
修改 Makefile 的如下内容:
ARCH=arm
CROSS_COMPILE=arm-linux-
修改完之后保存
运行配置命令根据你的系统进行相关的配置
#make menuconfig
配置完退出并保存,检查一下的内核目录中的
/crosstool/linux-2.4.21/linux-2.4.21/include/linux 下是否生成了
autoconf.h 和 version.h 这是编译 glibc 是要用到的,version.h 和
autoconf.h 文件的存在,也说明了你生成了正确的头文件。
然后执行:
#make dep
ARM-Linux交叉编译环境的创建


注意


需要注意的地方:
patch -p1 < ../patch-2.4.21-rmk1  


注意这行命令里面都是数字1,没有字母l







编译内核前,首先要确保安装了
yum  install ncurses
yum  install nucrses-devel
否则会报错


$make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig  

会弹出一个设置界面



设置好之后保存退出
检查一下的内核目录中的
/crosstool/linux-2.4.21/linux-2.4.21/include/linux 下是否生成了
autoconf.h 和 version.h 这是编译 glibc 是要用到的,version.h 和
autoconf.h 文件的存在,也说明了你生成了正确的头文件。
可以在当前目录下使用命令:
#find ../ -name autoconf.h
#find ../ -name version.h



3.建立二进制工具(binutils)
#cd /crosstool/binutils
#tar -xvzf binutils-2.14.tar.gz
然后进入 binutils 目录配置和编译 binutils。
在当前目录下新建一个 build-arm-linux 文件夹,用来作为临时工作目录,配置
编译过程生成的 Makefile、目标文件、临时文件等
#cd binutils
#mkdir build-arm-linux
#cd build-arm-linux
#../../binutils-2.14/configure --target=arm-linux
--prefix=/usr/local/arm/2.95.3

--target 选项是指出交叉工具的体系结构,所有运行在主机上的交叉工具都要
配置这个选项。
--prefix 选项是指定路径前缀,编译完成之后,将安装到这个目录下。
会出现很多 check,最后产生 Makefile 文件。
执行上述的操作后,将在 build-arm-linux 下看到一个 Makefile。
有了 Makefile 后,我们来编译并安装 binutils,命令很简单。
#make
#make install
安装完成之后,我们将会在我们的目标文件夹/usr/local/arm/2.95.3/bin 内看
到如下 13 个工具:
#ls /usr/local/arm/2.95.3/bin
arm-linux-addr2line
arm-linux-c++filt
arm-linux-objcopy
arm-linux-readelf
arm-linux-strip
arm-linux-ar  arm-linux-ld  
arm-linux-objdump
arm-linux-size
arm-linux-as
arm-linux-nm
arm-linux-ranlib
arm-linux-strings
这些 GNU 开发工具都带有 arm-linux 前缀。这些工具跟主机本地的工具的使用
方法是相同的,只是处理的二进制的体系结构不同。但要使用这些工具,我们必
须在 linux 的启动脚本中添加如下环境变量:
#vi /etc/profile
在profile文件中添加如下PATH环境变量:
export PATH=$PATH:/usr/local/arm/2.95.3/bin

4.建立初始编译器(bootstrap gcc)
首先进入 gcc 目录,将下载 gcc 源代码解压
#cd /crosstool/gcc
#tar -xvzf gcc-core-2.95.3.tar.gz
#tar –xvzf gcc-g++-2.95.3.tar.gz
然后进入 gcc-2.95.3 目录给 gcc 打上补丁
#cd gcc-2.95.3
#patch -p1< ../gcc-2.95.3-2.patch
#patch -p1< ../gcc-2.95.3-no-fixinc.patch
#patch -p1< ../gcc-2.95.3-returntype-fix.patch

可以到这里下载
http://www.linuxfromscratch.org/blfs/view/5.1/general/gcc2.html
配置 t-linux 文件
因为我们现在还没有 glibc 库的支持,所以需要简单配置一些简单的选项。对于
arm-linux 工具可以通过修改
/crosstool/gcc/gcc-2.95.3/gcc/config/arm/t-linux 配置文件。
编辑 t-linux 文件,在文件末尾加入如下 2 行:
#vi /crosstool/gcc/gcc-2.95.3/gcc/config/arm/t-linux
TARGET_LIBGCC2_CFLAGS += -Dinhibit_libc -D__gthr_posix_h
T_CFLAGS = -Dinhibit_libc -D__gthr_posix_h
-Dinhibit_libc 的意思是禁止使用 libc,因为现在还没有编译出 glibc 库 。
配置,生成 Makefile
#mkdir build-arm-linux
#cd build-arm-linux
#../configure –target=arm-linux --prefix=/usr/loacal/arm/2.95.3 --with-headers=/crosstool/linux-2.4.21/linux2.4.21/include --enable-threads --enable-shared --enable-static --enable-languages=”c,c++”
这条命令中:
--target 指定交叉编译工具的目标体系结构是 arm-linux
--prefix 指定安装路径为/usr/local/arm/2.95.3
--with-headers 指定内核头文件所在的路径为:
/crosstool/linux-2.4.21/linux-2.4.21/include
--disable-shared 选项指定不使用共享库,这样就不依赖 glibc 了。
--disable-threads 选项指定不使用线程,也就不使用线程库了。
--enable-languages 指定仅支持 c 语言 。

注意:如果出现 invalid configuration "x86_64_unknown-linux-gun": machine "x86_64_unknown-linux-gun" not recognized 这样的提示,说明你可能在64位的linux 上进行编译,而你的软件版本中config.guess 和config.sub 太老了,不认64位的系统。这时你可以在命令后面加上  --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu



编译、安装
#make
#make install

注意,configure 之前要先安装gcc。


如果碰到不能make.报错:
./config/arm/arm.c: In function 'arm_override_options' :
./config/arm/arm.c:286: warning: assignment discards qualifiers from
pointer target type
./config/arm/arm.c:530: error: invalid lvalue in assignment
make[2]: *** [arm.o] Error 1
make[2]: Leaving directory `embedded/build-tools/gcc-2.95.3/gcc'
make[1]: *** [bootstrap] Error 2
make[1]: Leaving directory embedded/build-tools/gcc-2.95.3/gcc'
make: *** [bootstrap] Error 2

说明你可能没有打补丁。如果打完补丁还是不行,说明不能用高版本的gcc:  查看rpm -q gcc。 如果大于3.x, 卸了电脑系统自带的gcc,重装。(我们要装)我到这里下了一个   http://rpmfind.net/linux/rpm2html/search.php?query=gcc&system=&arch=  
  
我电脑是英特尔64位的,所以到这里下了一个3.4版本的首先到http://rpmfind.net/linux/rpm2html/search.php?query=gcc-cpp下载一个对应版本的gcc-cpp.rpm下载好了之后yum localinstall gcc-cpp.rpm然后http://rpmfind.net//linux/RPM/mandriva/10.1/x86_64/media/main/gcc-3.4.1-4mdk.x86_64.html下载gcc.rpmyum localinstall gcc.rpm这样就装好了如果报错 :autoconf没有发现之类的,因为automake 工具没有安装yum install automake如果发现 can not find output from lex;giving up  这要安装flexyum install flex

我们来看看/usr/local/arm/2.95.3/bin 里面多了哪些东西
#ls /usr/local/arm/2.95.3/bin
你会发现多了:
arm-linux-gcc 、arm-linux-unprotoize、cpp 和 gcov 几个文件。
Gcc-gnu 的 C 语言编译器
Unprotoize-将 ANSI C 的源码转化为 K&R C 的形式,去掉函数原型中的参数类
型。
Cpp-gnu 的 C 的预编译器。
Gcov-gcc 的辅助测试工具,可以用它来分析和优程序。

5.编译生成glibc库
首先解压glibc-2.2.3.tar.gz 和glibc-linuxthreads-2.2.3.tar.gz 源代码
#cd /crosstool/glibc
#tar -xvzf glibc-2.2.4.tar.gz
#cd glibc-2.2.4
#tar -xzvf ../glibc-linuxthreads-2.2.4.tar.gz
配置生成 Makefile
#mkdir build-arm-linux
#cd build-arm-linux
#CC=arm-linux-gcc \
AS=arm-linux-as \
LD=arm-linux-ld \
../configure --host=arm-linux \
--with-headers=/crosstool/linux-2.4.21/linux-2.4.21/include\
--enable-add-ons=linuxthreads –enable-shared \
--prefix=/usr/local/arm/2.95.3/arm-linux
CC=arm-linux-gcc 是把 CC 变量设成你刚编译生成的 arm-linux-gcc,用它来
编译你的 glibc。
--host 指定目标板的体系结构
--with-headers 指定内核头文件的路径为
/crosstool/linux-2.4.21/linux-2.4.21/include
-enable-add-ons=linuxthreads 支持线程库。
--enable-shared 选项支持共享库
--prefix 指定工具链目标板相关文件的目录
配置完后就可以编译和安装 glibc
#make
#make install
此时在/usr/local/arm/2.95.3/arm-linux 目录下的lib 等目录中,安装了glibc
共享库等文件。
然后你还要修改 libc.so 文件,

GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a)
改为
GROUP ( libc.so.6 libc_nonshared.a)

这样连接程序 ld 就会在 libc.so 所在的目录查找它需要的库,因为你的机子
的/lib 目录可能已经装了一个相同名字的库,一个为编译可以在你的宿主机上
运行的程序的库,而不是用于交叉编译的。
6.建立全套编译器(full gcc)
在建立bootstrap gcc的时候,我们只支持了C。到这里,我们就要建立全套编译
器,来支持C和C++。
回到 gcc 目录,修改 t-linux 文件
#cd /crosstool/gcc/gcc-2.95.3
#vi gcc/config/arm/t-linux
将我们添加的 2 行-Dinhibit_libc 去掉,因为此时不能再禁止使用 libc 了,我
们在第 5 步中已经生成了 libc
进入 build-arm-linux 清除临时目录及临时文件
#cd build-arm-linux
#make distclean
#rm –rf ./*
配置生成新的 Makefile
#../configure –target=arm-linux --prefix=/usr/loacal/arm/2.95.3 --with-headers=/crosstool/linux-2.4.21/linux2.4.21/include --enable-threads=pthreads --enable-shared --enable-static --enable-languages=”c,c++”
编译、安装
#make
#make install
我们再次进入安装目录看都多了些什么东西:
#ls /usr/loacal/arm/2.95.3/bin
你会发现多了 arm-linux-g++ 、arm-linux-protoize 和 arm-linux-c++ 几个
文件。
G++-gnu 的 c++ 编译器。
Protoize-与 Unprotoize 相反,将 K&R C 的源码转化为 ANSI C 的形式,函数原
型中加入参数类型。
C++-gnu 的 c++ 编译器。

到这里我们的交叉编译工具就算做完了,简单验证一下你的交叉编译工具。
用它来编译一个很简单的程序 helloworld.c
#vi helloworld.c
#include  
int main(void)
{
printf("hello world\n");
return 0;
}
#arm-linux-gcc helloworld.c -o helloworld
#file helloworld
helloworld: ELF 32-bit LSB executable, ARM, version 1,
dynamically linked (uses shared libs), not stripped
上面的输出说明我们编译了一个能在 arm 体系结构下运行的 helloworld,证明
我们的编译工具做成功了。

7.制作交叉调试器
1.制作交叉调试器
解压
#cd /crosstool
#cd gdb
#tar –xvzf gdb-6.0.tar.gz
配置生成 Makefile
#cd gdb-6.0
#mkdir build-arm-linux
#cd build-arm-linux
#../configure --target=arm-linux \
--prefix=/usr/local/arm/2.95.3
编译、安装
#make
#make install
安装完成后,我们在我们的目标文件夹/usr/local/arm/2.95.3/bin 内就得到了
arm-linux-gdb 工具
2.编译gdbserver
要进行交叉调试,我们的目标板还需要一个gdbserver工具。
gdbserver的源代码在gdb的gdbserver目录下:
#cd gdb-6.0
#cd gdbserver
#chmod u+x configure
#CC = arm-linux-gcc \

./configure –host=arm-linux
#make
编译完成之后,将生成gdbserver和gdbreplay可执行程序,复制到目标机的文件
系统中即可。




这个写的也很好。


http://www.amobbs.com/thread-4343647-1-1.html


http://www.ibm.com/developerworks/cn/linux/l-embcmpl/






欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0