ARM926的Linux工具链的制作和测试

时间:2021-07-25 19:43:47

ARM926的Linux工具链的制作(续 : 基于uclibc)

本次制作与前一篇类似,出来用uClibc代替了Glibc

下载的代码目录 root: /home/lake/arm-uclibc-linux
目标目录
 dir: /home/lake/arm-uclibc-linux/uclibc-tools


1. 准备工作:

下载 Binutil2.17/Gcc3.4.6/uClibc0.9.28/Linux-kernel2.6.24
Patch: 
  URL: http://gcc.gnu.org/bugzilla/attachment.cgi?id=6132
此时针对Gcc3.4编译libstd的补丁

环境设定
export PREFIX=/home/lake/arm-uclibc-linux/uclibc-tools
export TARGET=arm-uclibc-linux
export TARGET_PREFIX=$PREFIX/$TARGET
export  PATH=$PREFIX/bin:$PATH
编译的host环境是LFS6.3 /Gcc4.1.2版本,不过在Redhat Enterprise Linux4或者5上也可以编译通过。
lake:~/mysrc$ uname  -a
Linux LFS 2.6.24 #2 SMP Thu Apr 30 03:05:00 CST 2009 i686 i686 i386 GNU/Linux
lake:~/mysrc$

2.   编译binutil 
 
#mkdir binutils
# cd build_binutils 
# rm -fr * 
# ../binutils-2.17/configure --target=$TARGET --prefix=$PREFIX --disable-multilib --disable-nls 
# make all 
# make install

3. 获得核心针对ARM926的头文件
cd  ~/lfs/linux-2.6.24   
make ARCH=arm CROSS_COMPILE=arm-linux-  defconfig
#make ARCH=arm CROSS_COMPILE=arm-linux-  menuconfig ------> Select ARM type 
make ARCH=arm CROSS_COMPILE=arm-linux-  
make include/linux/version.h
cp -ar include/linux ${TARGET_PREFIX}/include/
cp -ar include/asm-arm ${TARGET_PREFIX}/include/asm
cp -ar include/asm-generic ${TARGET_PREFIX}/include/asm-generic
 cd $TARGET_PREFIX/ 
 ln -s include sys-include  ###GCC编译时候默认使用sys-include,做一个软连接

4. 编译GCC---第一阶段

patch URL: http://gcc.gnu.org/bugzilla/attachment.cgi?id=6132

lake:~/arm-uclibc-linux$ patch -p1 -d gcc-3.4.6 < gcc3.4-libstdc++-uclibc.patch
 ============================================================== 
###Compile first stage gcc 
# mkdir build_bootstrap
# cd build_bootstrap 
# rm -fr *   ----->必须删除就的编译
#  
../gcc-3.4.6/configure --target=$TARGET --prefix=$PREFIX /
--with-local-prefix=$TARGET_PREFIX --disable-multilib /
--with-newlib --disable-nls --enable-threads=no --enable-symvers=gnu /
--enable-__cxa_atexit --enable-languages=c --disable-shared /

注意有些编译器版本支持 --with-float=soft --with-softfloat-supp,这对编译U-boot有帮助,不过在Gcc3.4.6上,笔者未试成功 
# make all-gcc 
# make install-gcc


5. 编译uClibc 
================== 
#### 进入uClibc的解压目录
# make CROSS=arm-uclibc-linux-   menuconfig 
-----> Choose ARM/ARM926T   .  
-----> Kernel header dir :  /home/lake/arm-uclibc-linux/uclibc-tools/arm-uclibc-linux

if not enable GCC"--with-float=soft --with-softfloat-supp", enable the following options
-----> Enable FPU etc 
   │ │[*] Enable floating point number support        
   │ │[*]   Target CPU has a floating point unit (FPU)  
   │ │[*]   Enable full C99 math library support  

if enable GCC"--with-float=soft --with-softfloat-supp", disable all FPU options
     Target Processor Type (Arm 926T)  ---> 
   │ │[ ] Enable floating point number support     
## 以上是针对FPU软件实现的选择,在本例中,全选中FPU

# make CROSS=arm-uclibc-linux- 
# make PREFIX=$TARGET_PREFIX install


6. 完整的编译GCC链接uClibc 
================= 
###Compile final stage gcc 
# mkdir build_gcc2 
# cd build_gcc2 
# rm -fr *   ---->必须清除上次的编译文件

../gcc-3.4.6/configure --target=$TARGET --prefix=$PREFIX /
--with-local-prefix=$TARGET_PREFIX /
--enable-multilib /
--disable-nls /
--enable-threads=posix /
--enable-symvers=gnu /
--disable-__cxa_atexit /
--enable-languages=c,c++ /
--enable-shared /
--enable-c99 /
--enable-long-long /
--with-headers=$TARGET_PREFIX/include /
--with-libs=$TARGET_PREFIX/lib
# make all 
make install
注: --with-float=soft --with-softfloat-supp  软件FPU本文不支持
 
