2009年1月23日 星期五

嵌入式LINUX ---ARM交叉編譯toolchain的編譯 - 使用crosstool

Linux 系統下ARM Linux交叉編譯環境的建立目前流行的有三種途徑。途徑一是使用別人編譯好的開發工具鏈如cross-2.95.3.tar.bz2 arm-linux-gcc-3.3.2.tar.bz2 和arm-elf-tools-20030314.sh。其中arm-elf-tools 是專門用來編譯uclinux內核的。我們常用的是cross-cross-2.95.3,下載cross-2.95.3.tar.bz2 解壓後放到/usr/local/arm 目錄下設置下PATH即可使用這是最方便快捷的方式,缺點是cross-2.95.3 GCC版本是2.95.3,版本較低,不能編譯2.6版本的Linux內核和版本較高的u-boot。cross-2.95.3.tar.bz2一般是交叉編譯2.4的linux內核的,而arm-linux-gcc-3.3.2.tar.bz2一般是交叉編譯2.6版本的內核的。途徑二自己動手慢慢編譯,這個方法是最麻煩的,需要下載很多源文件,步驟多比較繁瑣,成功率不高,極其容易出錯,即使是經驗豐富程序員,自己編譯一套完整的工具鏈也是很難成功的。網上關於這種方法的帖子很多,有毅力有耐心和專研精神的朋友不妨試試。如果是單純為開發程序建立一個開發環境來說確實沒必要在這上面浪費過多時間了。另外一種建立交叉編譯工具的途徑是使用 crosstool-0.43來編譯,目前來說比較好的交叉編譯開發工具製作方法。下面是用crosstool-0.43製作交叉編譯工具鏈的過程。

【編譯環境】
1、Ubuntu 8.04.1
2、linux-2.6.24-19
3、gcc 4.2.4
4、target:linux-2.6.15.3

【編譯步驟】

crosstool是由美國人Dan Kegel(畢業於加(利福尼亞)州工學院)開發的一套可以自動編譯不同匹配版本gcc和glibc,並作測試的腳本程序。下載地址:

http://kegel.com/crosstool/crosstool-0.43.tar.gz

在http://kegel.com/crosstool/crosstool-0.43/buildlogs/可以看到各種CPU和GCC+Glibc版本,哪些已經編譯成功,哪些部分成功,哪些徹底失敗。



注意:系統中一般不使用超級用戶(root),需要超級用戶權限時候用sudo臨時性的提高用戶權限。
而編譯crosstool時候,強烈要求不使用root用戶,以免帶來災難性後果



具體實驗步驟:
0. 先確認有安裝以下套件bison,flex,build-essential,patch,libncurses5-dev
1. 如果你當前用戶是超級用戶(root)則請登錄成普通用戶(在我們的試驗中用user用戶)
2. 創建工作目錄並拷貝相關的軟件包

[user@host ~]$ mkdir -p $HOME/downloads

把需要用的工具包拷貝到downloads目錄中。用到的工具包如下(gcc-3.4.5-glibc-2.3.6.dat中有說明,如果您的linux環境可以上網,則後面用到的安裝腳本會自動下載需要的數

據包):
gcc-3.4.5.tar.gz
glibc-2.3.6.tar.gz
linux-2.6.15.3.tar.gz
crosstool-0.43.tar.gz
binutils-2.15.tar.gz
glibc-linuxthreads-2.3.3.tar.gz
linux-libc-headers-2.6.12.0.tar.bz2
gdb-6.5.tar.bz2

3. 解壓軟件包,並進入該目錄,查看重要的腳本文件。


[user@host ~]$ cd downloads
[user@host ~/downloads]$ tar -zxvf crosstool-0.43.tar.gz
[user@host ~/downloads]$ cd crosstool-0.43


在此目錄下可以看到有很多.sh腳本和.dat配置文件,每一個支持的處理器都有它所相應的腳本。假如選用demo-arm-softfloat.sh 就是建立目標為支持軟浮點的arm交叉編譯工具

鏈。

4. 修改要使用到的script:demo-arm-softfloat.sh
最終修改後的文件是這樣的:
demo-arm-softfloat.sh

#!/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.txt

