幽幽
 
posts - 51,  comments - 28,  trackbacks - 0
首先,制作交叉工具链的目的是为了给我的手机--MOTO ROKR E2编译程序。
然后,顺便学习一下嵌入式软件的开发
先说一下,搞这个需要很大的耐心。
我用的硬件是Sempron3100+, 512MB内存, 编译环境是windowsXP + vmware5.5 + gentoo,
在CUI下,花了大概20个小时才编译完(我从晚上八点一直弄到第二天下午四点)。

1.
准备源码:
 binuitls-2.17
 gcc-4.1.1
 glibc-2.5
 glibc-ports-2.5
 
以上都可以在gnu.orgftp上下载
 
默认glibc不支持其它处理器, glibc-ports是支持其它处理器架构的补丁
 
另外还有kernel,我使用最新的2.19.1(kernel用于提供编译头文件)

2.
准备补丁:
 
这个可以在cross-lfs.org上面根据它的指南下载,我使用了下面的补丁:
 Binutils Branch Update
 Binutils Posix Patch
 GCC Cross Search Paths Patch
 GCC PR20425 Patch
 GCC Posix Patch
 Glibc Branch Update
 Glibc Cross-Compiling Hacks Patch
 Glibc Disable linking with libgcc_eh.a
 Glibc Localedef Segfault

 
准备编译环境,我直接使用的debian(sid)并且所有包都是最新状态,另外需要安装texinfo, gawk(注意mawk编译glibc header时会有问题), bison, flex

4.
准备环境变量.我写了一个pre.sh,所有相关内容都放里面
 set +h #
关闭bashhash功能,hash功能用来记忆系统中所有可执行文件来避免查找path. 编译时可能会增加新的同名可执行程序在其它目录下
 umask 022
 export CLFS_HOST="$(echo $MACHTYPE | sed "s/$(echo $MACHTYPE | cut -d- -f2)/cross/")"
 export CLFS_TARGET="arm-unknown-linux-gnu"
 export CLFS=/home/lizl/arm
 export LC_ALL=POSIX #
旧的libc2.2.4以下在LOCALE为其它时chroot回来可能会有异常
 export PATH=$CLFS/bin:$PATH

 # CFLAGS
CXXFLAGS对编译时可能会有影响
 unset CFLAGS
 unset CXXFLAGS


5.
准备环境.执行source pre.sh后执行下面的操作:
 install -dv ${CLFS} #
创建目标目录
 install -dv ${CLFS}/include
 install -dv ${CLFS}/usr/include

 
另外最好使用其它用户身份去进行编译的操作, 因为root可能会对系统造成破坏.建议创建一个clfs用户和组专门操作(我是直接使用的root):
 groupadd clfs #
增加组
 useradd -s /bin/bash -g clfs -m -k /dev/null clfs #
创建用户
 passwd clfs #
给用户指定口令
 chown -Rv clfs ${CLFS} #
修改输出目录的权限
 CLFS
建议clfs帐号登录时, 最好不要被系统中其它环境变量影响, 所以它在clfs帐号的~/.bash_profile里面写入下面内容:
 exec env -i HOME=${HOME} TERM=${TERM} PS1='\u:\w\$ ' /bin/bash
 
因为我是root, 没有修改.

 su - clfs #
切换到clfs用户执行操作

 
开始创建一些目录. 这里我没有创建, 因为我只需要gcc, binutilsglibc这三个

6.
编译binutils:
 
下载binutils-2.17并解压.
 
下载补丁:
 
注意安装gcc bison flex texinfo
 
不然编译过程会出错

 
我编译时报的错是 missing makeinfo
 
然后安装了texinfo还是不行
 
后面检查makefile才发现bison等都没有安装

 patch -Np1 -i ../patch/binutils-2.17-posix-1.patch
 patch -Np1 -i ../patch/binutils-2.17-branch_update-1.patch

 binutils
建议编译时在其它目录编译,所以我们创建binutils-build并在里面执行操作
 mkdir -v ../binutils-build
 cd ../binutils-build

 
 
如果你在binutils-2.17执行操作的话,那后面的make configure-host时可能会报错
 
我因为报错然后重做了一下干净的解压目录重执行

 
开始配置
 ../binutils-2.17/configure --prefix=${CLFS} \
  --host=${CLFS_HOST} --target=${CLFS_TARGET} --with-sysroot=${CLFS} \
  --disable-nls --enable-shared --disable-multilib

 
检查看主机上的运行条件是不是符合
 make configure-host

 
编译并安装:
 make
 make install
 cp -v ../binutils-2.17/include/libiberty.h ${CLFS}/usr/include


7.
安装内核头文件:
 clfs
中是直接复制目录, 我则是先make menuconfig然后修改一此事配置后才复制的

 clfs
中操作:
 install -dv ${CLFS}/usr/include
 cp -av include/{asm-generic,linux,mtd,scsi,sound} ${CLFS}/usr/include
 cp -av include/asm-arm ${CLFS}/usr/include/asm

 
我的操作:
 make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig

 
menuconfig里面load一个别人的2410的配置然后退出并保存
 cp -av include/{asm-generic,linux} ${CLFS}/usr/include
 cp -av include/asm-arm ${CLFS}/usr/include/asm

8.
安装glibc的头文件.
 
先把3.4的依赖去掉
 cd glibc-2.5
 cp configure{,.orig}
 sed -e 's/3.4/3.[0-9]/g' configure.orig > configure

 
然后解压glibc-ports
 tar -jxvf ../glibc-ports-2.5.tar.bz2
 mv -v glibc-ports-2.5 ports

 
注意是解压到当前目录(glibc-2.5),不然执行后面的configure时会报cpu不支持
 
然后开始准备编译目录, 同上, 我们也在其它目录下进行编译
 mkdir -v ../glibc-build
 cd ../glibc-build

 
为打开NPTL支持进行如下操作:
 echo "libc_cv_forced_unwind=yes" > config.cache
 echo "libc_cv_c_cleanup=yes" >> config.cache
 echo "libc_cv_arm_tls=yes" >> config.cache

 
然后把安装路径指定一下:
 echo "install_root=${CLFS}" > configparms

 
再执行下面的编译:
 CC=gcc ../glibc-2.5/configure --prefix=/usr --host=${CLFS_TARGET} --build=${CLFS_HOST} --with-headers=${CLFS}/usr/include --cache-file=config.cache
 make install-headers

 
由于awk语法兼容原因,如果安装mawk的话上面的步骤会出错, 安装gawk则不会
 
有一些文件还没有被自动复制过去, 需要手工复制:
 install -dv ${CLFS}/usr/include/bits
 cp -v bits/stdio_lim.h ${CLFS}/usr/include/bits
 touch ${CLFS}/usr/include/gnu/stubs.h
 cp -v ../glibc-2.5/ports/sysdeps/unix/sysv/linux/arm/nptl/bits/pthreadtypes.h \
 ${CLFS}/usr/include/bits

9.
安装gcc第一次,这次是为了编译交叉版本的glibcgcc,先打补丁
 patch -Np1 -i ../patch/gcc-4.1.1-posix-1.patch
 patch -Np1 -i ../patch/gcc-4.1.1-cross_search_paths-1.patch

 
然后同样创建编译目录并在里面进行编译:
 mkdir -v ../gcc-build
 cd ../gcc-build
 ../gcc-4.1.1/configure --prefix=${CLFS} --host=${CLFS_HOST} --target=${CLFS_TARGET} --disable-multilib --with-sysroot=${CLFS} --disable-nls --disable-shared --enable-languages=c
 make all-gcc
 make install-gcc

10.
安装glibc
 
在前面安装glibc的头时已经做了一些事情,如把port解压. 现在做的先是给glibc打补丁:
 cd glibc-2.5
 patch -Np1 -i ../patch/glibc-2.5-libgcc_eh-2.patch
 patch -Np1 -i ../patch/glibc-2.5-localedef_segfault-1.patch
 patch -Np1 -i ../patch/glibc-2.5-cross_hacks-2.patch
 patch -Np1 -i ../patch/glibc-2.5-branch_update-1.patch
 
然后创建编译目录并开始编译:
 cd ../glibc-build
 rm -rf *
 
为支持NPTL做如下操作:
 echo "libc_cv_forced_unwind=yes" > config.cache
 echo "libc_cv_c_cleanup=yes" >> config.cache
 
指明安装目录:
 echo "install_root=${CLFS}" > configparms
 
开始编译:
 BUILD_CC="gcc" CC="${CLFS_TARGET}-gcc" AR="${CLFS_TARGET}-ar" RANLIB="${CLFS_TARGET}-ranlib" ../glibc-2.5/configure --prefix=/usr --libexecdir=/usr/lib/glibc --host=${CLFS_TARGET} --build=${CLFS_HOST} --disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 --with-__thread --with-binutils=${CLFS}/bin --with-headers=${CLFS}/usr/include --cache-file=config.cache

 
由于使用的是2.6.19的内核, 内核中使用了新的netlink接口, 把一些宏去掉了
 
参考maillist可知这些定义已经不在内核中使用, 但是应该还在用户空间使用
 CLFS
中对最新内核的支持现在只到2.6.18.2
 
所以用2.6.19的需要自己修改一下:
 
修改目录和文件为:
 glibc-2.5/sysdeps/unix/sysv/linux# grep IFA * -l
  check_pf.c
  if_index.c
  ifaddrs.c
 
在上面的文件中增加如下内容:
 #include <linux/if_addr.h>

 #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
 #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
 #define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
 #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
 
然后执行下面操作
 make
 make install

 
下面安装locale, 如果想安装全部locale的话可以执行下面的命令(时间比较长, 可能有半小时):
 make localedata/install-locales
 
