日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

建立ARM交叉编译环境 (arm-none-linux-gnueabi-gcc with EABI)

發布時間:2024/9/5 linux 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 建立ARM交叉编译环境 (arm-none-linux-gnueabi-gcc with EABI) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

昨天終于把交叉編譯環境、移植內核和制作root文件系統在arm開發板上順利跑通了。期間有的步驟很順利,但更多的是被諸多問題困擾,比如最后一個不起眼的小問題導致文件系統無法加載,郁悶了我一個星期,最終通過分析慢慢發現了這個bug。還有各源碼包版本的問題,而且網上很多介紹都是基于舊版本的。我這里全部用最新或較新的版本,當然,至于新舊版本到底哪個更好更合適,這是個智者見智的論題,不在本文討論之列。我堅信很多人也遇到過或者即將遇到我曾經歷過的錯誤和問題,因此我覺得把我過去兩周做過的相關工作,詳細地寫下來,希望對大家有所幫助!
?

首先是平臺和環境?,我過去兩周都是基于vmware?中ubuntu 10.04的,但是我發現ubuntu這個很火的桌面linux發行版本并不適合進行嵌入式開發,典型的麻煩就是系統缺少很多庫、服務等等,需要自己手動安裝,增加了不少額外的工作,和我以前用的SuSe 9比麻煩不少。不過所以現在我干脆全新裝了一個SUSE 11.2?Enterprise Server 32bit,把過去的工作重復一遍,邊編譯邊紀錄,力求不遺漏細節!
?

過程預覽:
1,準備工作,包括下載源碼包、補丁、建立文件夾和設置環境變量等
2,建立內核頭文件
3,建立binutils
4,建立bootstrap gcc
5,建立glibc
6,建立完整版本gcc
7,測試hello world
?

現在就讓我們開始吧!??
?

1 準備工作

我使用的源碼包和補丁?如下:
linux-2.6.34.tar.bz2
binutils-2.20.tar.gz
gcc-4.3.5.tar.bz2
glibc-2.11.tar.gz
glibc-linuxthreads-2.5.tar.bz2
glibc-ports-2.11.tar.bz2
glibc-2.11.2-gcc_fix-1.patch
至于怎么得到這些源碼包,找google吧!
?

建立工作目錄?
自己選一個合適的地方,建立一個總文件夾Embedded,并且在其下建立 build-tools、kernel和tools三個子文件夾、我們以后的操作就都在這里進行了。

$ mkdir Embedded
$ cd Embedded
$ mkdir build-tools ?? kernel ? ? tool
$ ls
build-tools ?? kernel ? ? tool

?


各文件夾作用如下:

build-tools : 保存binutils、gcc 和 glibc的源代碼和用來編譯這些源代碼的目錄。
kernel??????? : 保存內核源代碼和補丁。
tools????????? : 保存編譯好的交叉編譯工具和庫文件。
然后在build-tools文件夾中建立如下子文件夾:

?


$ cd?
build-tools?
$ mkdir?build-binutils???build-boot-gcc???build-glibc??build-gcc?


build-binutils??? :編譯binutils的目錄
build-boot-gcc : 編譯gcc 啟動部分的目錄
build-glibc??????? :編譯glibc的目錄
build-gcc????????? :編譯完整gcc的目錄

?



設置環境變量:

這里設置環境變量只是為了方便,因為每個工具的config都需要輸入類似的變量,不如放在環境變量里。

在命令行下打開vi? ~/.bashrc,在文檔最后輸入下面幾行,然后注銷當前用戶,重新登錄

export PRJROOT=/home/jinglelong/MySoftware/Embedded
export TARGET=arm-none-linux-gnueabi
export PREFIX=$PRJROOT/tools
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PREFIX/bin:$PATH

?

?


各變量的具體意義如下:

PRJROOT???????????????????? : 整個工程的根目錄,這里當然是Embeded了
TARGET???????????????????????: 目標文件對應的體系結構,arm-linux代表編譯出來的target只能在arm體系結構中運行
PREFIX????????????????????????: 設置目標文件夾的路徑前綴
TARGET_PREFIX????????? : 設置目標文件夾的路徑前綴路徑
PATH???????????????????????????: 添加可執行文件的路徑,這里主要是只中間編譯工具等

?

?


2 建立內核include文件

