Linux ARM交叉編譯工具鏈制作過程
源代碼文件及其版本與下載地址:
Binutils-2.19.tar.bz2
http://ftp.gnu.org/gnu/binutils/
gcc-4.4.4.tar.bz2
http://mirrors.kernel.org/gnu/gcc/gcc-4.4.4/
Glibc-2.11.2.tar.bz2
Glibc-ports-2.11.tar.bz2
http://ftp.gnu.org/gnu/glibc/
Gmp-4.2.tar.bz2
http://ftp.gnu.org/gnu/gmp/
Mpfr-2.4.0.tar.bz2
http://ftp.gnu.org/gnu/mpfr/
Linux-2.6.29.tar.bz2
Patch-2.6.29.bz2
http://www.kernel.org/pub/linux/kernel/v2.6/
一般一個(gè)完整的交叉編譯器涉及到多個(gè)軟件,主要包括binutils、gcc、glibc等。其中,binutils主要生成一些輔助工具;gcc是用來生成交叉編譯器,主要生成arm-linux-gcc交叉編譯工具,而glibc主要提供用戶程序所需要的一些基本函數(shù)庫。
二、建立工作目錄
進(jìn)入工作目錄:
[root@localhost
[root@localhost
/home/karen/cross
創(chuàng)建工具鏈文件夾:
[root@localhost
在建立了頂層文件夾embedded- toolchains,下面在此文件夾下建立如下幾個(gè)目錄:
Ø
Ø
Ø
Ø
Ø
Ø
Ø
[root@localhost
[root@localhost
[root@localhost
build-dir doc kernel program setup-dir src-dir tool-chain
[root@localhost
這里我們采用直接拷貝源文件的方法,首先應(yīng)該修改setup-dir的權(quán)限
[root@localhost
然后直接拷貝/home/karen目錄下的源文件到setup-dir目錄中,如下圖:
建立編譯目錄:
[root@localhost
[root@localhost
三、輸出環(huán)境變量
輸出如下的環(huán)境變量方便我們編譯。
為簡(jiǎn)化操作過程。下面就建立shell命令腳本environment-variables:
[root@localhost
[root@localhost
[root@localhost
用編輯器vi編輯環(huán)境變量腳本envionment-variables:
[root@localhost
export
export
export
export
export
截圖如下:
%% Q:為什么用了source ./environment-variables才正常執(zhí)行,去掉source就沒有執(zhí)行? %%
%%
%%
說明:
TARGET變量用來定義目標(biāo)板的類型,以后會(huì)根據(jù)此目標(biāo)板的類型來建立工具鏈。參
看表6-1所示。目標(biāo)板的定義與主機(jī)的類型是沒有關(guān)系的,但是如果更改TARGET的值,
GNU工具鏈必須重新建立一次。
PREFIX變量提供了指針,指向目標(biāo)板工具程序?qū)⒈话惭b的目錄。
TARGET_PREFIX變量指向與目標(biāo)板相關(guān)的頭文件和鏈接庫將被安裝的目錄。
PATH變量指向二進(jìn)制文件(可執(zhí)行文件)將被安裝的目錄。
如果不慣用環(huán)境變量的,可以直接用絕對(duì)或相對(duì)路徑。如果不用環(huán)境變量,一般都用絕對(duì)路徑,相對(duì)路徑有時(shí)會(huì)失敗。環(huán)境變量也可以定義在.bashrc文件中,這樣就不用老是export這些變量了。
體系結(jié)構(gòu)和TAEGET變量的對(duì)應(yīng)如下表6-1所示:
表6-1 體系結(jié)構(gòu)和TAEGET變量的對(duì)應(yīng)
體系結(jié)構(gòu) | TARGET變量的值 |
PowerPC | Powerpc-linux |
ARM | arm-linux |
MIPS(big endian) | mips-linux |
MIPS(little endian) | mipsel-linux |
MIPS64 | mips64-linux |
SuperH3 | sh3-linux |
SuperH4 | sh4-linux |
I386 | i386-linux |
Ia64 | ia64-linux |
M68k | m68k-linux |
M88k | m88k-linux |
Alpha | alpha-linux |
Sparc | sparc-linux |
Sparc64 | sparc64-linux |
Binutils是GNU工具之一,它包括連接器、匯編器和其他用于目標(biāo)文件和檔案的工具,它是二進(jìn)制代碼的處理維護(hù)工具。安裝Binutils工具包含的程序有addr2line、ar、as、c++filt、gprof、ld、nm、objcopy、objdump、ranlib、readelf、size、strings、strip、libiberty、libbfd和libopcodes。對(duì)這些程序的簡(jiǎn)單解釋如下。
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Binutils工具安裝依賴于Bash、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Perl、Sed、Texinfo等工具
下面將分步介紹安裝binutils-2.19.2的過程。
[root@localhost
[root@localhost
[root@localhost
創(chuàng)建Makefile:
[root@localhost
注意:每個(gè)工具的文件名的前綴都是前面為TARGET變量設(shè)定的值。如果目標(biāo)板arm-linux,那么這些工具的文件名前綴就會(huì)是arm-linux-。這樣就可以根據(jù)目標(biāo)板類型找到正確的工具程序。
五、建立內(nèi)核頭文件
在這里我們使用時(shí)2.6.29的內(nèi)核版本,因?yàn)榻徊婀ぞ哝湽ぞ哝準(zhǔn)轻槍?duì)特定的處理器和操作系統(tǒng)的,因此在編譯之前就需要對(duì)linux內(nèi)核進(jìn)行配制,可以通過“make config”或“make menuconfig”命令對(duì)內(nèi)核進(jìn)行配制,配制完成后,在linux源文件的目錄下就會(huì)生成一個(gè).config文件,這就是我們所需要的文件。
Note: 目標(biāo)板的內(nèi)核版本是2.6.29
[root@localhost
[root@localhost
[root@localhost
[root@localhost
給Linux內(nèi)核打補(bǔ)?。?br />[root@localhost
然后就是配置內(nèi)核,第一步是修改Makefile
修改 Makefile:
ARCH = arm
CROSS_COMPILE = arm-linux- menuconfig
接著使用make menuconfig進(jìn)入內(nèi)核配置菜單
或者直接寫:
# make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
System Type -à
配置完退出并保存。
配置完須執(zhí)行make,參數(shù)如下:
[root@localhost linux-2.6.29]# make ARCH=arm CROSS_COMPILE=arm-linux- (執(zhí)行過程中有錯(cuò)誤出現(xiàn)也沒關(guān)系,主要目的是產(chǎn)生頭文件version.h和autoconf.h)
執(zhí)行完檢查一下內(nèi)核目錄中的/kernel/linux-2.6.29/include/linux/version.h和autoconf.h文件是不是生成了,這是編譯glibc要用到的。version.h 和 autoconf.h 文件的存在,說明你生成了正確的頭文件。
接下來建立工具鏈需要的include目錄,并將內(nèi)核頭文件復(fù)制過去。
[root@localhost
[root@localhost
可以查看一下,經(jīng)過編譯可以自動(dòng)生成。如果已經(jīng)生成鏈接,則不必重新鏈接。(2.6.29已自動(dòng)生成)
[root@localhost
[root@localhost
[root@localhost
可以查看一下,經(jīng)過編譯可以自動(dòng)生成。如果已經(jīng)生成鏈接,則不必重新鏈接。
復(fù)制頭文件到交叉編譯工具鏈的安裝目錄:
[root@localhost
[root@localhost asm] #cp –r $PRJROOT/kernel/linux-2.6.29/include/linux $TARGET_PREFIX/include
[root@localhost
[root@localhost
root@localhost
root@localhost
Note: mach-xxx是根據(jù)目標(biāo)板所用的cpu類型來選擇的
六、建立初始編譯器 (boot strap gcc)
這一步的目的主要是建立arm-linux-gcc工具,注意這個(gè)gcc沒有g(shù)libc庫的支持,所以只能用于編譯內(nèi)核、BootLoader等不需要C庫支持的程序,后面創(chuàng)建C庫也要用到這個(gè)編譯器,所以創(chuàng)建它主要是為創(chuàng)建C庫做準(zhǔn)備,如果只想編譯內(nèi)核和BootLoader,那么安裝完這個(gè)就可以到此結(jié)束。安裝過程如下:
重命名:
[root@localhost
[root@localhost
[root@localhost
從 GCC-4.3起,安裝GCC將依賴于GMP-4.1以上版本和MPFR-2.3.2以上版本。如果將這兩個(gè)軟件包分別解壓到GCC源碼樹的根目錄下,并分別命名為"gmp"和"mpfr",那么GCC的編譯程序?qū)⒆詣?dòng)將兩者與GCC一起編譯。建議盡可能使用最新的GMP和MPFR版本。
[root@localhost src-dir]# tar jxvf ../setup-dir/mpfr-2.4.0.tar.bz2
[root@localhost src-dir]# tar jxvf ../setup-dir/gmp-4.2.tar.bz2
[root@localhost src-dir]# mv mpfr-2.4.0 gcc-4.4.4/mpfr
[root@localhost src-dir]# mv gmp-4.2.0 gcc-4.4.4/gmp
•因?yàn)槭墙徊婢幾g器,還不需要目標(biāo)板的系統(tǒng)頭文件,所以需要使用 --without-headers這個(gè)選項(xiàng)。否則會(huì)有很多*.h頭文件找不到的報(bào)錯(cuò)
•--enable-language=c用來告訴配置腳本,需要產(chǎn)生的編譯器支持何種語言,現(xiàn)在只需支持C語言。雖然配置為c,c++也可以的
•--disable-threads 是因?yàn)閠hreads需要libc的支持。
•--disable-decimal-float,需要libc的支持,而我們?cè)诔醪骄幾g的時(shí)候尚未生成libc,否則出現(xiàn)以下的報(bào)錯(cuò):
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c:52:18: error: fenv.h: No such file or directory
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c: In function __dfp_test_except:
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c:64: error: FE_INEXACT undeclared (first use in this function)
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c:64: error: (Each undeclared identifier is reported only once
../../../gcc-4.3.1/libgcc/config/libbid/bid_decimal_globals.c:64: error: for each function it appears in.)
•--disable-shared,既然是第一次安裝ARM交叉編譯工具,那么本機(jī)的glibc支持的應(yīng)該是本機(jī)的編譯工具庫,而不是ARM交叉編譯工具庫。forces GCC to link its internal libraries statically,沒有這個(gè)選項(xiàng),會(huì)有 crti.o: No such file: No such file or directory collect2: ld returned 1 exit status
注:由于沒有arm的glibc,需要使用--disable-libmudflap --disable-libssp,禁止兩個(gè)邊界檢查使用的庫。
同樣,由于第一次安裝ARM交叉編譯工具,那么支持的libc庫的頭文件也沒有,src-dir/gcc-4.4.4/gcc/config/arm/t-linux文件,在TARGET_LIBGCC2_CFLAGS中添加兩個(gè)定義:-Dinhibit_libc
原文:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer –fPIC
改后:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D_gthr_posix.h
編譯:
[root@localhost
[root@localhost build-gcc]# ../../src-dir/gcc-4.4.4/configure --target=$TARGET --prefix=$PREFIX --without-headers --enable-languages=c --disable-shared --disable-threads --disable-decimal-float –disable-libmudflap –disable-lipssp
注:很多資料中之有前面兩項(xiàng),這只建立了gcc,沒有建立libgcc.a,這樣會(huì)在glibc的編譯中出現(xiàn)-lgcc沒有找到的錯(cuò)誤。報(bào)告:
……/build-tools/build-glibc/libc_pic.a
i586-linux-gcc
/workspace/wei/mywork/moblin/tools/bin/../lib/gcc/arm-linux/4.4.4/../../../../ram-linux/bin/ld: cannot find -lgcc
在glibc的編譯中,還需要libgcc_eh.a(否則出現(xiàn)錯(cuò)誤:-lgcc_eh沒有找到……bin/ld: cannot find -lgcc_eh),使用了--disable-shared的選項(xiàng),將不會(huì)生成libgcc_eh.a,可以通過對(duì)libgcc.a的鏈接來實(shí)現(xiàn)。
[root@localhost build-gcc]#
“/workspace/wei/mywork/moblin/tools/bin/../lib/gcc/i586-linux/4.3.3/libgcc_eh.a” -> “libgcc.a”
裝完成后,查看結(jié)果:
[root@localhost
如果arm-linux-gcc等工具已經(jīng)生成,表示boot trap gcc工具已經(jīng)安裝成功
七、編譯glibc
[root@localhost
[root@localhost
[root@localhost
[root@localhost
[root@localhost
[root@localhost
[root@localhost
[root@localhost
[root@localhost build-glibc] # CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib /
../../src-dir/glibc-2.11.2/configure /
--host=arm-linux /
--prefix=$PREFIX/$TARGET /
--with-tls --disable-profile /
--enable-add-ons /
--with-headers=$PREFIX/$TARGET/include /
libc_cv_forced_unwind=yes /
libc_cv_c_cleanup=yes /
libc_cv_arm_tls=yes
這樣連接程序 ld 就會(huì)在 libc.so 所在的目錄查找它需要的庫,因?yàn)槟愕臋C(jī)子的/lib目錄可能已經(jīng)裝了一個(gè)相同名字的庫,一個(gè)為編譯可以在你的宿主機(jī)上運(yùn)行的程序的庫,而不是用于交叉編譯的。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
對(duì) libc.so 的修正·
vi $PREFIX /${TARGET}/lib/libc.so
去掉絕對(duì)路徑,修改后的內(nèi)容如下:
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
八、建立全套編譯器 (full gcc)
[root@localhost
[root@localhost
[root@localhost
我們?cè)賮砜纯?$PREFIX/bin 里面多了哪些東西。你會(huì)發(fā)現(xiàn)多了 arm-linux-g++ 、和 arm-linux-c++ 幾個(gè)文件。
G++-gnu的 c++ 編譯器。
C++-gnu 的 c++ 編譯器。
至此,整個(gè)交叉編譯環(huán)境就建立完成了。
查看文件是否為二進(jìn)制文件:
[root@localhost
查看缺省的搜尋路徑:
[root@localhost
[root@localhost
[root@localhost
#include
int main(void)
{
}
[root@localhost
評(píng)論