set -ex
TARBALLS_DIR=$HOME/downloads // 表示下載的source code的存放目錄
RESULT_TOP=$HOME/opt/crosstool // 表示生成的cross tool的存放目錄
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES="c,c++" // 表示將要生成的cross tool支持的語言
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 arm-softfloat.dat gcc-2.95.3-glibc-2.1.3.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-2.95.3-glibc-2.2.2.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-2.95.3-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.2.3-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.2.3-glibc-2.3.2.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.2.3-glibc-2.3.2-tls.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.3.6-glibc-2.2.2.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.3.6-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.3.6-glibc-2.3.2.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.3.6-glibc-2.3.2-tls.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.4.5-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.4.5-glibc-2.3.5.dat` sh all.sh --notest
eval `cat arm-softfloat.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest --gdb
# // 上面表示你要選cross tool的版本號!"#"起註釋功能!可以選擇一行!

echo Done.



demo-arm-softfloat.sh這個腳本在執行的時候,是執行的eval `cat arm-softfloat.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest這個批處理文件。

修改gcc-3.4.5-glibc-2.3.6.dat成以下的內容

BINUTILS_DIR=binutils-2.15
GCC_DIR=gcc-3.4.5
GLIBC_DIR=glibc-2.3.6
LINUX_DIR=linux-2.6.8 // 由於cross-compiler是編譯2.6.8的kernel,那麼修改LINUX_DIR=linux-2.6.8,因為,我們要用這一個

cross-compiler去編譯pxa270的linux-kernel,且其kernel為linux-2.6.8

GDB_DIR=gdb-6.5 // 另外,我們需要增加GDB的調試功能,在LINUX_DIR這一行後面增加一行
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.6



5. 修改arm-softfloat.dat

KERNELCONFIG=`pwd`/arm.config
TARGET=arm-softfloat-linux-gnu
TARGET_CFLAGS="-O"
GCC_EXTRA_CONFIG="--with-float=soft"
GLIBC_EXTRA_CONFIG="--without-fp"


6. 就可以執行編譯腳本了。

[user@host ~]$ ./ demo-arm-softfloat.sh

約1個多小時後,編譯完畢。
註: 如果編譯過程遇到問題,在改正問題前,請在eval `cat arm-softfloat.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest --gdb末尾處加--nounpack表示不重新解壓

安裝包,目的是讓安裝過程繼續進行,而不覆蓋掉以前的編譯結果。



7. 在利用它編譯kernel之前還要設置環境變量,

[user@host ~]$ export PATH=/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux-gnu/bin:$PATH
[user@host ~]$ source /etc/profile

以上是在當前終端上設置環境變量,如果要添加到系統環境變量中,請在/etc/profile中export PATH之前添加如下一行:

PATH=/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux-gnu/bin:$PATH
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC

在終端窗口中執行:

[user@host ~]$ source /etc/profile

下面就可以用這個交叉編譯器來編譯application和kernel了。



錯誤訊息:

錯誤一:

/home/liuwei/crosstool-0.43/build/arm-arm9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.2/build-glibc/csu/version-info.h:1:1: missing terminating " character

/home/liuwei/crosstool-0.43/build/arm-9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.2/build-glibc/csu/version-info.h:2:1: missing terminating " character

/home/liuwei/crosstool-0.43/build/arm-9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.2/build-glibc/csu/version-info.h:3:1: missing terminating " character

/home/liuwei/crosstool-0.43/build/arm-9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.2/build-glibc/csu/version-info.h:4:1: missing terminating " character

make[2]: *** [/home/liuwei/crosstool-0.43/build/arm-9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.6/build-glibc/csu/version.o] 錯誤 1

make[2]: Leaving directory `/home/liuwei/crosstool-0.43/build/arm-9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.2/glibc-2.3.6/csu'

make[1]: *** [csu/subdir_lib] 錯誤 2

make[1]: Leaving directory `/home/liuwei/crosstool-0.43/build/arm-9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.2/glibc-2.3.6'

make: *** [lib] 錯誤 2


系統在編譯生成version.o 時候發現 version-info.h 文件有錯誤

version-info.h 位於

$HOME/crosstool-0.43/build/arm-9tdmi-linux-gnu/gcc-4.1.1-glibc-2.3.2/build-glibc/csu

打開後內容如下:

"Compiled on a Linux >>2.6.22-14-generic<< system on 2008-04-12.

"

"Available extensions:

"

" GNU libio by Per Bothner\n"

" crypt add-on version 2.1 by Michael Glad and others\n"

" linuxthreads-0.10 by Xavier Leroy\n"

" BIND-8.2.3-T5B\n"

" libthread_db work sponsored by Alpha Processor Inc\n"

" NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk\n"


錯誤內容說明:第1行 2行 3行 4行缺少符號 「 」」。

正常內容應為:

