寫在前面:
本系列文章將詳細的講述AT91RM9200引導程序的建立過程,其中包括建立交叉編譯工具鏈,gdb+gdbserver的編譯安裝使用,tftp,NFS的安裝使用,超級終端或者minicom的使用,內核的編譯升級,U-Boot的移植,Ramdisk、根文件系統的建立製作,busybox的編譯、應用等。從而重現完整的開發過程。在寫這個文檔的過程中,本人蔘考了許多資料,在這裏要感謝互聯網,感謝所有社區,論壇裏無私提供幫助的同行們。特別感謝一下魯鬱先生,是他讓我在AT91RM9200上成功的移植了U-Boot<?XML:NAMESPACE PREFIX = ST1 />1.1.4。本人是從不懂一路走來,走的過程中將開發過程詳細記述下來,從一個初學者的角度來寫下這個系列的文章,以方便其他初學者能得到一些幫助,少走一些彎路。本系列文章主要講述開發過程及實際應用,並不能很好的講述一些原理性的東西,所以您在看這篇文章的時候最好要參考其他資料,以形成一個完整的知識鏈。祝你旅途愉快。
開發環境
軟件環境<?XML:NAMESPACE PREFIX = O />
宿主機:Redhat9.0 ,虛擬機vmware5.5.1
U-Boot 1.1.4, busybox1.2.2.1
硬件環境
CPU:AT91RM9200 ,180MHz(200MIPS)
存儲器:32M SDRAM(MT48LC8M16A2)
64Mbits Flash(SST39VF6401B)
USB接口:USB-Host USB-Device
網絡接口: 10/100M DM9161E
DBGU串行調試接口
JTAG接口
移植過程
虛擬機
關於虛擬機的安裝使用,這裏就不介紹了。使用很方便,網上也有大量的資料。大家可自行查閱。我們使用的是5.5.1版本,當然,你也可以使用最新的版本。
建立交叉編譯工具鏈。
交叉編譯工具鏈就是爲了在一個平臺體系結構下(如X86 PC機)能編譯,鏈接,處理和調試另一個平臺體系結構下(如ARM)的程序,使得編譯生成的程序能夠在另一平臺下運行。
Linux使用的工具鏈軟件是:Binutils,gcc,glibc,gdb。
其中binutils是二進制程序處理工具。gcc是編譯器。glibc是應用程序編程的函數庫文件軟件包。gdb是調試工具。
對交叉編譯工具鏈的編譯是很麻煩和瑣碎的一件事,如果自己一個一個編譯,很可能會遇到各種各樣的麻煩。幸好有人做了一套腳本程序,可以很方便的生成你所需要的交叉編譯工具鏈。我們使用的腳本就是crosstool,關於詳細內容可以訪問http://kegel.com/crosstool/,可以從該網站下載到它的腳本,補丁和文檔。
本文以i686平臺,虛擬機vmware5.5.1,redhat9.0來建立arm交叉編譯工具鏈。
我們採用crosstool0.42來作爲我們編譯交叉編譯工具鏈的腳本。詳細的用法說明請閱讀網站上的文檔crosstool-how to 。
[zzl@localhost] tar -xzvf crosstool-0.42.tar.gz
[zzl@localhost]cd crosstool-0.42
我們可以看到目錄下有很多.sh腳本和.dat配置文件。每一個支持的CPU都有它所相應的腳本,如我們選用demo-arm-softfloat.sh 就是建立目標爲支持軟浮點的arm的交叉編譯工具鏈。其中需要我們記住的三個重要的變量:
TARBALLS_DIR=$HOME/downloads
RESULT_TOP=/opt/crosstool
GCC_LANGUAGES="c,c++"
第一行指明我們放置源代碼軟件包的目錄,我的主目錄是/home/zzl。第二行指明我們生成的交叉編譯工具鏈在/opt/crosstool下。第三行表示,我們的交叉編譯工具鏈支持c,c++語言。
所以,你的首要任務是下載這些源代碼軟件包,並將它們放在/home/zzl/downloads下面,保證這些包的所有者爲當前用戶而不是根用戶。
由於我們以後的內核版本爲2.6.17,所以我們還需要下載linux2.6.17的內核包,並放在/home/zzl/downloads/下。
我們選擇的配置是:demo-arm-softfloat.sh,其內容具體如下:
#!/bin/sh
set -ex
TARBALLS_DIR=$HOME/downloads
RESULT_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
# Build the toolchain. Takes a couple hours and a couple gigabytes.
#eval `cat arm-softfloat.dat gcc-3.3.3-glibc-2.3.2.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.4.0-glibc-2.3.2.dat` sh all.sh --notest
eval `cat arm-softfloat.dat gcc-3.4.1-glibc-2.3.3.dat` sh all.sh --notest
#eval `cat arm-softfloat.dat gcc-3.4.1-glibc-20040827.dat` sh all.sh --notest
echo Done.
從這一行eval `cat arm-softfloat.dat gcc-3.4.1-glibc-2.3.3.dat` sh all.sh --notest
可以看出,我們的gcc版本採用3.4.1,glibc版本採用2.3.3。
我們再來看gcc-3.4.1-glibc-2.3.3.dat這個文件
BINUTILS_DIR=binutils-2.15
GCC_DIR=gcc-3.4.1
GLIBC_DIR=glibc-2.3.3
LINUX_DIR=linux-2.6.8
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.3
由於我們採用的是Linux-2.6.17的內核包,所以這裏要將linux-2.6.8改成linux-2.6.17。否則,腳本執行解壓縮時,找不到linux源代碼包。
建立我們的目標生成目錄
[zzl@localhost]sudo mkdir /opt/crosstool
[zzl@localhost]sudo chown zzl /opt/crosstool
執行我們的配置文件arm-softfloat.sh
[zzl@localhost]sh demo-arm-softfloat.sh
這裏要注意運行該配置文件不能以root來運行,crosstool-0.42, /opt/crosstool爲非root用戶所有。
如果一切順利的話,經過一段時間的等待,得到一個新目錄:(如果不順利且始終找不到錯誤原因的話,我建議你重新安裝redhat9.0的操作系統,然後按照先前步驟進行。:))
/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu
交叉編譯工具就在該目錄的bin/下
[zzl@localhost]ls –l /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/bin
總用量 29184
-rwxr-xr-x 1 zzl zzl 1806212 12月 29 09:02 arm-softfloat-linux-gnu-addr2line
-rwxr-xr-x 2 zzl zzl 1864030 12月 29 09:02 arm-softfloat-linux-gnu-ar
-rwxr-xr-x 2 zzl zzl 3248953 12月 29 09:02 arm-softfloat-linux-gnu-as
-rwxr-xr-x 2 zzl zzl 287996 12月 29 09:43 arm-softfloat-linux-gnu-c++
-rwxr-xr-x 1 zzl zzl 1761855 12月 29 09:02 arm-softfloat-linux-gnu-c++filt
-rwxr-xr-x 1 zzl zzl 287111 12月 29 09:43 arm-softfloat-linux-gnu-cpp
-rwxr-xr-x 2 zzl zzl 287996 12月 29 09:43 arm-softfloat-linux-gnu-g++
-rwxr-xr-x 2 zzl zzl 285852 12月 29 09:43 arm-softfloat-linux-gnu-gcc
-rwxr-xr-x 2 zzl zzl 285852 12月 29 09:43 arm-softfloat-linux-gnu-gcc-3.4.1
-rwxr-xr-x 1 zzl zzl 16241 12月 29 09:43 arm-softfloat-linux-gnu-gccbug
-rwxr-xr-x 1 zzl zzl 103366 12月 29 09:43 arm-softfloat-linux-gnu-gcov
-rwxr-xr-x 1 zzl zzl 2286490 12月 29 09:02 arm-softfloat-linux-gnu-gprof
-rwxr-xr-x 2 zzl zzl 2542659 12月 29 09:02 arm-softfloat-linux-gnu-ld
-rwxr-xr-x 2 zzl zzl 1840205 12月 29 09:02 arm-softfloat-linux-gnu-nm
-rwxr-xr-x 1 zzl zzl 2344807 12月 29 09:02 arm-softfloat-linux-gnu-objcopy
-rwxr-xr-x 1 zzl zzl 2487727 12月 29 09:01 arm-softfloat-linux-gnu-objdump
-rwxr-xr-x 2 zzl zzl 1864029 12月 29 09:02 arm-softfloat-linux-gnu-ranlib
-rwxr-xr-x 1 zzl zzl 384396 12月 29 09:02 arm-softfloat-linux-gnu-readelf
-rwxr-xr-x 1 zzl zzl 1712993 12月 29 09:01 arm-softfloat-linux-gnu-size
-rwxr-xr-x 1 zzl zzl 1689683 12月 29 09:02 arm-softfloat-linux-gnu-strings
-rwxr-xr-x 2 zzl zzl 2344806 12月 29 09:02 arm-softfloat-linux-gnu-strip
-rwxrwxr-x 1 zzl zzl 19084 12月 29 09:43 fix-embedded-paths
我們可以看出,交叉編譯的所有工具都在這裏。
將這個路徑加進PATH變量中:
[zzl@localhost]export PATH=$PATH :/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/bin
如果每次都要輸入上面的shell命令,的確是比較煩人的事情。我們可以在linux啓動腳本中添加該語句。從而避免每次開機後重新輸入。我是在啓動腳本/etc/profile中添加了環境變量。
找到這一行export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
在其上面一行添加:
PATH=$PATH :/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/bin
今後我們編譯程序的時候,就用arm-softfloat-linux-gnu-gcc 來編譯我們的程序。
當然,應用程序的調試是開發過程中必不可少的環節之一。Linux下的GNU的調試器即是GDB。所以我們有了這個交叉編譯工具鏈之後,可以用它來編譯gdb和gdbserver。如果你暫時不需要GDB的話,也可以先略過這一步。
GDB的編譯安裝
目前比較新的是版本是GDB6.6。其官方網站是http://www.gnu.org/software/gdb/。
下載gdb-6.6.tar.gz源代碼包到/usr/src下。
[root@localhost]tar –zxvf gdb-6.6.tar.gz
[root@localhost]cd gdb-6.6
配置很簡單,只需要指定目標板體系結構和安裝路徑即可。
[root@localhost]mkdir /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/gdb6.6
[root@localhost]./configure --target=arm-softfloat-linux-gnu --prefix=/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/gdb6.6 -v
[root@localhost]make
[root@localhost]make install
順利的話,則在gdb6.6下生成新的目錄,其中gdb工具就在bin目錄下。
[root@localhost]ls –l /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/gdb6.6
/bin
總用量 30476
-rwxr-xr-x 1 root root 14335251 12月 29 15:53 arm-softfloat-linux-gnu-gdb
-rwxr-xr-x 1 root root 14335296 12月 29 15:53 arm-softfloat-linux-gnu-gdbtui
-rwxr-xr-x 1 root root 2489663 12月 29 15:52 arm-softfloat-linux-gnu-run
同樣在環境變量中添加gdb的路徑
[root@localhost]export PATH=$PATH :/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/gdb6.6/bin
今後調試程序的時候,用arm-softfloat-linux-gnu-gdb 來調試。
gdbserver的編譯
[root@localhost]cd gdb-6.6
[root@localhost]cd gdb/gdbserver
[root@localhost] ./configure --target=arm-softfloat-linux-gnu –-host=arm-softfloat-linux-gnu
[root@localhost] make CC=/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-softfloat-linux-gnu/bin/arm-softfloat-linux-gnu-gcc
如果不出錯的話,將在當前目錄下生成兩個可執行文件:gdbserver和gdbreplay。以後就可以用gdb+gdbserver調試我們開發板上的程序了。至此,我們的交叉編譯工具鏈已經基本建立。可以用來作爲我們bootloader的編譯環境了。
GDB+GDBServer的使用
在目標系統上啓動gdbserver,其實就是在超級終端下或者minicom下啓動gdbserver。這裏將gdbserver放在宿主機的NFS設置的共享目錄下/home/zzl,該目錄掛載在目標板/work下。宿主機的ip爲192.168.1.1,目標板的ip爲192.168.1.33
超級終端或者minicom下
[root@localhost]cd /work
[root@localhost]./gdbserver 192.168.1.1:1234 hello
出現提示:
Process /work/hello created: pid=69
Listening on port 1234
這時切換到宿主機的控制檯,運行
[root@localhost] arm-softfloat-linux-gnu-gdb hello
(gdb) target remote 192.168.2.33:1234
出現提示:
Remote debugging using 192.168.1.33:1234
[New thread 80]
[Switching to thread 80]
0x40002a90 in ??()
同時在minicom下提示:
Remote debugging from host 192.168.2.100
(gdb)
連接成功,這時候就可以輸入各種gdb命令如list、continue、next、step、break等進行程序調試了。
對於GDBServer出現的問題
1. GDBServer調試時出現packet error 問題。
主要是虛擬機與目標機的網絡連接要經過windows,數據包容易丟失。換到Linux系統下則恢復正常。