建立ARM交叉編譯環境 (arm-none-linux-gnueabi-gcc with EABI)
昨天終於把交叉編譯環境、移植核心和製作root檔案系統在arm開發板上順利跑通了。期間有的步驟很順利,但更多的是被諸多問題困擾,比如最後一個不起眼的小問題導致檔案系統無法載入,鬱悶了我一個星期,最終通過分析慢慢發現了這個bug。還有各原始碼包版本的問題,而且網上很多介紹都是基於舊版本的。我這裡全部用最新或較新的版本,當然,至於新舊版本到底哪個更好更合適,這是個智者見智的論題,不在本文討論之列。我堅信很多人也遇到過或者即將遇到我曾經歷過的錯誤和問題,因此我覺得把我過去兩週做過的相關工作,詳細地寫下來,希望對大家有所幫助!
首先是平臺和環境 ,我過去兩週都是基於vmware 中ubuntu 10.04的,但是我發現ubuntu這個很火的桌面linux發行版本並不適合進行嵌入式開發,典型的麻煩就是系統缺少很多庫、服務等等,需要自己手動安裝,增加了不少額外的工作,和我以前用的SuSe 9比麻煩不少。不過所以現在我乾脆全新裝了一個SUSE 11.2
過程預覽:
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-binutilsbuild-boot-gccbuild-glibcbuild-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個可執行檔案:
[[email protected] 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發行版上都會比較順利。不過我還是建議直接下在編譯好的工具鏈,省下了不少麻煩,而且可靠性也能保證。最後,希望本教程對大家有所幫助,如果有什麼遺漏或錯誤之處,希望大家能批評指正!
參考文獻:
相關推薦
建立ARM交叉編譯環境 (arm-none-linux-gnueabi-gcc with EABI)
昨天終於把交叉編譯環境、移植核心和製作root檔案系統在arm開發板上順利跑通了。期間有的步驟很順利,但更多的是被諸多問題困擾,比如最後一個不起眼的小問題導致檔案系統無法載入,鬱悶了我一個星期,最終通過分析慢慢發現了這個bug。還有各原始碼包版本的問題,而且網上很多介紹都是基
ubuntu12.04建立交叉編譯環境,bin/.arm-none-linux-gnueabi-gcc: not found
ubuntu12.04交叉編譯器安裝,已經設定好環境變量了 ~$ echo $PATH /usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/ga
ubuntu12.04 64建立交叉編譯環境,bin/.arm-none-linux-gnueabi-gcc: not found(安裝 ia32-libs)
ubuntu12.04交叉編譯器安裝,已經設定好環境變量了 ~$ echo $PATH/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/ga
嵌入式交叉編譯環境arm-linux-gcc環境搭建
arm linux gcc 嵌入式交叉編譯環境 準備工具安裝目錄 可以去官網下載對應系統版本的arm-Linux-gcc。將壓縮包arm-linux-gcc-4.4.3.tar.gz存放在一個目錄下。 .tar.gz 和.tgz 解壓:tar zxvf FileName.tar.gz 壓縮:t
Linux下搭建arm交叉編譯環境
首先需要在網上搜索arm-linux-gcc-4.3.2.tgz 傳到Linux下,執行tar xzvf arm-linux-gcc-4.3.2.tgz -C/ 解壓到根目錄下(目錄結構/usr/local/arm/4.3.2) 這樣,編譯器就解壓到了Linux系統中 然後建立
Ubuntu14.04下嵌入式交叉編譯環境arm-linux-gcc-4.3.3搭建過程
需要做嵌入式的開發,照著板子的教程安裝arm-linux-gcc-4.3.3交叉編譯工具,安裝完驗證時發現安裝失敗 (報錯,錯誤與下面參考文章1中第6步一樣,照他說的那條命令去裝32位的庫,但是安裝失
64位Ubuntu 16.04搭建嵌入式交叉編譯環境arm-linux-gcc過程圖解
64位Ubuntu 16.04搭建嵌入式交叉編譯環境arm-linux-gcc過程圖解,開發裸機環境之前需要先搭建其開發環境,畢竟工欲善其事必先利其器嘛。 安裝步驟 1、準備工具安裝目錄 將壓縮包arm-Linux-gcc-4.4.3.tar.gz存放在
Ubuntu 12.04嵌入式交叉編譯環境arm-linux-gcc搭建過程圖解
安裝前的絮叨 首先簡單介紹一下,所謂的搭建交叉編譯環境,即安裝、配置交叉編譯工具鏈。在該環境下編譯出嵌入式Linux系統所需的作業系統、應用程式等,然後再上傳到目標機上。 交叉編譯工具鏈是為了編譯、連結、處理和除錯跨平臺體系結構的程式程式碼。對於交叉開發的工具鏈來說,在檔名稱上加了一個字首,用來區別本地的
配置64位UBUNTU 編譯環境出現的arm-none-linux-gnueabi-gcc: not found
在網上查詢資料後發現原因為該命令需要32庫進行支援。 需要sudo apt-get ia32-libs 但是又有資料提到ia32-libs已經廢棄。 ia32-libs已經被廢棄,那麼應該有取代的方式。 於是按照以下步驟 $ sudo apt-get install li
【Linux學習】Ubuntu下嵌入式交叉編譯環境arm-linux-gcc搭建
(1)首先選擇一個路徑用來存放arm-linux-gcc。我選用的是/home/book,並在下面建立一個資料夾arm-linux-gcc。 (2)利用cp EABI-4.3.3_Emdedsky_20100610.tar.bz2 arm-linux-gcc,將壓縮包EA
visual studio 2013上搭建arm交叉編譯環境(三)Visual studio2013中Cygwin工程的建立
前兩篇文章已經介紹了在vs上搭建arm環境的準備工作。 http://blog.csdn.net/water1209/article/details/50926869 http://blog.csdn.net/water1209/article/detail
ubuntu14.01 搭建交叉編譯環境arm-linux-gcc 4.3.2
安裝步驟 0. 安裝標準的C開發環境,由於Ubuntu 9.04 Linux安裝預設是不安裝的,所以需要先安裝一下(如果已經安裝好的話,就可以免去這一步了):$ sudo apt-get install gcc g++ libgcc1 libg++ make gdb如果
Ubuntu 14.04 LTS嵌入式交叉編譯環境arm-linux-gcc搭建過程圖解
1、將壓縮包arm-linux-gcc-3.4.5-glibc-2.3.6.tar.bz2存放在一個目錄下,這個目錄就是你等會解壓縮的目錄,以後這個目錄就不能隨便刪掉了,我的存放路徑是/home/g
Ubuntu160403安裝交叉編譯工具鏈後,出錯: ./arm-none-linux-gnueabi-gcc -v bash: ./arm-none-linux-gn
cd /etc/apt1在修改前先對 sources.list檔案進行備份sudo cp sources.list sources.list.bak1修改sources.list檔案sudo vi sources.list1刪除掉sources.list的其他內容,選擇任意源貼上複製進去,這裡以阿里云為例ub
安裝交叉編譯工具arm-none-linux-gnueabi-gcc——Linux上編譯在android上執行的c程式
# vim /etc/bash.bashrc 在最後新增 PATH=$PATH:/usr/local/arm-2014.05/bin source /etc/bash.bashrc 使其立刻生效 開啟另一個終端 執行 arm-none-linux-gnueabi-gcc -v,顯示版本即說明安裝成功 方法二
在Ubentu環境下創建arm交叉編譯環境
老師 build 目錄 更新 hello 分享 date win 例程 學校:華中科技大學機械學院 作業任務:在Ubentu環境下創建arm交叉編譯環境並且在虛擬機中編譯例程 首先,利用U盤安裝windows10+Ubuntu16.04雙系統,系統剛開始安裝,需要執行以下兩
ubuntu14.04搭建Android-arm交叉編譯環境
前面我們搭建了NDK開發環境 下面開始搭建arm交叉編譯環境 1.下載交叉編譯工具 進入到NDK根目錄:cd /home/wjt/AndroidWorkSpace/NDK_Tools/android-ndk-r10b 下載到指定路徑指令:./build/tools/make-st
docker搭建ros-indigo-arm交叉編譯環境
ROS執行環境:ARM ubuntu14.04 + ROS indigo 在arm環境下編譯ros應用程式,速度極慢,無法忍受,嘗試在x86機器上搭建docker+ros交叉編譯環境。 交叉編譯環境的搭建主要參考: 1 ARM ubuntu環境上安裝arm-indigo
一套完整的ARM交叉編譯環境的搭建過程——不使用現成的工具鏈
Glibc是交叉編譯環境的執行庫。首先將glibc-2.13.tar解壓至build-tools,然後將glibc-linuxthreads-2.3.6.tar解壓至glibc原始碼所在目錄,將glibc-ports-2.13.tar.gz解壓至glibc原始碼所在目錄,並重命名為ports。進入
arm-none-linux-gnueabi-gcc【實驗環境】 1、 Ubuntu 10.10發行版 2、 FS2410平臺 【實驗步驟】
Configuredwith:/home/linux/s3c2410-2.6.35/toolchain/toolchain-build/targets/src/gcc-4.3.2/configure--build=i686-build_pc-linux-gnu --host=i686-build_pc-lin