"Compiled on a Linux >>2.6.22-14-generic<< system on 2008-04-12."

"Available extensions:"

" GNU libio by Per Bothner\n"

" crypt add-on version 2.1 by Michael Glad and others\n"

" linuxthreads-0.10 by Xavier Leroy\n"

" BIND-8.2.3-T5B\n"

" libthread_db work sponsored by Alpha Processor Inc\n"

" NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk\n"

version-info.h 是由 downloads目錄下的glibc-2.3.2 源文件 glibc-2.3.2/csu/ 目錄下的Makefile 執行後生成故錯誤可能發生在Makefile中。

修改方法:

解壓 glibc-2.3.2.tar.bz2 找到glibc-2.3.2/csu 目錄下的Makefile 按如下修改


文件末尾有2處echo

echo "\"Compiled on a $$os $$version system" \

"on `date +%Y-%m-%d`.\\n\"" ;; \

改為:

echo "\"Compiled on a $$os $$version system" \

"on `date +%Y-%m-%d`.\\\\n\"" ;; \


echo "\"Available extensions:\\n\"";

改為:

echo "\"Available extensions:\\\\n\"" \

保存並重新壓縮為glibc-2.3.2.tar.bz2 覆蓋原來downloads 目錄下的glibc-2.3.2.tar.bz2,轉到crosstool-0.43目錄下從新執行 demo-arm9tdmi.sh 腳本文件。


錯誤二:

提示:configure: error: installation or configuration problem: C compiler cannot create executables.

原因是因為沒有安裝:libc6-dev,運行: sudo apt-get install libc6-dev安裝

錯誤三:
出現的結果是:
configure: error:
*** These critical programs are missing or too old: gcc
*** Check the INSTALL file for required versions.

原因是因為ubuntu8.04自帶的gcc版本太新了,不必卸載系統自帶的gcc4.2.4。去下載個gcc4.1的版本安裝一下。
然後進行:

[user@host ~]$ sudo rm /usr/bin/gcc (刪除gcc,它只是個連接文件)
[user@host ~]$ sudo ln -s /usr/bin/gcc-4.1 /usr/bin/gcc (建立GCC到gcc-4.1的連接)


錯誤四:
In file included from version.c:33:
/home/skorpio/crosstool-0.43/build/powerpc-405-linux-gnu/gcc-4.1.0-glibc-2.3.6/build-glibc/csu/version-info.h:2:1: missing terminating " character
/home/skorpio/crosstool-0.43/build/powerpc-405-linux-gnu/gcc-4.1.0-glibc-2.3.6/build-glibc/csu/version-info.h:3:1: missing terminating " character
make[2]: *** [/home/skorpio/crosstool-0.43/build/powerpc-405-linux-gnu/gcc-4.1.0-glibc-2.3.6/build-glibc/csu/version.o] Error 1
make[2]: Leaving directory `/home/skorpio/crosstool-0.43/build/powerpc-405-linux-gnu/gcc-4.1.0-glibc-2.3.6/glibc-2.3.6/csu'
make[1]: *** [csu/subdir_lib] Error 2
make[1]: Leaving directory `/home/skorpio/crosstool-0.43/build/powerpc-405-linux-gnu/gcc-4.1.0-glibc-2.3.6/glibc-2.3.6'
make: *** [lib] Error 2

原來是ubuntu這傢伙搞的鬼

In Ubuntu 6.10, the default system shell, /bin/sh, was changed to dash (the Debian Almquist Shell); previously it had been bash (the GNU Bourne-Again Shell). The same change will affect users of Ubuntu 6.06 LTS upgrading directly to Ubuntu 8.04 LTS. This document explains this change and what you should do if you encounter problems.

The default login shell remains bash.

(From UBUNTU WIKI https://wiki.ubuntu.com/DashAsBinSh)

為了確認你可以在命令行下執行

[user@host ~]$ sudo rm /bin/sh (因為是soft line,所以可以直接刪掉)
[user@host ~]$ sudo ln -s /bin/bash /bin/sh


用crosstool-0.43在Ubuntu7.10下建立ARM linux交叉編譯環境
ubuntu 8.04中編譯ARM交叉平台的一點心得!
內核編譯之二:交叉編譯工具
在ubuntu下使用crosstool製作交叉編譯工具
在 Ubuntu 8.10 64bit version下用 Crosstool-0.43 建立 ARM-Linux 交叉編譯環境
Crosstool variables
在Fedora 下建立 ARM-Linux 交叉編譯環境

沒有留言: