组装SDK之arm交叉编译器的制作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dongkun152/article/details/81636819

组装SDK之arm交叉编译器的制作#

闲来无事,打扫出了积灰了N年的一块arm9 samsung2416的开发板,来做点事情,从组装一个SDK开始吧。 首先来制作交叉编译器。 制作交叉编译器的方法有很多,比如用buildroot,cross-ng,不过这里是手工搭建一个可以转移到不同目录或Ubuntu 64PC上的arm交叉编译器。制作的过程中搜集了很多资料,下面的每一步都经过实验。
##简介##
GCC不仅仅是一个编译器,它是一个能够构建多种编译器的开源工程。本文将说明如何编译一个arm 交叉编译器。所需要的是带有gcc的Linux的机器。本文中我的build机器是Ubuntu x86_64(buid system, BS=X86_64), 制作的是用于arm (target system, TS=arm)的c/c++ 交叉编译器(host system compiler running on, HS=x86_64)。 用这个交叉编译器编译uboot 和kernel,验证它确实可用。
这里写图片描述
在开始制作之前需要分清几个路径,源码目录,编译目录,安装目录,最后是sysroot。 sysroot是编译得到的可执行档认为的目标系统根目录。 sysroot中有完整的库和头文件,包含标准的Linux执行时的目录层次。

##需要的软件包##

$ sudo apt-get install g++ make gawk

需要相应的源码包,新建一个目录,将下列需要的源码下载下来。

$ wget http://ftpmirror.gnu.org/binutils/binutils-2.24.tar.gz
$ wget http://ftpmirror.gnu.org/gcc/gcc-4.9.2/gcc-4.9.2.tar.gz
$ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.27.tar.xz
$ wget http://ftpmirror.gnu.org/glibc/glibc-2.20.tar.xz
$ wget http://ftpmirror.gnu.org/mpfr/mpfr-3.1.2.tar.xz
$ wget http://ftpmirror.gnu.org/gmp/gmp-6.0.0a.tar.xz
$ wget http://ftpmirror.gnu.org/mpc/mpc-1.0.2.tar.gz
$ wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.12.2.tar.bz2
$ wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz

开头的四个源码包是最主要的,binutils 二进制工具集(ld,as,objdump), gcc, kernel, glibc。剩下的是编译gcc需要的库源码包。
##这些组件如何组织在一起##
完成以后我们将会获得如下图所示的一些库。我们会首先编译左边的部分,最后编译生成右边的部分。
这里写图片描述
左边部分当中,我们会首先从binutils中生成目标平台的汇编器arm-linux-as,链接器arm-linux-ld等,然后编译gcc获得交叉编译器gcc和g++。mpfr,gmp,mpc等库会被链接到交叉编译器中。
图的右边部分是一个使用交叉编译器编译的可执行程序。它使用了标准c++库的接口,还可能使用到libgcc库,标准c++库,标准c库都是glibc提供,c++库依赖c库。libgcc从gcc编译得到,libgcc会依赖c库。libc需要内核的头文件,它使用标准系统调用访问kernel。
##构建工具链的步骤##
解压下载的源码包

$ for f in *.tar*; do tar xf $f; done

在GCC目录下创建依赖库目录的符号链接,创建完成后,执行GCC编译脚本时,会自动处理相关的库。

$ cd gcc-4.9.2
$ ln -s ../mpfr-3.1.2 mpfr
$ ln -s ../gmp-6.0.0 gmp
$ ln -s ../mpc-1.0.2 mpc
$ ln -s ../isl-0.12.2 isl
$ ln -s ../cloog-0.18.1 cloog
$ cd ..

创建一个安装目录,并保证对目录有读写权限。

$ mkdir -p /home/nkd/cross/bin
$ mkdir -p /home/nkd/cross/arm-none-linux-gnueabi/libc

创建cross目录,cross目录是安装目录,libc是gcc和libc的sysroot目录,使其成为cross的子目录,可以构建可移动交叉工具链,gcc在链接c库时会从相对路径中去找。
在bashrc中添加

 export PATH=/home/nkd/cross/bin:$PATH
 export prefix=/home/nkd/cross
 export sysroot=/home/nkd/cross/arm-none-linux-gnueabi/libc

###1.Binutils###
第一步,编译binutils生成交叉汇编器,交叉链接器等工具。

