您的位置 首页 模拟

Linux ARM穿插编译东西链制造进程

一、下载源文件源代码文件及其版本与下载地址:Binutils-219tarbz2http:ftpgnuorggnubinutilsgcc-444tarbz2http:mirrorsk

一、下载源文件
源代码文件及其版别与下载地址:
Binutils-2.19.tar.bz2
http://ftp.gnu.org/gnu/binutils/
gcc-4.4.4.tar.bz2
http://mirrors.kernel.org/gnu/gcc/gcc-4.4.4/
Glibc-2.11.2.tar.bz2
Glibc-ports-2.11.tar.bz2
http://ftp.gnu.org/gnu/glibc/
Gmp-4.2.tar.bz2
http://ftp.gnu.org/gnu/gmp/
Mpfr-2.4.0.tar.bz2
http://ftp.gnu.org/gnu/mpfr/
Linux-2.6.29.tar.bz2
Patch-2.6.29.bz2
http://www.kernel.org/pub/linux/kernel/v2.6/

一般一个完好的穿插编译器涉及到多个软件,首要包括binutils、gcc、glibc等。其间,binutils首要生成一些辅助东西;gcc是用来生成穿插编译器,首要生成arm-linux-gcc穿插编译东西,而glibc首要供给用户程序所需求的一些根本函数库。

二、树立作业目录
编译所用主机类型 FC12.i686
第一次编译时用的是root用户(第2次用一般用户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
exportPRJROOT=/home/mxl/diliuzhang/embedded- toolchains
exportTARGET=arm-linux
exportPREFIX=$PRJROOT/tool-chain
exportTARGET_PREFIX=$PREFIX/$TARGET
exportPATH=$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变量的对应

体系结构 TARGET变量的值
PowerPC Powerpc-linux
ARM arm-linux
MIPS(big endian) mips-linux
MIPS(little endian) mipsel-linux
MIPS64 mips64-linux
SuperH3 sh3-linux
SuperH4 sh4-linux
I386 i386-linux
Ia64 ia64-linux
M68k m68k-linux
M88k m88k-linux
Alpha alpha-linux
Sparc sparc-linux
Sparc64 sparc64-linux

四、树立二进制东西(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 < ../../setup-dir/patch-2.6.29
然后便是装备内核,第一步是批改Makefile
批改 Makefile:
ARCH = arm
CROSS_COMPILE = arm-linux- menuconfig
接着运用make menuconfig进入内核装备菜单
或许直接写:
# make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig,留意在装备时一定要挑选处理器的类型,比方我的方针机运用的处理器是OMAP类型的,就选TI OMAP:
System Type -à
ARM System Type -à
(x) TI OMAP
装备完退出并保存。
装备完须履行make,参数如下:
[root@localhost linux-2.6.29]# make ARCH=arm CROSS_COMPILE=arm-linux- (履行进程中有过错呈现也不要紧,首要意图是发生头文件version.h和autoconf.h)
履行完检查一下内核目录中的/kernel/linux-2.6.29/include/linux/version.h和autoconf.h文件是不是生成了,这是编译glibc要用到的。version.h 和 autoconf.h 文件的存在,阐明你生成了正确的头文件。
接下来树立东西链需求的include目录,并将内核头文件仿制曩昔。
[root@localhost linux-2.6.29] #cd include
[root@localhost include] #ln -s asm-arm asm
能够检查一下,通过编译能够主动生成。假如现已生成链接,则不必从头链接。(2.6.29已主动生成)
[root@localhost include] #cd asm
[root@localhost asm] #ln -s arch-epxa arch
[root@localhost asm] #ln -s proc-armv proc
能够检查一下,通过编译能够主动生成。假如现已生成链接,则不必从头链接。
仿制头文件到穿插编译东西链的装置目录:
[root@localhost asm] #mkdir –p $TARGET_PREFIX/include
[root@localhost asm] #cp –r $PRJROOT/kernel/linux-2.6.29/include/linux $TARGET_PREFIX/include
[root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/include/asm-arm $TARGET_PREFIX/include/asm
[root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/include/asm-generic $TARGET_PREFIX/include
root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/arch/arm/include/asm $TARGET_PREFIX/include
root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/arch/arm/mach-omap2/include/mach $TARGET_PREFIX/include/asm
Note: mach-xxx是依据方针板所用的cpu类型来挑选的

六、树立初始编译器 (boot strap gcc)
这一步的意图首要是树立arm-linux-gcc东西,留意这个gcc没有glibc库的支撑,所以只能用于编译内核、BootLoader等不需求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_decimal_globals.c:52:18: error: fenv.h: No such file or directory
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c: In function __dfp_test_except:
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c:64: error: FE_INEXACT undeclared (first use in this function)
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c:64: error: (Each undeclared identifier is reported only once
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_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 -fP%&&&&&% -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/build-glibc/elf/librtld.map.o -Wl,-( /home/wei/workspace/mywork/moblin/build-tools/build-glibc/elf/dl-allobjs.os /home/wei/workspace/mywork/moblin/build-tools/build-glibc/libc_pic.a -lgcc -Wl,-) -Wl,-Map,/home/wei/workspace/mywork/moblin/build-tools/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

去掉肯定途径,批改后的内容如下:



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


咱们再来看看 $PREFIX/bin 里边多了哪些东西。你会发现多了 arm-linux-g++ 、和 arm-linux-c++ 几个文件。
G++-gnu的 c++ 编译器。
C++-gnu 的 c++ 编译器。
至此,整个穿插编译环境就树立完结了。
九、完结东西链的设置
root@localhost build-gcc] # cd $TARGET_PREFIX/bin
检查文件是否为二进制文件:
[root@localhost bin] # file as ar gcc ld nm ranlib strip
检查缺省的搜索途径:
[root@localhost bin] #arm-linux-gcc -print-search-dirs
十、测验和验证穿插编译东西
下面编写一个简略的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能够直接在方针机上运转。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/moni/262848.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部