本次制作与前一篇类似,出来用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}
- 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!