Linux ARM交叉编译工具链制作过程
2010年11月24日
一、下载源文件 源代码文件及其版本与下载地址:
Binutils-2.19.tar.bz2 gcc-4.4.4.tar.bz2 Glibc-2.11.2.tar.bz2 Glibc-ports-2.11.tar.bz2 Gmp-4.2.tar.bz2 Mpfr-2.4.0.tar.bz2 Linux-2.6.29.tar.bz2 Patch-2.6.29.bz2 一般一个完整的交叉编译器涉及到多个软件,主要包括binutils、gcc、glibc等。其中,binutils主要生成一些辅助工具;gcc是用来生成交叉编译器,主要生成arm-linux-gcc交叉编译工具,而glibc主要提供用户程序所需要的一些基本函数库。 二、建立工作目录
编译所用主机型号 FC12.i686
第一次编译时用的是root用户(第二次用一般用户karen,该用户可以使用sudo指令)
所有的工作目录都在/home/Karen/cross下面建立完成,首先在/home/karen目录下建立cross目录 [root@localhost karen] mkdir cross 进入工作目录:
[root@localhost root]#cd /home/karen/cross
查看当前目录:
[root@localhost cross ]# pwd
/home/karen/cross
创建工具链文件夹: [root@localhost cross]# mkdir embedded-toolchains 在建立了顶层文件夹embedded- toolchains,下面在此文件夹下建立如下几个目录:
?? setup-dir,存放下载的压缩包;
?? src-dir,存放binutils、gcc、glibc解压之后的源文件;
?? kernel,存放内核文件,对内核的配置和编译工作也在此完成;
?? build-dir ,编译src-dir下面的源文件,这是GNU推荐的源文件目录与编译目录分离的做法;
?? tool-chain,交叉编译工具链的安装位;
?? program,存放编写程序;
?? doc,说明文档和脚本文件;
下面建立目录,并拷贝源文件。
[root@localhost cross] #cd embedded- toolchains
[root@localhost embedded- toolchains] #mkdir setup-dir src-dir kernel build-dir tool-chain program doc
[root@localhost embedded- toolchains] #ls
build-dir doc kernel program setup-dir src-dir tool-chain
[root@localhost embedded- toolchains] #cd setup-dir
拷贝源文件:
这里我们采用直接拷贝源文件的方法,首先应该修改setup-dir的权限
[root@localhost embedded- toolchains] #chmod 777 setup-dir 然后直接拷贝/home/karen目录下的源文件到setup-dir目录中,如下图:
建立编译目录:
[root@localhost setup-dir] #cd ../build-dir
[root@localhost build -dir] #mkdir build-binutils build-gcc build-glibc
三、输出环境变量 输出如下的环境变量方便我们编译。
为简化操作过程。下面就建立shell命令脚本environment-variables:
[root@localhost build -dir] #cd ../doc
[root@localhost doc] #mkdir scripts
[root@localhost doc] #cd scripts
用编辑器vi编辑环境变量脚本envionment-variables:
[root@localhost scripts] #vi envionment-variables
export PRJROOT=/home/mxl/diliuzhang/embedded- toolchains
export TARGET=arm-linux
export PREFIX=$PRJROOT/tool-chain
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PREFIX/bin:$PATH
截图如下:
%% Q:为什么用了source ./environment-variables才正常执行,去掉source就没有执行? %%
%% 如果用source 执行,不需要脚本有执行权限,权限为664也可以,执行命令如下:%%
%% Source environment-variables %%
说明: TARGET变量用来定义目标板的类型,以后会根据此目标板的类型来建立工具链。参
看表6-1所示。目标板的定义与主机的类型是没有关系的,但是如果更改TARGET的值,
GNU工具链必须重新建立一次。
PREFIX变量提供了指针,指向目标板工具程序将被安装的目录。
TARGET_PREFIX变量指向与目标板相关的头文件和链接库将被安装的目录。
PATH变量指向二进制文件(可执行文件)将被安装的目录。
如果不惯用环境变量的,可以直接用绝对或相对路径。如果不用环境变量,一般都用绝对路径,相对路径有时会失败。环境变量也可以定义在.bashrc文件中,这样就不用老是export这些变量了。
体系结构和TAEGET变量的对应如下表6-1所示:
表6-1 体系结构和TAEGET变量的对应 四、建立二进制工具(binutils) Binutils是GNU工具之一,它包括连接器、汇编器和其他用于目标文件和档案的工具,它是二进制代码的处理维护工具。安装Binutils工具包含的程序有addr2line、ar、as、c++filt、gprof、ld、nm、objcopy、objdump、ranlib、readelf、size、strings、strip、libiberty、libbfd和libopcodes。对这些程序的简单解释如下。
?? addr2line 把程序地址转换为文件名和行号。在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上是哪个文件以及行号。
?? ar 建立、修改、提取归档文件。归档文件是包含多个文件内容的一个大文件,其结构保证了可以恢复原始文件内容。
?? as 主要用来编译GNU C编译器gcc输出的汇编文件,产生的目标文件由连接器ld连接。
?? c++filt 连接器使用它来过滤 C++ 和 Java 符号,防止重载函数冲突。
?? gprof 显示程序调用段的各种数据。
?? ld 是连接器,它把一些目标和归档文件结合在一起,重定位数据,并连接符号引用。通常,建立一个新编译程序的最后一步就是调用ld。
?? nm 列出目标文件中的符号。
?? objcopy 把一种目标文件中的内容复制到另一种类型的目标文件中。
?? objdump 显示一个或者更多目标文件的信息。使用选项来控制其显示的信息,它所显示的信息通常只有编写编译工具的人才感兴趣。
?? ranlib 产生归档文件索引,并将其保存到这个归档文件中。在索引中列出了归档文件各成员所定义的可重分配目标文件。
?? readelf 显示elf格式可执行文件的信息。
?? size 列出目标文件每一段的大小以及总体的大小。默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
?? strings 打印某个文件的可打印字符串,这些字符串最少4个字符长,也可以使用选项-n设置字符串的最小长度。默认情况下,它只打印目标文件初始化和可加载段中的可打印字符;对于其它类型的文件它打印整个文件的可打印字符。这个程序对于了解非文本文件的内容很有帮助。
?? strip 丢弃目标文件中的全部或者特定符号。
?? libiberty 包含许多GNU程序都会用到的函数,这些程序有getopt、obstack、strerror、strtol和strtoul。
?? libbfd 二进制文件描述库。
?? libopcode 用来处理opcodes的库,在生成一些应用程序的时候也会用到它。
Binutils工具安装依赖于Bash、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Perl、Sed、Texinfo等工具
下面将分步介绍安装binutils-2.19.2的过程。
[root@localhost script] # cd $PRJROOT/src-dir
[root@localhost src-dir] # tar jxvf ../setup-dir/binutils-2.19.tar.bz2
[root@localhost src-dir] # cd $PRJROOT/build-dir/build-binutils
创建Makefile:
[root@localhost build-binutils] #../../src-dir/binutils-2.19/configure --target=$TARGET --prefix=$PREFIX 在build-binutils目录下面生成Makefile文件,然后执行make,make install。完成后可以在$PREFIX/bin下面看到我们的新的binutil。
注意:每个工具的文件名的前缀都是前面为TARGET变量设定的值。如果目标板arm-linux,那么这些工具的文件名前缀就会是arm-linux-。这样就可以根据目标板类型找到正确的工具程序。
五、建立内核头文件 在这里我们使用时2.6.29的内核版本,因为交叉工具链工具链是针对特定的处理器和操作系统的,因此在编译之前就需要对linux内核进行配制,可以通过"make config"或"make menuconfig"命令对内核进行配制,配制完成后,在linux源文件的目录下就会生成一个.config文件,这就是我们所需要的文件。
Note:目标板的内核版本是2.6.29
[root@localhost embedded- toolchains] #cd kernel [root@localhost kernel] #tar jxvf ../setup-dir/ linux-2.6.29.tar.bz2
[root@localhost kernel] #bunzip2 ../setup-dir/ patch-2.6.29.bz2
[root@localhost kernel] #cd linux-2.6.29
给Linux内核打补丁: [root@localhost linux-2.6.29] #patch p1 C库支持的程序,后面创建C库也要用到这个编译器,所以创建它主要是为创建C库做准备,如果只想编译内核和BootLoader,那么安装完这个就可以到此结束。安装过程如下:
[root@localhost build-binutils] #cd $PRJROOT/setup-dir
重命名:
[root@localhost setup-dir] #mv gcc-core-4.4.4.tar.bz2 gcc-4.4.4.tar.bz2
[root@localhost setup-dir] #cd $PRJROOT/src-dir
[root@localhost src-dir] #tar jxvf ../setup-dir/gcc-4.4.4.tar.bz2
从 GCC-4.3起,安装GCC将依赖于GMP-4.1以上版本和MPFR-2.3.2以上版本。如果将这两个软件包分别解压到GCC源码树的根目录下,并分别命名为"gmp"和"mpfr",那么GCC的编译程序将自动将两者与GCC一起编译。建议尽可能使用最新的GMP和MPFR版本。
[root@localhost src-dir]# tar jxvf ../setup-dir/mpfr-2.4.0.tar.bz2
[root@localhost src-dir]# tar jxvf ../setup-dir/gmp-4.2.tar.bz2
[root@localhost src-dir]# mv mpfr-2.4.0 gcc-4.4.4/mpfr
[root@localhost src-dir]# mv gmp-4.2.0 gcc-4.4.4/gmp
??因为是交叉编译器,还不需要目标板的系统头文件,所以需要使用 --without-headers这个选项。否则会有很多*.h头文件找不到的报错
??--enable-language=c用来告诉配置脚本,需要产生的编译器支持何种语言,现在只需支持C语言。虽然配置为c,c++也可以的
??--disable-threads 是因为threads需要libc的支持。
??--disable-decimal-float,需要libc的支持,而我们在初步编译的时候尚未生成libc,否则出现以下的报错:
../../../gcc-4.3.1/libgcc/config/libbid/bid_decima l_globals.c:52:18: error: fenv.h: No such file or directory
../../../gcc-4.3.1/libgcc/config/libbid/bid_decima l_globals.c: In function '__dfp_test_except':
../../../gcc-4.3.1/libgcc/config/libbid/bid_decima l_globals.c:64: error: 'FE_INEXACT' undeclared (first use in this function)
../../../gcc-4.3.1/libgcc/config/libbid/bid_decima l_globals.c:64: error: (Each undeclared identifier is reported only once
../../../gcc-4.3.1/libgcc/config/libbid/bid_decima l_globals.c:64: error: for each function it appears in.)
??--disable-shared,既然是第一次安装ARM交叉编译工具,那么本机的glibc支持的应该是本机的编译工具库,而不是ARM交叉编译工具库。forces GCC to link its internal libraries statically,没有这个选项,会有 crti.o: No such file: No such file or directory collect2: ld returned 1 exit status
注:由于没有arm的glibc,需要使用--disable-libmudflap --disable-libssp,禁止两个边界检查使用的库。
同样,由于第一次安装ARM交叉编译工具,那么支持的libc库的头文件也没有,src-dir/gcc-4.4.4/gcc/config/arm/t-linux文件,在TARGET_LIBGCC2_CFLAGS中添加两个定义:-Dinhibit_libc D__gthr_posix_h
原文:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer fPIC
改后:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D_gthr_posix.h
编译:
[root@localhost src-dir] #cd $PRJROOT/build-dir/build-gcc
[root@localhost build-gcc]# ../../src-dir/gcc-4.4.4/configure --target=$TARGET --prefix=$PREFIX --without-headers --enable-languages=c --disable-shared --disable-threads --disable-decimal-float disable-libmudflap disable-lipssp
[root@localhost build-gcc]# make all-gcc
[root@localhost build-gcc]# make install-gcc
[root@localhost build-gcc]# make all-target-libgcc
[root@localhost build-gcc]# make install-target-libgcc 注:很多资料中之有前面两项,这只建立了gcc,没有建立libgcc.a,这样会在glibc的编译中出现-lgcc没有找到的错误。报告:
……/build-tools/build-glibc/libc_pic.a
i586-linux-gcc -nostdlib -nostartfiles -r -o /home/wei/workspace/mywork/moblin/build-tools/buil d-glibc/elf/librtld.map.o '-Wl,-(' /home/wei/workspace/mywork/moblin/build-tools/buil d-glibc/elf/dl-allobjs.os /home/wei/workspace/mywork/moblin/build-tools/buil d-glibc/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/home/wei/workspace/mywork/moblin/build-t ools/build-glibc/elf/librtld.mapT
/workspace/wei/mywork/moblin/tools/bin/../lib/gcc/ arm-linux/4.4.4/../../../../ram-linux/bin/ld: cannot find -lgcc
在glibc的编译中,还需要libgcc_eh.a(否则出现错误:-lgcc_eh没有找到……bin/ld: cannot find -lgcc_eh),使用了--disable-shared的选项,将不会生成libgcc_eh.a,可以通过对libgcc.a的链接来实现。
[root@localhost build-gcc]# ln -vs libgcc.a `arm-linux-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'`
Note:arm-linux-gcc与-print-libgcc-file-name之间有一个空格
运行报告:
"/workspace/wei/mywork/moblin/tools/bin/../lib/gcc/ i586-linux/4.3.3/libgcc_eh.a" -> "libgcc.a" 装完成后,查看结果: [root@localhost build-gcc] #ls $PREFIX/bin
如果arm-linux-gcc等工具已经生成,表示boot trap gcc工具已经安装成功 七、编译glibc
这一步是最为繁琐的过程,目标板必须靠它来执行或者是开发大部分的应用程序。glibc套件常被称为C链接库,但是glibc实际产生很多链接库,其中之一是C链接库libc。因为嵌入式系统的限制,标准GNU C链接库显得太大,不适合应用在目标板上。所以需要寻找C链接库的替代品,在这里现以标准GNU C为例建立工具链。 [root@localhost build-gcc] #cd $PRJROOT/src-dir
[root@localhost src-dir] # tar jxvf ../setup-dir/glibc-2.11.2.tar.bz2
[root@localhost src-dir] # tar jxvf ../setup-dir/glibc-ports-2.11.tar.bz2 [root@localhost src-dir] # mv v glibc-ports-2.11 glibc-2.11.2/ports [root@localhost src-dir] # cd glibc-2.11.2 [root@localhost glibc-2.11.2] # patch Np1 i ../../setup-dir/glibc-2.11.2-gcc_fix-1.patch [root@localhost glibc-2.11.2] # patch Np1 i ../../setup-dir/glibc-2.11.2-makefile_fix-1.patch [root@localhost glibc-2.11.2] # cd $PRJROOT/build-dir/build-glibc [root@localhost build-glibc] # CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib \
../../src-dir/glibc-2.11.2/configure \
--host=arm-linux \
--prefix=$PREFIX/$TARGET \ --with-tls --disable-profile \
--enable-add-ons \ --with-headers=$PREFIX/$TARGET/include \
libc_cv_forced_unwind=yes \
libc_cv_c_cleanup=yes \ libc_cv_arm_tls=yes [root@localhost build-glibc] # make [root@localhost build-glibc] # make install 注:以上完成后,请查看一下$TARGET_PREFIX/lib目录下的文件libc.so,看看GROUP的内容是否指定到可以用于交叉编译的库,如果不是请修改,如下。 libc.so 文件(所在目录是$TARGET_PREFIX/lib),将GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a)改为GROUP ( libc.so.6 libc_nonshared.a)
这样连接程序 ld 就会在 libc.so 所在的目录查找它需要的库,因为你的机子的/lib目录可能已经装了一个相同名字的库,一个为编译可以在你的宿主机上运行的程序的库,而不是用于交叉编译的。 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 经过查看,发现libc.so中的GROUP已经是交叉编译链的目录,所以不用更改
对 libc.so 的修正.
vi $PREFIX /${TARGET}/lib/libc.so
去掉绝对路径,修改后的内容如下:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
八、建立全套编译器(full gcc)
[root@localhost build-gcc] #../../src-dir/gcc-4.4.4/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ --enable-shared
[root@localhost build-gcc] #make all
[root@localhost build-gcc] #make install
下面编写一个简单的C程序,使用建立的工具链。、
[root@localhost bin] #cd $PRJROOT/program
[root@localhost program] #vi hello.c
#include
int main(void)
{
printf("hello linux\n");
return 0;
}
[root@localhost program] #arm-linux-gcc hello.c -o hello static (制作静态可执行文件) 制作的可执行文件hello可以直接在目标机上运行。
Karen
发表评论
-
Android 目录结构
2012-01-20 12:19 694Android 目录结构 2010年11月08日 In ... -
【zz】静态库与动态库搜索路径
2012-01-20 12:19 1225【zz】静态库与动态库 ... -
实现一个最简单的嵌入式操作系统
2012-01-20 12:19 758实现一个最简单的嵌入 ... -
内核级程序开发的特点
2012-01-20 12:19 814内核级程序开发的特点 2010年06月28日 In fa ... -
Python Gossip:简介模组
2012-01-19 17:00 818Python Gossip:简介模组 2010年09月18日 ... -
python sys模块详解!
2012-01-19 17:00 3918python sys模块详解! 2011年06月28日 ... -
C++ 扩展和嵌入 Python
2012-01-19 17:00 869C++ 扩展和嵌入 Python 2011年02月17日 ... -
话说Python:非主流编程语言
2012-01-19 17:00 1021话说Python:非主流编程语言 2010年07月06日 ... -
全能选手 看看Python应乎潮流的72变
2012-01-19 17:00 727全能选手 看看Python应乎潮流的72变 2010年10月 ... -
张志晨VB实例教程之打开word方法种种
2012-01-17 06:45 1071张志晨VB实例教程之打开word方法种种 2011年08月3 ... -
暂时放一放./..脑子要炸了
2012-01-17 06:45 562暂时放一放./..脑子要炸了 2010年11月10日 f ... -
VB制作快捷打开电脑里的应用软件比如:我的电脑 网上邻居 等....
2012-01-17 06:45 615VB制作快捷打开电脑里的应用软件比如:我的电脑 网上邻居 等. ... -
vb代码2
2012-01-17 06:45 596vb代码2 2010年11月21日 ... -
天铭本期热招岗位7.19-7.25
2012-01-17 06:45 3天铭本期热招岗位7.19-7. ... -
世界各国驻中国大使馆名录(全)
2012-01-16 05:35 1177世界各国驻中国大使馆名录(全) 2009年10月07日 ... -
Flex:学习标准(转载)
2012-01-16 05:34 581Flex:学习标准(转载) 2009年12月27日 转载 ... -
藏经阁
2012-01-16 05:34 668藏经阁 2009年07月21日 藏经阁 ... -
FlashBuilder4 (FlexBuilder4)中文版下载
2012-01-16 05:34 1330FlashBuilder4 (FlexBuilder4)中 ... -
Singleton模式--个人理解
2012-01-16 05:34 591Singleton模式--个人理解 ...
相关推荐
标题中的“xilinx-arm-linux 交叉编译工具链”指的是专为Xilinx的ARM架构处理器设计的一套用于Linux系统的编译工具。这些工具使得开发者能够在一台非目标硬件(通常是运行不同操作系统如Windows或Linux的个人电脑)...
**交叉编译工具:ARM-Linux-GCC 4.5.1详解** 在嵌入式系统开发领域,尤其是针对ARM架构的设备,由于目标硬件资源有限,通常会在性能更强的主机上进行编译,这就是所谓的“交叉编译”。ARM-Linux-GCC 4.5.1就是一款...
### 制作GNU-ARM交叉编译工具链 在嵌入式系统开发中,交叉编译工具链扮演着至关重要的角色。本文将详细介绍如何构建一个GNU-ARM交叉编译工具链,包括所需的软件版本、配置参数及其含义,以及具体步骤。 #### 软件...
ARM Linux 交叉编译工具链制作是嵌入式开发中的重要环节,特别是在处理ARM架构的设备上运行Linux系统时。交叉编译允许我们在一个不同架构的主机系统(如x86)上构建针对目标系统(如ARM)的软件。下面我们将深入探讨...
使用crosstool-ng制作的MacOS下arm-linux交叉编译器,编译器版本linaro 7.2.1,支持armv8,cortex-a53,neon-vfpv4。可以在Mac下开发树莓派3程序。MacOS下需要安装到区分大小写的分区中,具体方法网上找。
GNU 工具链软件包可以生成针对不同体系结构的交叉编译工具链,例如 arm-linux-gcc、mips-linux-gcc 等。 BINUTILS BINUTILS 是二进制程序处理工具,包括连接器、汇编器等目标程序处理的工具。BINUTILS 是 GNU 工具...
### 使用crosstool制作ARM-Linux交叉编译工具链的知识点详解 #### 1. 交叉编译的概念与重要性 交叉编译是指在一个平台上(宿主机)编译代码,使其能够在另一个不同架构的平台上(目标机)运行。这种需求在嵌入式...
在本文中,我们将详细介绍构建ARMLinux交叉编译工具链的过程。构建交叉编译工具链是ARM Linux系统的开发必备步骤之一。 首先,我们需要确定目标平台。在GNU系统中,每个目标平台都有一个明确的格式,这些信息用于在...
使用环境:以X86平台,虚拟机VMware Workstation V5.5.1,RHEL4.0来建立arm交叉编译工具链。 制作交叉编译工具链的步骤: 1. 准备资源:从网上下载所需资源文件linux-2.6.27.tar.bz2、binutils-2.15.tar.bz2、gcc-...
这是ARM LINUX 下的交叉编译工具链,是用croostool制作的。制作环境是ubuntu linux 。 crosstool-ng。 使用的平台是arm920t armv4 ,arm9TDMI.
Crosstool是一款自动化创建交叉编译工具链的脚本集合,它简化了工具链的构建过程,提高了开发效率。 #### 二、Ubuntu下使用crosstool创建交叉编译工具链的步骤详解 ##### 1. 准备工作:获取必要的源码包 根据题目...
本工具链的制作运行环境是macOS Monterey 12.5.1 适用目标机Asus AX86U路由器 本工具链中各软件版本: binutils 2.28.1 glibc 2.26 Linux 4.1.52 gcc 12.2.0 gdb 12.1.0 gmp 6.2.1 mpfr 4.1.0 mpc 1.2.1 isl 0.24...
在嵌入式Linux应用开发中,交叉编译工具链是一个至关重要的组成部分,它允许开发者在宿主机(通常是基于x86架构的个人电脑)上构建适用于目标硬件平台(如ARM架构的嵌入式设备)的软件。《申延超_嵌入式Linux应用...
下面将详细介绍在Fedora 8.0上构建ARM交叉编译链的过程,以及涉及的相关知识点。 首先,理解交叉编译的基本概念至关重要。交叉编译是将源代码在不同的体系结构上编译为另一体系结构可执行代码的过程。在这个场景中...
这个过程就需要用到ARM-Linux交叉编译工具链。 交叉编译工具链包括了编译器(如GCC)、链接器、汇编器、库文件等,它们可以将源代码转化为针对目标平台的机器码。其中,`arm-linux-gcc`是常用的交叉编译器,它实际...
本文将深入探讨交叉编译、crosstool-ng的功能以及如何使用它来构建arm架构的交叉编译工具链。 首先,让我们理解什么是交叉编译。交叉编译是指在一个平台上编译出可以在另一种不同架构的系统上运行的代码。在Linux...