$ ln -s? /home/jinglelong/MySoftware/Embedded/kernel/linux-2.6.34/include/linux? $TARGET_PREFIX/include/linux?
$ ln -s? /home/jinglelong/MySoftware/Embedded/kernel/linux-2.6.34/include/asm-generic/????? $TARGET_PREFIX/include/asm-generic?
$ ln -s? /home/jinglelong/MySoftware/Embedded/kernel/linux-2.6.34/arch/arm/include/asm/? $TARGET_PREFIX/include/asm?


編譯生成version頭文件

這個是編譯glibc時必須的,使用命令:make include/linux/version.h

?

?


3 建立binutils

解壓binutils源碼到文件夾: $PRJROOT/build-tools/binutils-2.20

?


配置:

cd $PRJROOT/build-tools/build-binutils
$ ../binutils-2.20/configure --target=$TARGET --prefix=$PREFIX


編譯:make
出錯:
../../binutils-2.20/gas/config/tc-arm.c: In function ‘make_mapping_symbol’:
../../binutils-2.20/gas/config/tc-arm.c:2489: error: suggest braces around empty body in an ‘if’ statement
打開文件binutils-2.20/gas/config/tc-arm.c,把2490行的語句,用一對大括號括起來就可以了

?


安裝: make install
完成后檢查一下$PREFIX文件夾,是不是多了三個子文件夾,bin, lib, share? 打開bin,發現里面生成了14個可執行文件:
?

[root@localhost bin]# ls
arm-none-linux-gnueabi-addr2line? arm-none-linux-gnueabi-as???arm-none-linux-gnueabi-gprof? arm-none-linux-gnueabi-nm?????? arm-none-linux-gnueabi-objdump? arm-none-linux-gnueabi-readelf? arm-none-linux-gnueabi-strings arm-none-linux-gnueabi-ar???????? arm-none-linux-gnueabi-c++filt? arm-none-linux-gnueabi-ld???? arm-none-linux-gnueabi-objcopy? arm-none-linux-gnueabi-ranlib?? arm-none-linux-gnueabi-size???? arm-none-linux-gnueabi-strip


他們的功能分別是:

add2line???????? :將你要找的地址轉成文件和行號,它要使用 debug 信息。
ar??????????????????:產生、修改和解開一個存檔文件
as??????????????????:gnu的匯編器
c++filt????????????:C++ 和 java 中有一種重載函數,所用的重載函數最后會被編譯轉化成匯編的標,c++filt 就是實現這種反向的轉化,根據標號得到函數名。
gprof ???????????? :gnu 匯編器預編譯器。
ld???????????????????:gnu 的連接器
nm???????????????? :列出目標文件的符號和對應的地址
objcopy?????????? :將某種格式的目標文件轉化成另外格式的目標文件
objdump????????? :顯示目標文件的信息
ranlib? ??????????? :為一個存檔文件產生一個索引,并將這個索引存入存檔文件中
readelf??????? ??? :顯示 elf 格式的目標文件的信息
size??????????????? :顯示目標文件各個節的大小和目標文件的大小
strings??????????? :打印出目標文件中可以打印的字符串,有個默認的長度,為4
strip??????????????? :剝掉目標文件的所有的符號信息

?



4 建立bootstrap gcc


首先,我們為什么要建立bootstrap gcc,而不能一次性成功?原因有兩點:

?


一是由于平臺本身的gcc編譯器和我們要建立的gcc版本不同,第一次用平臺本身的編譯器去build目標版本的gcc編譯器的時候,新生成的目標編譯器(相當于初始編譯器編譯鏈接生成的可執行文件)必然帶有初始編譯器的特征。而當我們用新生成的編譯器再次編譯自身時,便可去掉這種差異性。

?


二是因為gcc編譯器依賴于glibc,而當前我們的glibc是基于本機的,所以我們首先要build基于arm體系結構的glibc,再在glibc的基礎上生成基于arm體系結構的gcc。

?


這一步是最容易出錯的,對每一步都必須謹慎,不要犯粗心之類的低級錯誤。

?


解壓源碼
解壓gcc源碼到build-tool文件夾下
?

修改源碼:
gcc-4.3.5
CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC -Dinhibit_libc -D__gthr_posix_h

確保本機已經安裝了mpc, mpfr, gmp, 如果沒有,則在yast里面安裝好再往后走。