7. 修改Gcc的默认链接spec文件
这一步很重要, Gcc默认的动态连接器是/lib/ld-linux.so.x,与glibc连接。需要修改为ld-uClibc.so

=============================================================== 
## Update Cross GCC spec
vi    $PREFIX/lib/gcc/arm-uclibc-linux/3.4.6/specs
 
 %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2} 
修改为 %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}


8. OK, 我们测试一下
测试的平台为一个已经运行的ARM926的Linux系统

/mnt/lake/mysrc $ uname -a
Linux (none) 2.6.14-xxxxxx-release #1 Sat Mar 21 18:06:04 CST 2009 armv5tejl unknown
~ $ cat /proc/cpuinfo
Processor       : ARM926EJ-Sid(wb) rev 5 (v5l)
BogoMIPS        : 146.63
Features        : swp half thumb fastmult edsp java
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant     : 0x0
CPU part        : 0x926
CPU revision    : 5
Cache type      : write-back
Cache clean     : cp15 c7 ops
Cache lockdown  : format C
Cache format    : Harvard
I size          : 16384
I assoc         : 4
I line length   : 32
I sets          : 128
D size          : 16384
D assoc         : 4
D line length   : 32
D sets          : 128

Hardware        : Hi3511v100
Revision        : 0000
Serial          : 0000000000000000
~ $
目标机器昂已经存在uClibc的相关动态dll文件
/ $ ls /lib
ld-uClibc-0.9.28.so     libm-0.9.28.so          librt.so.0
ld-uClibc.so.0          libm.so.0               libthread_db-0.9.28.so
libc.so.0               libnsl-0.9.28.so        libthread_db.so.1
libcrypt-0.9.28.so      libnsl.so.0             libuClibc-0.9.28.so
libcrypt.so.0           libpthread-0.9.28.so    libutil-0.9.28.so
libdl-0.9.28.so         libpthread.so.0         libutil.so.0
libdl.so.0              libresolv-0.9.28.so     modules
libgcc_s.so             libresolv.so.0
libgcc_s.so.1           librt-0.9.28.so

测试程序
lake:~/mysrc$ cat hello.c
#include <stdio.h>

int main()
{
 printf("hello  /n");
 return 1;
}

lake:~/mysrc$ cat hello.cpp

#include <iostream>
    int main()
    {
        std::cout << "Hello, world!/n" << std::endl;
    }
lake:~/mysrc$ ~/arm-uclibc-linux/uclibc-tools/bin/arm-uclibc-linux-gcc -v
Reading specs from /home/lake/arm-uclibc-linux/uclibc-tools/lib/gcc/arm-uclibc-linux/3.4.6/specs
Configured with: ../gcc-3.4.6/configure --target=arm-uclibc-linux --prefix=/home/lake/arm-uclibc-linux/uclibc-tools --with-local-prefix=/home/lake/arm-uclibc-linux/uclibc-tools/arm-uclibc-linux --enable-multilib --disable-nls --enable-threads=posix --enable-symvers=gnu --disable-__cxa_atexit --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long --with-headers=/home/lake/arm-uclibc-linux/uclibc-tools/arm-uclibc-linux/include --with-libs=/home/lake/arm-uclibc-linux/uclibc-tools/arm-uclibc-linux/lib
Thread model: posix
gcc version 3.4.6

在host机器上编译
lake:~/mysrc$ arm-uclibc-linux-gcc  hello.c -o hello
lake:~/mysrc$ arm-uclibc-linux-g++  hello.cpp -o hellocpp

在目标机器上运行, /mnt/lake/sysrc为在目标机器上挂接的NFS目录
/mnt/lake/mysrc $ /mnt/lake/mysrc/hello
hello
/mnt/lake/mysrc $ ./hellocpp
./hellocpp: can't load library 'libstdc++.so.6'
由于目标板上/lib中没有C++需要的动态链接库,因此设定LD_LIBRARY_PATH使其指向NFS挂接的host机器上的libstdc++.so所在目录
/mnt/lake/mysrc $ echo   $LD_LIBRARY_PATH
/usr/local/lib:/usr/lib

/mnt/lake/mysrc $ export LD_LIBRARY_PATH=/mnt/lake/arm-uclibc-linux/uclibc-tools/arm-uclibc-linux/lib:$LD_LIBRARY_PATH
/mnt/lake/mysrc $ echo   $LD_LIBRARY_PATH
/mnt/lake/arm-uclibc-linux/uclibc-tools/arm-uclibc-linux/lib:/usr/local/lib:/usr/lib
/mnt/lake/mysrc $ ./hellocpp  
Hello, world!

执行成功