l前言在嵌入式系统移植的过程中,必不可少的一样东西是交叉编译器,只有使用交叉编译器才可以把原先在宿主机(相信大多数人所使用的宿主机会是Linuxx86系统的)上所编写的程序交叉编译成开发板(如ARM系统或PPC系统)所识别的二进制形式。对于一些成熟的移植过程来说,互联网上存在已经制作好的交叉编译器,只要下载过来解压缩配置后就可以使用了。但在使用这些交叉编译器的过程中可能存在着一些问题,由于自己机子上的某些环境不一样,会导致使用这些交叉编译器编译出来的内核,bootloader存在这样或那样的问题。为了去除交叉编译器对今后的编译工作带来的错误影响,最好创建属于自己的交叉编译器。l配置手动创建交叉编译器相当复杂,对于一般的嵌入式程序开发员来说,这部分知识并不是必须的。幸好我们有Dan
Kegel所写的创建交叉编译器的脚本工具crosstool。从crosstool官方网站上下载crosstool的最新版本(0.43之后就再没更新过),解压缩后得到crosstool-0.43目录,查看crosstool-0.43文件夹,可以看到目录下有很多demo-*.sh脚本和*.dat配置文件。首先需要找到你要交叉编译的平台CPU所对应的demo-*.sh脚本,比如说我要交叉编译的平台是三星的S3C2440,它的CPU是ARM9T,则选用demo-arm9tdmi.sh。如下是对该文件的说明,标红 {MOD}部分表示可根据需要进行修改,这里我们保持文件默认:#!/bin/sh
# This script has one line for each known working toolchain
# for this architecture. Uncomment the one you want.
# Generated by generate-demo.pl from buildlogs/all.dats.txtset -ex TARBALLS_DIR=$HOME/downloadsRESULT_TOP=/opt/crosstool export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES=”c,c++”
export GCC_LANGUAGES# Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don’t need to run as root.
mkdir -p $RESULT_TOP#eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.2.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.2.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.2.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.5-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh –notest eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.6-tls.dat` sh all.sh –notest #eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.5-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.6.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.6-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.1.0-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.1.0-glibc-2.3.2-tls.dat` sh all.sh –notestecho Done.TARBALLS_DIR是指创建crosstool过程中所需要的glibc,
binutils, gcc等程序的tar.bz2文件所要存放的位置,这里我把他们放在我的下载目录。Crosstool会自动的从网上下载所需的程序,但由于crosstool在下载的过程中选择的服务器会是国外的官方服务器,会比较慢,最好在build过程之前从网上把这些所需要的文件下载过来放到TARBALLS_DIR中,具体所需要的文件会在下面做介绍。RESULT_TOP指的是编译好后所生成的交叉编译器存放的目录,一定要改到有写权限的目录,不然无法编译。eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.6-tls.dat` sh all.sh –notest表示使用cross-tools顶层目录下的arm9tdmi.dat(根据CPU类型选择)和gcc-3.4.5-glibc-2.3.6-tls.dat(根据想要使用的gcc版本和glibc版本进行选择)来进行交叉编译器的创建。在crosstool官方网站的buildlog页面上可以看到各种CPU和GCC+Glibc版本那些已经编译成功,那些部分成功,那些彻底失败。如果需要更改,在修改好demo-*.sh脚本后,打开所选定的arm9tdmi.dat和
gcc-3.4.5-glibc-2.3.6-tls.dat文件首先,打开arm9tdmi.datKERNELCONFIG=`pwd`/arm.config TARGET=arm-9tdmi-linux-gnu GCC_EXTRA_CONFIG=”–with-cpu=arm9tdmi –enable-cxx-flags=-mcpu=arm9tdmi”
TARGET_CFLAGS=”-O”TARGET表示最后生成的交叉编译工具链的名称,根据自己喜欢修改。其次打开gcc-3.4.5-glibc-2.3.6-tls.datBINUTILS_DIR=binutils-2.15
GCC_DIR=gcc-3.4.5
GLIBC_DIR=glibc-2.3.6
LINUX_DIR=linux-2.6.23.8
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.6 将这里的LINUX_DIR改成你真正想要移植的Linux版本,然后这里的binutils-2.15,
gcc-3.4.5, glibc-2.3.6, linux-2.6.23.8, linux-libc-headers-2.6.12.0, glibc-linuxthreads-2.3.6就是你所要下载后放到之前提到的TARBALLS_DIR里的文件(必须是tar.bz2文件)。l步骤以root登陆Ubuntu系统,创建目录/opt/crosstool/(视demo-*.sh脚本里面的变量RESULT_TOP不同而不同)并修改其owner。这是是因为此crosstool不能以root安装,而须以username安装,安装过程会读写此目录,故需要修改属主。以用户username登陆,创建TARBALLS_DIR指定的目录,在这是系统默认的下载路径/home/username/downloads,本身已存在,不需要自己创建,但如果TARBALLS_DIR被修改过了,则要创建这个修改后的目录,这个目录将来用于自动从网上下载gcc,
binutilty,glibc等。如果自己已经下载了这些软件包,也放在这个目录下,这样就不用程序自动从网上下载了。从http://kegel.com/crosstool/下载crosstool-0.43.tar.gz到目录/opt/crosstool,,执行如下命令cd /opt/crosstool tar xzvf crosstool-0.43.tar.gz进入crosstool-0.43目录执行shdemo-arm9tdmi.sh开始创建交叉编译工具,大概要经历1到2个小时l问题与解决方案配置好crosstool后,运行脚本有可能得到如下错误问题1:. ……………….
……………….
applying patch /opt/crosstool-0.43/patches/glibc-2.3.6/arm-ctl_bus_isa.patch
getandpatch.sh: 1: patch: not found
patch /opt/crosstool-0.43/patches/glibc-2.3.6/arm-ctl_bus_isa.patch failed解决办法:通过sudo
apt-get install patch 安装patch解决这一问题问题2:……………………………………………………/home/rookiesean/workspace/crosstool-0.43/crosstool.sh: 110: bison: not foundcrosstool: You don’t have bison installed解决办法:通过sudo
apt-get install bison 安装bison解决这一问题问题3:…………………………
…………………………
/home/rookiesean/workspace/crosstool-0.43/crosstool.sh: 111: flex: not found
crosstool: You don’t have flex installed解决办法:通过sudo
apt-get install flex 安装flex解决这一问题问题4:…………………………
…………………………configure: error:*** These critical programs are missing or too old: as ld*** Check the INSTALL file for required versions.出现这种情况是因为Ubuntu默认所安装的binutils版本为binutils-2.20,当binutils太新的时候,crosstool只好将它当成太老的版本,报告说too
old; as ld. 于是我们需要重新编译安装一个老版本的binutils,
2.19或者2.18都可以被crosstool所识别,这里拿binutils-2.18举例。但还有一个问题,Ubuntu10.04默认安装的gcc版本是gcc-4.4.3,跟binutils-2.20一样,太高版本的gcc对语法要求更为严格,这样会导致binutils-2.18无法轻松的编译通过,于是我们需要编译安装一个老版本的gcc,4.1的版本可以编译成功binutils-2.18。在Ubuntu10.04可以通过解决方案:执行sudo apt-get install gcc-4.1安装gcc-4.1,安装完成后,执行如下命令:cd/usr/binsudo rm gccsudo ln -sf gcc-4.1 gccgcc -v得到如下显示:Using built-in specs.Target: i486-linux-gnuConfigured with: ../src/configure -v –enable-languages=c,c++ –prefix=/usr –enable-shared –with-system-zlib –libexecdir=/usr/lib –without-included-gettext –enable-threads=posix –enable-nls –with-gxx-include-dir=/usr/include/c++/4.1.3
–program-suffix=-4.1 –enable-__cxa_atexit –enable-clocale=gnu –enable-libstdcxx-debug –with-tune=generic –enable-checking=release i486-linux-gnuThread model: posixgcc version 4.1.3 20080704 (prerelease) (Ubuntu 4.1.2-27ubuntu1)表明原先指向gcc-4.4的的符号链接已经被重新指向新安装的gcc-4.1,系统中默认的gcc版本为4.1下载binutils-2.18,将其解压缩后,进入binutils顶层目录,运行./configure -prefix=/home/rookiesean/temp/binutils -disable-nls
make all
make install其中–prefix=/home/rookiesean/temp/binutils表示生成可执行文件的存放位置,可自定义。编译成功后在/home/rookiesean/temp/binutils/bin/中就生成了ld
as程序的可执行文件,到/usr/bin目录下面将系统默认的ld和as替换成2.18版本的:#进入/usr/bin目录cd /usr/bin/#备份as ld为后面恢复使用sudo cp as as.baksudo cp ld ld.bak#删除原来版本的as ldsudo rm as ld#替换2.18版本
ln -sf /opt/crosstool/binutils/bin/ld ld
ln -sf /opt/crosstool /binutils/bin/as as
ld -v; as -v得到如下显示:GNU ld (GNU Binutils) 2.18
GNU assembler version 2.18 (i686-pc-linux-gnu) using BFD version (GNU Binutils) 2.18表示系统默认的binutils版本已经变换为2.18版本。接下来,就可以运行demo-*.sh建立属于自己的交叉编译器了。问题5:version.c:40: error: syntax error before string constantmake[2]: *** [/opt/crosstool/crosstool-0.43/build/arm-softfloat-linux-gnu/gcc-3.4.5-glibc-2.3.6/build-glibc/csu/version.o] Error 1make[2]: Leaving directory `/opt/crosstool/crosstool-0.43/build/arm-softfloat-linux-gnu/gcc-3.4.5-glibc-2.3.6/glibc-2.3.6/csu'make[1]: *** [csu/subdir_lib] Error 2make[1]: Leaving directory `/opt/crosstool/crosstool-0.43/build/arm-softfloat-linux-gnu/gcc-3.4.5-glibc-2.3.6/glibc-2.3.6'make: *** [lib] Error 2解决办法:老版本的glibc在/bin/sh为dash的时候会出现这个问题,一种解决方法是把/bin/sh重定向为bash,在创建完交叉编译器后可以将/bin/sh重新改回dash,运行如下面命令修改/bin/sh:cd /bin
sudo mv /bin/sh sh.old
sudo ln -sf bash /bin/sh
sh –version得到如下显示:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. 重新运行demo-*.sh建立属于自己的交叉编译器了。 l恢复修改的系统设置1.恢复gcc为4.4Sudo rm /usr/bin/gccSudo ln –s /usr/bin/gcc-4.4 /usr/bin/gcc2.恢复shCd /binSudo rm shSudo mv sh.old sh3.恢复as
ldCd /usr/binSudo rm ld Sudo mv ld.bak ldSudo rm asSudo mv as.bak ashttp://blog.csdn.net/mr_raptorhttp://blog.csdn.net/fudan_abc