一套完整的ARM交叉編譯環(huán)境的搭建過程
在網(wǎng)上查看了不少資料,參考別人的,在加上一些自己遇到的問題結(jié)合的,內(nèi)容直接轉(zhuǎn)載過來了,給和我一樣,剛
入門ARM的新手的。雖然網(wǎng)上很多現(xiàn)成的,但是自己動手做作,還是很好的。
編譯環(huán)境:
內(nèi)核名稱:Linux
內(nèi)核發(fā)行版: 3.3.0-4.fc16.x86_64
內(nèi)核版本:#1 SMP Tue Mar 20 18:05:40 UTC 2012
硬件架構(gòu)名稱: x86_64
硬件平臺:x86_64
操作系統(tǒng):GNU/Linux
當前系統(tǒng)gcc版本號:4.6.3
在Linux中建立整個ARM交叉編譯環(huán)境的整體過程為:
1、下載源碼包放在/mnt/hgfs/Document/
2、建立編譯目錄并設(shè)置環(huán)境變量
3、安裝內(nèi)核頭文件
4、安裝二進制工具(binutils)
5、建立初始編譯器工具鏈(簡版gcc)
6、建立glibc庫
7、建立全套編譯器工具鏈(full gcc)
8、驗證
一、下載源碼包
GNU的所有源碼文件都可以到這個地址下載:http://ftp.gnu.org/gnu/
Linux Kernel源代碼可以去這里下載:http://www.kernel.org
mpc可以去這里下載:http://www.multiprecision.org
下載的源碼包如下:
binutils-2.22.tar
gcc-4.6.3.tar
glibc-2.13.tar
glibc-linuxthreads-2.3.6.tar
glibc-ports-2.13.tar
gmp-5.0.4.tar
linux-3.2.12.tar
mpc-0.9.tar
mpfr-2.4.2.tar.gz
注:mpfr不建議使用3.0.0版本。mpfr-3.0.0有Bug,會導致gcc編譯不過。
C 庫我試用了很多的版本,只有這套組合才能編譯成功
在后面編譯的過程中會提示缺少頭文件,去內(nèi)核中找到cp里就可以了。
二、建立編譯目錄并設(shè)置環(huán)境變量
選定自己的工作目錄,如我選擇/opt/embedded作為自己的工作目錄。然后再embedded中建立build-tools、kernel、tools
三個文件夾。實例:
root@fedora:/opt/ming# cd /opt/
root@fedora:/opt# mkdir embedded
root@fedora:/opt# cd embedded/
root@fedora:/opt/embedded# mkdir build-tools kernel tools
root@fedora:/opt/embedded# cd build-tools/
root@fedora:/opt/embedded/build-tools# mkdir build-binutils build-boot-gcc build-glibc build-gcc
各文件夾的作用如下:
/opt/embedded:交叉編譯環(huán)境的主目錄
/opt/embedded/build-tools:存放binutils、gcc、glibc等GNU源碼和用來編譯這些源代碼的目錄
/opt/embedded/kernel:用來存放Linux內(nèi)核源代碼
/opt/embedded/tools:用來存放編譯好的交叉編譯工具和庫文件
/opt/embedded/build-tools/build-binutils:編譯binutils的目錄
/opt/embedded/build-tools/build-boot-gcc:編譯gcc啟動部分的目錄
/opt/embedded/build-tools/build-glibc:編譯glibc的目錄
/opt/embedded/build-tools/build-gcc:編譯整個gcc的目錄
建立好編譯目錄之后便是設(shè)置環(huán)境變量(建議直接在~/.bashrc中修改,注意修改之后要重新運行Terminal)。如下:
export PRJROOT=/opt/embedded
export TARGET=arm-linux
export PREFIX=$PRJROOT/tools
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PREFIX/bin:$PATH
各個環(huán)境變量的意義如下:
PRJROOT:整個交叉編譯環(huán)境的根目錄
TARGET:目標文件對應(yīng)的architecture,arm-linux表示編譯出來的target只能在arm architecture中運行
PREFIX:目標文件夾的路徑前綴
TARGET_PREFIX:目標文件夾的路徑前綴路徑
PATH:可執(zhí)行文件路徑,這里主要指定編譯工具等
三、安裝內(nèi)核頭文件
將Linux內(nèi)核源碼解壓至$PRJROOT/kernel目錄,然后建立幾個文件的符號鏈接,最后生成version.h文件。實例:
首先解壓Linux內(nèi)核源文件
root@fedora:/opt/embedded/kernel# cp /mnt/hgfs/Document/linux-3.2.12.tar .
root@fedora:/opt/embedded/kernel# tar -xvf linux-3.2.12.tar
root@fedora:/opt/embedded/kernel# mkdir /opt/embedded/tools/arm-linux
root@fedora:/opt/embedded/kernel# mkdir /opt/embedded/tools/arm-linux/include
root@fedora:/opt/embedded/kernel# ln -s /opt/embedded/kernel/linux-3.2.12/include/linux /opt/embedded/tools/arm-linux/include/linux
root@fedora:/opt/embedded/kernel# ln -s /opt/embedded/kernel/linux-3.2.12/include/asm-generic /opt/embedded/tools/arm-linux/include/asm-generic
root@fedora:/opt/embedded/kernel# ln -s /opt/embedded/kernel/linux-3.2.12/arch/arm/include/asm /opt/embedded/tools/arm-
linux/include/asm (也可能是是asm-arm,示內(nèi)核版本而定)
下面檢查上面創(chuàng)建的符號鏈接是否正確。實例:
root@fedora:/opt/embedded/kernel# cd /opt/embedded/tools/arm-linux/include/
root@fedora:/opt/embedded/tools/arm-linux/include# ll
asm -> /opt/embedded/kernel/linux-3.2.12/arch/arm/include/asm/
asm-generic -> /opt/embedded/kernel/linux-3.2.12/include/asm-generic/
linux -> /opt/embedded/kernel/linux-3.2.12/include/linux/
有如上結(jié)果表示符號鏈接創(chuàng)建正確。
root@fedora:/opt/embedded/kernel/linux-3.2.12#make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig*配置(注
意:arm-linux- 與menuconfig之間有一個空格)*
//在隨后出現(xiàn)的文本菜單進行配置、配置完退出并保存。若要設(shè)置某個選項,可將光標定位在該項上,按回車鍵。對
于前面有[]或者<>的,可以按空格鍵顯示所包含的子選項。
注意在選項System Types中選擇正確的硬件類型。配置完退出并保存(Exit Yes)。
最后生成version.h文件。實例:
root@fedora:/opt/embedded/kernel/linux-3.2.12# cd /opt/embedded/kernel/linux-3.2.12/
root@fedora:/opt/embedded/kernel/linux-3.2.12# make include/linux/version.h
CHK include/linux/version.h
UPD include/linux/version.h
接著進入相應(yīng)目錄查看version.h文件是否建立成功。
注:上述的做法理論上沒什么問題,但實際操作時,如果用其他版本的linux內(nèi)核可能會出現(xiàn)頭文件包含不全的情況,
這會直接導致后面編譯glibc時出現(xiàn)未定義、未聲明、缺少頭文件(如asm/unistd.h)的錯誤。如果可能的話,建議按上
述操作直接copy好用的其他交叉編譯工具鏈中的asm-arm、asm-generic、linux目錄。
四、安裝二進制工具(binutils)
Binutils是一些二進制工具集合,其中包含了常用的一些命令。首先將binutils-2.22.tar.bz2解壓至build-tools,然后進入
build-binutils目錄,配置并編譯binutils,最后使用make install進行安裝。實例:
root@fedora:/opt/embedded/build-tools# cd /opt/embedded/build-tools/
root@fedora:/opt/embedded/build-tools# cp /mnt/hgfs/Document/binutils-2.22.tar.bz2 .
root@fedora:/opt/embedded/build-tools# tar -xjf binutils-2.22.tar.bz2
root@fedora:/opt/embedded/build-tools# cd build-binutils/
root@fedora:/opt/embedded/build-tools/build-binutils#../binutils-2.22/configure --target=$TARGET --prefix=$PREFIX
root@fedora:/opt/embedded/build-tools/build-binutils# make
root@fedora:/opt/embedded/build-tools/build-binutils# make install
完成后,去$PREFIX中檢查一下生成的工具。實例:
root@fedora:/opt/embedded/build-tools/build-binutils# cd /opt/embedded/tools/bin
root@fedora:/opt/embedded/tools/bin# ll
有如下文件:
arm-linux-addr2line*
arm-linux-ar*
arm-linux-as*
arm-linux-c++filt*
arm-linux-elfedit*
arm-linux-gprof*
arm-linux-ld*
arm-linux-ld.bfd*
arm-linux-nm*
arm-linux-objcopy*
arm-linux-objdump*
arm-linux-ranlib*
arm-linux-readelf*
arm-linux-size*
arm-linux-strings*
arm-linux-strip*
這些生成的文件的作用分別為:
arm-linux-addr2line:將你要找的地址轉(zhuǎn)成文件和行號,它要使用 debug 信息
arm-linux-ar:產(chǎn)生、修改和解開一個存檔文件
arm-linux-as:GNU的匯編器
arm-linux-c++filt:C++ 和 java 中有一種重載函數(shù),所用的重載函數(shù)最后會被編譯轉(zhuǎn)化成匯編的標,c++filt 就是實現(xiàn)
這種反向的轉(zhuǎn)化,根據(jù)標號得到函數(shù)名
arm-linux-elfedit:用途暫時未知
arm-linux-gprof:GNU匯編器預(yù)編譯器
arm-linux-ld:GNU的連接器
arm-linux-ld.bfd:用途暫時未知
arm-linux-nm:列出目標文件的符號和對應(yīng)的地址
arm-linux-objcopy:將某種格式的目標文件轉(zhuǎn)化成另外格式的目標文件
arm-linux-objdump:顯示目標文件的信息
arm-linux-ranlib:為一個存檔文件產(chǎn)生一個索引,并將這個索引存入存檔文件中
arm-linux-readelf:顯示 elf 格式的目標文件的信息
arm-linux-size:顯示目標文件各個節(jié)的大小和目標文件的大小
arm-linux-strings:打印出目標文件中可以打印的字符串,有個默認的長度,為4
arm-linux-strip:剝掉目標文件的所有的符號信息
注:編譯過程中有可能出現(xiàn)的錯誤:
gcc -DHAVE_CONFIG_H -I.-I. -I. -I../bfd -I./config -I./../include -I./.. -I./../bfd -
DLOCALEDIR=""/tools/cross/share/locale""-W -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror -g -O2 -MT tc-
arm.o -MD -MP -MF .deps/tc-arm.Tpo -c -o tc-arm.o `test -f 'config/tc-arm.c' || echo './'`config/tc-arm.c
cc1: warnings being treated as errors
config/tc-arm.c: In function ‘make_mapping_symbol’:
config/tc-arm.c:2489: 警告:if 語句體為空
make[4]: *** [tc-arm.o] 錯誤 1// 排錯要充分利用報錯信息。
make[4]: Leaving directory `/root/build/binutils-2.20_cross/gas'
make[3]: *** [all-recursive] 錯誤 1
make[3]: Leaving directory `/root/build/binutils-2.20_cross/gas'
make[2]: *** [all] 錯誤 2
make[2]: Leaving directory `/root/build/binutils-2.20_cross/gas'
make[1]: *** [all-gas] 錯誤 2
make[1]: Leaving directory `/root/build/binutils-2.20_cross'
make: *** [all] 錯誤 2
解決方案:
1)網(wǎng)上說的在tc-arm.c中加個括號,沒研究,可能好用;
2)在make這一步中,可能會在編譯../binutils-2.22/gas/config/tc-arm.c出現(xiàn)gcc把警告當成錯誤的錯誤,其原因在于編譯
該文件時使用了-Werror選項,解決辦法是修改../binutils-2.22/gas/configure文件第10624行,把
ERROR_ON_WARNING=yes改為ERROR_ON_WARNING=no,保存退出,重新執(zhí)行make即可。
3)在配置時,關(guān)閉Warning報錯,也可以編譯成功:(我用的是這種)
[root@localhost binutils-2.20_cross_no_2]# ./configure --target=arm-linux --disable-werror && make
參考:http://hi.baidu.com/thinke365/bl ... 1f095af819b853.html
五、建立初始編譯器(簡版 gcc)
Gcc是最主要的編譯器。首先將gcc-4.6.3.ta解壓至build-tools,然后將gmp-5.0.2.tar.bz2、mpfr-2.4.2.tar.gz、mpc-0.9.tar.gz