而如果你不想全装, 只想装某些localeclfs推荐按下面命令执行:
 mkdir -pv ${CLFS}/usr/lib/locale
 export I18NPATH=${PWD}/localedata
 export GCONV_PATH=${PWD}/iconvdata
 export LOCALEDEF="${PWD}/locale/localedef-native --alias-file=../intl/locale.alias"
 cd ../glibc-2.5/localedata
 ${LOCALEDEF} -i locales/de_DE -f charmaps/ISO-8859-1 --prefix=${CLFS} de_DE
 ${LOCALEDEF} -i locales/de_DE@euro -f charmaps/ISO-8859-15 --prefix=${CLFS} de_DE@euro
 ${LOCALEDEF} -i locales/en_HK -f charmaps/ISO-8859-1 --prefix=${CLFS} en_HK
 ${LOCALEDEF} -i locales/en_PH -f charmaps/ISO-8859-1 --prefix=${CLFS} en_PH
 ${LOCALEDEF} -i locales/en_US -f charmaps/ISO-8859-1 --prefix=${CLFS} en_US
 ${LOCALEDEF} -i locales/es_MX -f charmaps/ISO-8859-1 --prefix=${CLFS} es_MX
 ${LOCALEDEF} -i locales/fa_IR -f charmaps/UTF-8 --prefix=${CLFS} fa_IR
 ${LOCALEDEF} -i locales/fr_FR -f charmaps/ISO-8859-1 --prefix=${CLFS} fr_FR
 ${LOCALEDEF} -i locales/fr_FR@euro -f charmaps/ISO-8859-15 --prefix=${CLFS} fr_FR@euro
 ${LOCALEDEF} -i locales/it_IT -f charmaps/ISO-8859-1 --prefix=${CLFS} it_IT
 ${LOCALEDEF} -i locales/ja_JP -f charmaps/EUC-JP --prefix=${CLFS} ja_JP
 unset I18NPATH GCONV_PATH LOCALEDEF
 
个人认为如果不想全装, 直接修改一下localedata/Makefile,把不需要的locale去掉后再执行第一种方法可能更简单. 这里我执行的是第一种方法.

11.
配置glibc运行信息
 
如果不配置的话glibc也会有默认配置, 但是在网络环境下可能不正常. 所以需要配置一下.
 
用如下命令创建文件/etc/nsswitch.conf,当然直接编辑更快(直接编辑时把后面的EOF去掉):
 cat > ${CLFS}/etc/nsswitch.conf << "EOF"
 # Begin /etc/nsswitch.conf

 passwd: files
 group: files
 shadow: files

 hosts: files dns
 networks: files

 protocols: files
 services: files
 ethers: files
 rpc: files

 # End /etc/nsswitch.conf
 EOF
 
然后用下面命令配置一下时区:
 TZDIR="${CLFS}/usr/share/zoneinfo" ${CLFS}/usr/bin/tzselect
 
回答一些问题后, 使用下面命令保存timezone:
 cp -v --remove-destination ${clfs}/usr/share/zoneinfo/[xxx] \
  ${clfs}/etc/localtime
 [xxx]
就是上面的结果.
 
我的结果是:
 TZ='Asia/Shanghai'; export TZ
 
所以命令是:
 cp -v --remove-destination ${clfs}/usr/share/zoneinfo/'Asia/Shanghai' ${clfs}/etc/localtime


12.
配置动态装载器(如果你有库文件放在/lib/usr/lib外的其它目录的话)
 
动态装载器(/lib/ld-linux.so.2) /lib/usr/lib目录下查找程序需要的动态库.
 
如果动态库所在目录不上上面两个目录下, 那需要把它的目录写到/etc/ld.so.conf.
 
一般/usr/local/lib/opt/lib目录也需要查找.
 
如果你有动态库放在这两个目录下的话, 做如下操作(我没有所以不做):
 cat > ${CLFS}/etc/ld.so.conf << "EOF"
 # Begin /etc/ld.so.conf

 /usr/local/lib
 /opt/lib

 # End /etc/ld.so.conf
 EOF

13.
编译gcc. 前面已经编译过一次. 前面的编译是为了创建交叉版本的glibc, 现在则是创建交叉版本的gcc.
 
先打补丁
 cd gcc-4.1.1
 patch -Np1 -i ../patch/gcc-4.1.1-posix-1.patch
 patch -Np1 -i ../patch/gcc-4.1.1-PR20425-1.patch
 patch -Np1 -i ../patch/gcc-4.1.1-cross_search_paths-1.patch
 
第一个和每三个前面都已经打过了, 所以这里只需要再打第二个就可以了
 
然后创建编译目录:
 mkdir -v ../gcc-build
 cd ../gcc-build
 ../gcc-4.1.1/configure --prefix=${CLFS} \
  --host=${CLFS_HOST} --target=${CLFS_TARGET} --disable-multilib \
  --with-sysroot=${CLFS} --disable-nls --enable-shared \
  --enable-languages=c,c++ --enable-__cxa_atexit \
  --enable-c99 --enable-long-long --enable-threads=posix
 make
 make install

14.
交叉编译工具链已经做好,现在就小试一下牛刀,马上来个Hello World

posted on 2008-02-10 16:18 幽幽 阅读(1964) 评论(0)  编辑 收藏 引用 所属分类: Linux

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2008年2月>
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678

常用链接

留言簿(5)

随笔分类(35)

随笔档案(51)

文章分类(3)

文章档案(3)

相册

我的链接

搜索

  •  

最新评论

阅读排行榜

评论排行榜