先看一篇轉載的關於gdb和gdbserver的生成。
在對嵌入式進行調試之前,必須要生成調試器。經典地,Linux平臺下的調試器爲gdb。
1、下載gdb:
下載地址爲:
按照一般的想法,最新版本越好,因此下載7.2這個版本。當然,凡事無絕對。
我們以gdb-7.2.tar.bz2 這個文件爲例。
2、解壓縮:$ tar jxvf gdb-7.2.tar.bz2
注:小技巧:Linux下一般壓縮文件後綴爲.tar.bz2和.tar.gz,它們解壓命令有兩三個選項是一致的:
xf(v),前者再加上j選項,後者再加上z選項。
3、進入該目錄:
$ cd gdb-7.2/
4、配置:
$./configure --target=arm-linux --program-prefix=arm-linux- --prefix=/opt/gdb/
注:--target=arm-linux意思是說目標平臺是運行於ARM體系結構的linux內核;--program-prefix=arm-linux-是指生成的可執行文件的前綴,比如arm-linux-gdb,--prefix是指生成的可執行文件安裝在哪個目錄,這個目錄需要根據實際情況作選擇。如果該目錄不存在,會自動創建,當然,權限足夠的話。
5、編譯、安裝
$ make
$ make install
幸運的話,會在--prefix指定的目錄下生成三個子目錄:bin、lib、share,我們需要的arm-linux-gdb就在其中的bin目錄下。
如果你不小心查看它的大小的話,會發覺它有14MB那麼大!天吶!怎麼會佔這麼多空間?沒關係,我們可以爲它瘦身。沒錯!就是使用strip命令!
$ strip arm-linux-gdb -o arm-linux-gdb-stripped
$ ls -lh
總計 33M
-rwxr-xr-x 1 root 14M 12-14 16:16 arm-linux-gdb
-rwxr-xr-x 1 root 3.1M 12-14 16:25 arm-linux-gdb-stripped
可以看到,strip後的文件大小隻有3.1MB,瘦身效果明顯!如果做廣告的話,絕對有說服力。
這個文件就是我們以後遠程調試時在主機上運行的交叉調試器了:在主機上執行,調試的卻是另一種體系結構的代碼。但是,光有主機的調試器還不夠。還需要在目標板上運行一個叫gdbserver的東東。這個東東是怎麼來的呢?
1、在剛纔那個gdb解壓後的目錄:gdb-7.2,進入./gdb/gdbserver子目錄
$ cd gdb/gdbserver
$ pwd
/home/gotohell/soft/gdb-7.2/gdb/gdbserver
2、配置
$ ./configure --target=arm-linux --host=arm-linux
這裏的--host指定了生成可執行文件運行的平臺和系統:運行於ARM平臺的Linux系統
3、編譯
$ make
一切如果沒有問題的話,會在當前目錄下生成gdbserver這個只有在ARM下運行的文件。
注:網上絕大部分資料顯示,這裏的make會出錯,說某個頭文件不存在。經本人親自掛帥出征,在gdb的7.2版本不存在那個問題。低於7.2版本的就要注意了。解決方法也簡單,在配置後(執行./configure後),將生成的config.h文件中
#define HAVE_SYS_REG_H 1
語句註釋掉即可。
另外,也有資料說編譯gdbserver需要指定交叉編譯器(即執行make CC=arm-linux-gcc),但此處直接make,也沒問題。當然,交叉編譯器需要安裝好並設置好環境變量。我們看一下這個是什麼傢伙:
$ file gdbserver
gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses
shared libs), for GNU/Linux 2.6.14, not stripped
32位,ARM平臺,動態鏈接,未strip。
同樣,我們也減小它的體積:、
$ arm-linux-strip gdbserver -o gdbserver-stripped
$ ls -lh | grep gdbserver
-rwxr-xr-x 1 root 534K 12-14 15:50 gdbserver
-rwxr-xr-x 1 root 173K 12-14 16:36 gdbserver-stripped
瘦身效果同樣那麼明顯!
注意,這裏必須使用strip的交叉版本,也就是arm-linux-strip。
到此,我們生成了兩個重量級別的文件:arm-linux-gdb和gdbserver。它們的版本是一致的,這一點非常重要。我們需要將gdbserver下載到開發板中,——可以通過各種各樣的手段,包括但不限於NFS。調試時需要在開發板中運行這個程序。同時在主機中執行arm-linux-gdb調試器。
-----------------------------------------------------------------------------------------------------分割線
下面 說說 在按照上述過程中遇到的問題:
1 我先按 。./configure
make
make install
的順序安裝了gdb7.2,那麼接下來按 $./configure --target=arm-linux --program-prefix=arm-linux- --prefix=/opt/gdb/
在接下來make的過程中會出現如下錯誤:
Configuring in ./intl
configure: loading cache ./config.cache
configure: error: `target_alias' has changed since the previous run:
configure: former value: `i686-pc-linux-gnu'
configure: current value: `arm-linux'
configure: error: in `/home/w/下載/gdb-7.2/intl':
configure: error: changes in the environment can compromise the build
configure: error: run `make distclean' and/or `rm ./config.cache' and start over
make[1]: *** [configure-intl] 錯誤 1
make[1]:正在離開目錄 `/home/w/下載/gdb-7.2'
make: *** [all] 錯誤 2
解決的方法:暫時沒去想
2 換到另一個虛擬機上,這次不再直接安裝 按照轉載的文章的步驟可以順利完成gdb的編譯安裝。但是在編譯gdbserver的時候出現了問題,雖然 ./configure --target=arm-linux --host=arm-linux 指定了目標平臺和 主機都是arm-linux但是編譯出來結果
gdbserver: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
還是intel 80386的。
即使是指定CC爲交叉編譯器還是不行。
export CC=arm-none-linux-gnueabi-gcc
通過分析輸出的信息
checking for arm-linux-gcc... no
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
由於我安裝的交叉編譯器是codesource的交叉編譯工具鏈,似乎是我的交叉編譯名字不符合它的要求,一定要叫 arm-linux-gcc ?於是創建一系列軟鏈接
n -s arm-none-linux-gnueabi-gdbtui arm-linux-gdbtui
ln -s arm-none-linux-gnueabi-addr2line arm-linux-addr2line
ln -s arm-none-linux-gnueabi-gprof arm-linux-gprof
ln -s arm-none-linux-gnueabi-ar arm-linux-ar
ln -s arm-none-linux-gnueabi-as arm-linux-as
ln -s arm-none-linux-gnueabi-nm arm-linux-nm
ln -s arm-none-linux-gnueabi-ld arm-linux-ld
ln -s arm-none-linux-gnueabi-c++ arm-linux-c++
ln -s arm-none-linux-gnueabi-objcopy arm-linux-objcopy
ln -s arm-none-linux-gnueabi-c++filt arm-linux-c++filt
ln -s arm-none-linux-gnueabi-cpp arm-linux-cpp
ln -s arm-none-linux-gnueabi-ranlib arm-linux-ranlib
ln -s arm-none-linux-gnueabi-objdump arm-linux-objdump
ln -s arm-none-linux-gnueabi-readelf arm-linux-readelf
ln -s arm-none-linux-gnueabi-size arm-linux-size
ln -s arm-none-linux-gnueabi-gcov arm-linux-gcov
ln -s arm-none-linux-gnueabi-strings arm-linux-strings
ln -s arm-none-linux-gnueabi-gdb arm-linux-gdb
ln -s arm-none-linux-gnueabi-strip arm-linux-strip
ln -s arm-none-linux-gnueabi-sprite arm-linux-sprite
ln -s arm-none-linux-gnueabi-gcc-4.3.3 arm-linux-gcc-4.3.3
ln -s arm-none-linux-gnueabi-gcc arm-linux-gcc
重新執行命令 CC=arm-linux-gcc ./configure --target=arm-linux --host=arm-linux
發現 找到了交叉編譯器,變成yes了
checking for arm-linux-gcc... arm-linux-gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... yes
以爲大功告成了,結果又出現問題
/opt/tools/arm-2009q1/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/bin/ld: xml-builtin.o: Relocations in generic ELF (EM: 3)
/opt/tools/arm-2009q1/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/bin/ld: xml-builtin.o: Relocations in generic ELF (EM: 3)
/opt/tools/arm-2009q1/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/bin/ld: xml-builtin.o: Relocations in generic ELF (EM: 3)
xml-builtin.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
make: *** [gdbserver] Error 1
有點鬱悶,錯誤提示文件格式不對。執行命令 file xml-builtin.o
xml-builtin.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
不對呀,已經指定了是交叉編譯了怎麼生成的目標文件還是 intel 80386呢?
原來是之前執行過沒有設置好交叉編譯的時候,執行過了make命令,所以生成了這樣的目標文件。於是 執行 make clean 清除掉這些之前生成的文件
重新 執行CC=arm-linux-gcc ./configure --target=arm-linux --host=arm-linux make
再來查看生成的gdbserver
執行命令 file gdbserver
gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.14, not stripped
終於 看到ARM!
單槍匹馬摸索嵌入式的這些東西還真是讓人頭疼,各種問題讓人摸不着頭腦。好在經過長時間的嘗試和摸索找到了解決的方法。