$ mkdir build-binutils
$ cd build-binutils
$ ../binutils-2.24/configure --prefix=$(prefix) --target=arm-none-linux-gnueabi --with-sysroot=$(sysroot) --disable-multilib
$ make -j4
$ make install
$ cd ..
  • 我们给出的目标系统参数是arm-none-linux-gnueabi,配置脚本会识别这个参数。编译时会生成arm目标系统的汇编器和链接器,并在cross目录下生成arm-none-linux-gnueabi目录。编译出来的工具会被安装到cross/bin/目录下,会带有arm-none-linux-gnueabi前缀。
    ###2.编译stage1 crossgcc###
    在下载的源码目录下执行
$ mkdir -p build-gcc
$ cd build-gcc
$ ../gcc-4.9.2/configure --prefix=$(prefix) --target=arm-none-linux-guneabi --enable-languages=c,c++ --disable-multilib --with-gnu-ld --with-gnu-as
$ make -j4 all-gcc
$ make install-gcc
$ cd ..

执行完毕后,会在prefix/bin目录下生成arm-none-linux-gnueabi-gcc,这是第一阶段的交叉编译器。不带有libgcc交叉编译器,因为libgcc需要libc,libc又需要交叉编译的gcc。
###3.安装linux 内核头文件###
安装内核头文件

$ cd linux-3.10.27
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi INSTALL_HDR_PATH=$(sysroot)/usr headers_install
$ cd ..

剩下的就是编译glibc和gcc的后两阶段编译。编译过程中gcc和glibc内的相关组件会相互依赖,下图展示了组件的编译顺序。其中某些组件是不能被被单独编译的,按照图的编译顺序,各组件才能找到所依赖的组件最后顺利编译出来。
这里写图片描述
另外一种过程图
这里写图片描述
###4.安装glibc头文件和最初用到库###

$ mkdir -p build-glibc
$ cd build-glibc
$ ../glibc-2.20/configure --prefix=/usr --build=x86_64  --target=arm-none-linux-gnueabi --with-headers=$(sysroot)/usr/include --disable-multilib libc_cv_forced_unwind=yes
$ make install_root=$(sysroot) install-bootstrap-headers=yes install-headers
$ make -j4 csu/subdir_lib
$ install csu/crt1.o csu/crti.o csu/crtn.o $(sysroot)/usr/lib
$ arm-none-linux-gnueabi-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $(sysroot)/usr/lib/libc.so
$ touch $(sysroot)/usr/include/gnu/stubs.h
$ cd ..

首先安装头文件,编译启动和清理相关的链接库。创建空的libc库, 创建占位用的必须的stubs.h文件。
在配置glibc时,prefix必须是/usr,它是基于install_root目录的,所以install_root也必须要有。
###5. 编译stage2 crossgcc2###

$ cd build-gcc
$ rm -rf *
$ ../gcc-4.9.2/configure --prefix=$(prefix) --target=arm-none-linux-guneabi --enable-languages=c,c++ --disable-multilib --with-gnu-ld --with-gnu-as --with-sysroot=$(sysroot)
$ make -j4 all-target-libgcc
$ make install-target-libgcc
$ cd ..

注意一定要带–with-sysroot参数。
###6.编译完整的glibc库###

$ cd build-glibc
$ rm -rf *
$ ../glibc-2.20/configure --prefix=/usr --build=x86_64  --target=arm-none-linux-gnueabi --with-headers=$(sysroot)/usr/include --disable-multilib
$ make -j4
$ make install_root=$(sysroot) install
$ cd ..

###7. 编译完整的crossgcc###

$ cd build-gcc
$ rm -rf *
$ ../gcc-4.9.2/configure --prefix=$(prefix) --target=arm-none-linux-guneabi --enable-languages=c,c++ --disable-multilib --with-gnu-ld --with-gnu-as --with-sysroot=$(sysroot)
//将生成的config.status中的target_os参数改为linux-gnu
$ make -j4
$ make install
$ cp -d $(prefix)/arm-none-linux-gnueabi/lib/libgcc_s.so* $(sysroot)/lib
$ cp -d $(prefix)/arm-none-linux-gnueabi/lib/libstdc++.so* $(sysroot)/usr/lib

到此为止就已经在prefix下得到了交叉编译器,在sysroot下得到安装好的c库。 以prefix为最顶层目录,整个toolchain可以移动到任何的路径下执行(已经设置好了PATH)。
###8. 测试###
将这个toolchain安装到buildroot中,可以正确编译uboot,kernel, uboot,kernel能在板子上正常运行。

猜你喜欢

转载自blog.csdn.net/dongkun152/article/details/81636819