构建ARM Linux交叉编译器

    对于构建交叉编译器的兴趣完全来源于本科毕业设计。当时因为需要使用交叉编译器,而且查找资料的过程中有很多是关于如何动手构建一个交叉编译器。只不过时间不允许,所以就没有自己动手做。现在才开始,可以说是对之前的一点升华和补充吧,最大的原因是想亲自实验一下。弄了4天(截至到前天就是12日),算是搞定了,记录如下。(目前日期07年8月14日)

第一步:找到合适的参考文献

    用baidu和google可以搜到很多构建编译器的资料,但是发现很多人在文章里头讲的东西除了他自己明白之外,估计外人是很难看懂。因为是新手,所以重要的是简洁和可模仿性。在这里推荐两篇文章:

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

这篇文章的时间很早,应该算是元老级别的,参考价值很大,缺点是现在看来版本有点低,但是绝对是很经典的。

2,http://blog.csdn.net/mlite/archive/2007/06/24/1665017.aspx

这篇文章是刚出来2个月的不久的,最大的特点是简洁扼要,容易模仿。以至于我怀着感激之情看了作者blog里的相册,天啊,竟然是华工的校友  ,从心里感概咱华工人的实在和学习的严谨。本人就是参考这篇文章来完成的。

第二步:开始投入工作

原文如下:(在原文的基础上有补充)

下载需要的文件:

Linux kernel package used: (ftp://ftp.kernel.org/pub/linux/kernel/v2.6/)
linux-2.6.17.tar.gz 

GNU compiler sources: (ftp://ftp.gnu.org/gnu/)
binutils-2.17.tar.gz
gcc-3.4.6.tar.gz
glibc-2.3.6.tar.gz
glibc-linuxthreads-2.3.6.tar.gz

Patches used: (http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/)
33_all_pr15068-fix.patch
5090_all_divdi3-asm-fix.patch
6200_all_arm-glibc-2.3.6-ioperm.patch
6230_all_arm-glibc-2.3.6-socket-no-weak-lias.patch
gcc_eh.patch.cross

这里要说的是:

    补丁文件中的“gcc_eh.patch.cross”在gentoo上找不到,可以到http://www.linuxfromscratch.org/patches/downloads上面下,文件名是glibc-2.3.6-libgcc_eh-1.patch;

    6200_all_arm-glibc-2.3.6-ioperm.patch这个补丁文件在gentoo glibc2.3.6中找到的是6200_all_arm-glibc-2.3.4-ioperm.patch,在gentoo glibc2.3.4中看到的也是6200_all_arm-glibc-2.3.4-ioperm.patch,估计是人的错误或者这个补丁是通用的,既适合2.3.4,也适合2.3.6。,事实证明是后者。

着手编译:

1. Preparation
Create project directory like this:
/root/scholar
     |
     |--toolchain
     |  |--binutils-2.17.tar.gz
     |  |--gcc-3.4.6.tar.gz
     |  |--glibc-2.3.6.tar.gz
     |  |--glibc-linuxthreads-2.3.6.tar.gz
     |
     |--patches
     |  |--33_all_pr15068-fix.patch
     |  |--5090_all_divdi3-asm-fix.patch
     |  |--6200_all_arm-glibc-2.3.6-ioperm.patch
     |  |--6230_all_arm-glibc-2.3.6-socket-no-weak-lias.patch
     |  |--gcc_eh.patch.cross
     |
     |--kernel
        |--linux-2.6.17.tar.gz

export PREFIX=/usr/local/arm/scholar

2. Building binutils-2.17
tar -zxvf binutils-2.17.tar.gz
cd binutils-2.17
mkdir arm-linux
cd arm-linux
../configure --target=arm-linux --prefix=$PREFIX --program-prefix=arm-linux-
make
make install

PATH=$PATH:/usr/local/arm/scholar/bin(这里作者的原文中没有,该命令的目的是因为后面用到了这里生成的二进制工具,所以必须添加到PATH变量中,否则后面会出错。)

3. Bootstrap GCC (First time compiling GCC without glibc, only pure-C is supported)
tar -zxvf gcc-3.4.6.tar.gz
patch -p1 -d gcc-3.4.6 < patches/33_all_pr15068-fix.patch(这样不能打成功,我使用的是绝对路径,总之是成功打上补丁就可以了。这里要补充的是,这个补丁有部分不能打上去,这得靠手动更改相关的文件才可以。)
cd gcc-3.4.6
vi gcc/config/arm/t-linux (TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h)
mkdir arm-linux
cd arm-linux
../configure --target=arm-linux --prefix=$PREFIX --program-prefix=arm-linux- --disable-threads --disable-shared --enable-languages=c
make
make install

4. Linux kernel header files (This step creates the arm-specified header files for glibc)
tar -zxvf linux-2.6.17.tar.gz
cd linux-2.6.17
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
make include/linux/version.h
cp -dR include/linux $PREFIX/arm-linux/include/linux/
cp -dR include/asm-generic $PREFIX/arm-linux/include/asm-generic/
cp -dR include/asm-arm $PREFIX/arm-linux/include/asm-arm/
mv $PREFIX/arm-linux/include/asm-arm $PREFIX/arm-linux/include/asm

5. glibc-2.3.6
tar -zxvf glibc-2.3.6.tar.gz
tar -zxvf glibc-linuxthreads-2.3.6.tar.gz --directory ./glibc-2.3.6
patch -p1 -d glibc-2.3.6 < patches/5090_all_divdi3-asm-fix.patch
patch -p1 -d glibc-2.3.6 < patches/6200_all_arm-glibc-2.3.6-ioperm.patch
patch -p1 -d glibc-2.3.6 < patches/6230_all_arm-glibc-2.3.6-socket-no-weak-lias.patch
patch -p1 -d glibc-2.3.6 < patches/gcc_eh.patch.cross 
cd glibc-2.3.6(这里作者的原文中没有,应该是疏漏)
mkdir arm-linux
cd arm-linux
CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib LD=arm-linux-ld ../configure --target=arm-linux --prefix=$PREFIX/arm-linux --host=arm-linux --enable-add-ons=linuxthreads --enable-shared --with-headers=$PREFIX/arm-linux/include
make
make install

6. gcc-3.4.6 full version (with glibc, support C/C++)
cd gcc-3.4.6
Change ./gcc/config/arm/t-linux back to original
cd arm-linux
../configure --target=arm-linux --prefix=$PREFIX --program-prefix=arm-linux- --enable-multilib --with-headers=$PREFIX/arm-linux/include --enable-languages=c,c++
make
make install

自此,整个arm-linux的工具链也就生成了.最后,可以打包发布了  !

小结:

    最终得到了交叉编译工具,收获不小。每个步骤中的make命令都是要消耗一个多小时时。当然,编译过程出错的和4个cpu的机器除外  。

    不明白的地方还很多,比如补丁程序如何选,在一个补丁目录下有那么多的补丁,一般不少于20个,为什么只选那几个,希望有高手不吝赐教, 这年头,猪肉忒贵,送上小猪  。

 

作者: cywcdwxjf   发布时间: 2010-09-14