?


配置:
../gcc-4.3.5/configure --target=$TARGET --prefix=$PREFIX --without-headers --enable-languages=c --disable-threads --with-newlib --disable-shared --disable-libmudflap --disable-libssp
?

編譯:make all-gcc
安裝gcc: make install?
再編譯安裝libgcc,這個是后面編譯glibc必須的。
編譯:make all-target-libgcc
安裝libgcc: make install-target-libgcc
?

我看到網上很多文章在這一步有很多錯誤,一種是直接用make命令編譯gcc下所有內容,這個是沒有必要的,而且容易出錯。我在ubuntu和suse下都無法完成編譯,而在fedora下通過了;第二種情況是沒有編譯libgcc,這會導致后面編譯glibc無法通過。
?

安裝完成后,在$PREFIX/bin下又多了幾個文件,
arm-none-linux-gnueabi-cpp?????????: gnu的 C 的預編譯器
arm-none-linux-gnueabi-gcc?????????: gnu的 C 語言編譯器
arm-none-linux-gnueabi-gcc-4.3.5 : gnu的 C 語言編譯器,其實和arm-linux-gcc是一樣的
arm-none-linux-gnueabi-gccbug??? :? 一個可執行腳本,具體作用未知。
arm-none-linux-gnueabi-gcov??????? : gcc 的輔助測試工具,用來分析和優化程序

?

?



5 建立glibc
?
解壓源碼:
把glibc源碼解壓到build-tool下,把glibc-linuxthreads-2.5.tar.bz2解壓到glibc根目錄下,把glibc-ports-2.11.tar.bz2解壓到glibc根目錄下,并且命名為ports
?

進入文件夾build-glibc,創建config.cache文件,并且在文件中輸入以下內容

libc_cv_forced_unwind=yes
libc_cv_c_cleanup=yes
libc_cv_arm_tls=yes

?

配置:

BUILD_CC="gcc" CC=$TARGET-gcc ../glibc-2.11/configure --host=$TARGET --target=$TARGET --prefix=/usr --enable-add-ons --disable-profile --cache-file=config.cache --with-binutils=$PREFIX/bin/ --with-headers=$TARGET_PREFIX/include/

?


編譯:make
出錯:/arm-linux/bin/ld: cannot find -lgcc_eh
打開glibc根目錄下Makeconfig文件,去掉第541,546行中的-lgcc_eh,重新make

?


安裝:

make install_root=$TARGET_PREFIX prefix="" install

?


修改libc.so:

用vi或gedit打開libc.so文件,將文件中的:
GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a? AS_NEEDED ( /lib/ld-linux.so.2 ) )?
更改為
GROUP ( libc.so.6 libc_nonshared.a )
保存后退出

?

?



6 建立完整版gcc

有了前面的經驗,現在就簡單多了,進入目錄build-gcc,

?


配置:

../gcc-4.3.5/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ --disable-libgomp

?


編譯:
make all
?

安裝:?
make install
?

安裝完成后,在$PREFIX/bin下多了gnu的c++編譯器:
arm-none-linux-gnueabi-gcc
arm-none-linux-gnueabi-c++??
??

?

?

7 驗證工具鏈
創建,編譯生成一個hello world程序helloworld, 查看elf文件信息:
$? arm-none-linux-gnueabi-readelf? -d helloworld
是不是看到了ARM的信息?更直接的,就是把這個helloworld和相關依賴的動態庫拷到開發板上,看它是不是真的能helloworld!

?


8 總結
這次在SUSE 11.2上編譯安裝工具鏈,整個過程非常順利,其實我相信只要環境,配置等正確,常見linux發行版上都會比較順利。不過我還是建議直接下在編譯好的工具鏈,省下了不少麻煩,而且可靠性也能保證。最后,希望本教程對大家有所幫助,如果有什么遺漏或錯誤之處,希望大家能批評指正!

?

?



參考文獻:

1,?如何為嵌入式開發建立交叉編譯環境:?http://www.ibm.com/developerworks/cn/linux/l-embcmpl/?

?

?

?自http://blog.csdn.net/wyjkk/article/details/5792048

總結

以上是生活随笔為你收集整理的建立ARM交叉编译环境 (arm-none-linux-gnueabi-gcc with EABI)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。