歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 定制ARM For Linux交叉編譯工具詳解

定制ARM For Linux交叉編譯工具詳解

日期:2017/3/3 16:41:25   编辑:關於Linux

1、 ToolChain 簡介

ToolChain包含許多部件:主要之一是GCC,它可以是本機編譯工具或交叉編譯工具,GCC由Binuitls工具支持,Binutils是二進制代碼維護工具,這些部件是編譯程序的必要工具,同時他們也需要C庫(glibc)支持。認真考慮一下:定制一套編譯工具並不是想像中的易事!如果你還想繼續看下去,必須具備如下技能:

熟悉Linux環境

熟悉Linux的必要命令和工具的使用

知道如何配置、編譯核心和應用程序

以下章節將介紹怎樣定制ARM交叉編譯工具集,但對於大多數ARM開發者來說,沒有必要親自做這件事,完全可以用現成的工具集。除非現成的工具集不滿足你的使用要求,或者你想提高開發應用的能力。總之,我們強烈建議你使用現成穩定的工具集來做應用開發!

2、 定制ToolChain

首先來看看工作的大至步驟:

決定目標的名稱

決定目標的存放位置

編譯、安裝Binutils

編譯、安裝GCC

編譯、安裝GLIBC

讓交叉編譯工具支持更多編譯語言

測試定制的交叉編譯工具

2.1、決定目標的名稱

本機編譯工具集編譯的代碼只適用本機(大多數PC是X86)運行,對於ARM開發者來說,需要一個能在本機編譯、但編譯卻生成ARM運行代碼的一套交叉編譯工具集。

因此,選擇一個與本機工具集相異的特定含義的目標名稱是非常有必要的。

arm-linux:是個比較受歡迎的名稱,支持ELF格式(ARMLinux標准)。除Acorn用戶使用老的a.out格式外。

arm-linuxaout:選擇a.out格式,ARMLinux基本不支持它了。

arm-aout、arm-coff、arm-elf、arm-thumb:其它的格式名。

你也可以在其中插入版本信息,比如:

armv2:ARMV2核,支持26bit模式。

armv3l、armv3b:ARMV3核,小字節(l)或大字節(b)模式。

armv4l、armv4b:ARMV4核,如:StrongARM、ARM7TDMI、ARM8、ARM9。同樣也支持小字節(l)或大字節(b)模式。

armv5l、armv5b:ARMV5核,如:XScale核ARM10。同樣也支持小字節(l)或大字節(b)模式。

選擇什麼名稱對定制ARM交叉編譯工具集沒太大的影響,但用大家常用的名稱會比較好些。

2.2、決定目標的存放位置

既然是定制ARM交叉編譯工具集,那麼就不能覆蓋本機的編譯工具集(否則,本機將不能再編譯本機運行代碼!),同時還要考慮本機Linux環境的多用戶、多任務特征。因此,選擇一個與本機編譯工具集不同的多用戶共享位置是必要的。

ARM交叉編譯工具集的存放位置:在本文中,我們讓它等於/usr/local/arm

(本機編譯工具集的存放位置通常在/usr或/usr/local)

ARM交叉編譯工具集的名稱:在本文中,我們讓它等於 arm-pc-linux,表示在本

地pc上編譯,生成的是ARM指令代碼(詳細規則見glibc的README文件)。

(本機編譯工具集名稱通常是: i686-pc-linux-gnu,表示在本地pc上編譯,

生成的是i686指令代碼)

ARM核心文件位置:本文中我們讓它等於 ~/armlinux 。不過,~/armlinux在這裡僅

是個聯接而已,它指向真正ARM核心源代碼位置(見2.4.1描述)。

(本機核心存放位置通常在/usr/src/linux)

2.3、編譯、安裝Binutils

它是GNU(ftp://ftp.gnu.org)工具之一,主要是二進制代碼的處理維護工具。

2.3.1、Binutils工具部件簡介

add2line:將地址轉換成文件名或行號對,以便調試程序。

ar:從體系文件中創建、修改、擴展程序代碼。

as:生成匯編程序代碼。

c++filt:建立低級語言和用戶級語言的名稱符號聯接,並保持它們的相互關系。

gasp:匯編宏處理器。

ld:目標代碼聯接,聯接各目標代碼塊,它是生成可執行代碼的最終步驟。

nm:從目標代碼文件中枚舉所有調試符號名。

objcopy:使用GNU BSD庫,把目標代碼從一文件格試拷貝成另一種格試。

objdump:顯示目標文件信息。

readelf:顯示elf文件信息。

ranlib:生成索引以加快對歸檔文件的訪問。

size:列出目標模塊或文件的代碼尺寸。

strings:打印可打印的目標代碼字符(至少4個字符),打印字符多少可以控制。對於其它格試的文件,打印字符串。

strip:放棄所有符號聯接。

2.3.2、Binutils的配置和編譯安裝

tar -jxvf binutils-2.16.1.tar.bz2 -C ~
cd ~/binutils-2.16.1
make clean
make distclean
./configure --target=arm-pc-linux  --prefix=/usr/local/arm
make
make install

如果安裝成功(通常都不會有問題),進入下一步:GCC

2.4、編譯、安裝GCC

它是GNU(ftp://ftp.gnu.org)工具之一,是主要的編譯處理工具。

2.4.1 ARM核心頭文件

對於本機的編譯工具集,通常核心頭文件已經安裝在/usr/src/linux/include,或被gcc拷貝到搜尋路徑內。但對於ARM交叉編譯工具集,可能還沒有(除非在此前已經安裝過),由其是第一次定制。所以,我們需要提取ARM核心頭文件。這裡我們使用面向AT91RM9200的核心文件linux-2.4.27-vrs1.tar.bz2

(如果是通用核心,那麼你需要面向ARM的補丁文件)

tar -jxvf linux-2.4.27-vrs1.tar.bz2 -C ~

cd ~

ln -s linux-2.4.27-vrs1-ATMEL armlinux

好了,我們建立了:~/armlinux 聯接

cd ~/armlinux

vim Makefile

檢查ARCH := 的行,如果不是arm,請把它改成ARCH := arm,保存退出。

(檢查CROSS_COMPILE := /usr/local/arm/bin/arm-pc-linux-,如果不同,修改它)

make clean

make distclean

make menuconfig

配置核心(選擇ARM為AT91RM9200和其它相關配置),保存退出。

make dep

(如遇錯誤終止,看第3部份是否有解答!)

肯定有錯誤發生而終止!當然,我們並不是想現在編譯這個核心,只是理順核心文件間的關系,以便下面拷貝操作順利進行......

mkdir /usr/local/arm/arm-pc-linux/sys-include

cp -dR ~/armlinux/include/asm-arm

/usr/local/arm/arm-pc-linux/sys-include/asm

cp -dR ~/armlinux/include/linux

/usr/local/arm/arm-pc-linux/sys-include/linux

好了,我們現在有ARM交叉編譯的公用核心頭文件了。

2.4.2、gcc配置、編譯和安裝

閱讀gcc源代碼INSTALL目錄下的文件,獲得更多的配置和編譯安裝幫助。

為了使用前面編譯好的Binutils工具,添加路徑。

export PATH=$PATH:/usr/local/arm/bin

(如果/usr/local/arm/bin已經包含在PATH,此步驟省略)

tar -jxvf gcc-3.4.5.tar.bz2 -C ~

cd ~/gcc-3.4.5

2.4.3、第一次安裝ARM交叉編譯工具gcc

(閱讀gcc源代碼INSTALL目錄下的文件,獲得更多的配置、編譯和安裝幫助)

通常都會遇到問題而使整個過程不能完成,因為以下要素必須考慮:

既然是第一次安裝ARM交叉編譯工具,那麼本機的glibc支持的應該是本機的編譯工具庫,而不是ARM交叉編譯工具庫。並且支持ARM交叉編譯工具的其它支持語言(比如:C++、java)的libc庫(最終的gcc生成的二進制代碼聯接需要該庫支持)我們也沒有,所以,要增加編譯開關:

--enable-languages=c --disable-threads --disable-shared

同理,由於第一次安裝ARM交叉編譯工具,那麼支持的libc庫的頭文件也沒有!所以我們征用Dinhibit_libc來hack(這個詞只可意會,不可言傳)這個問題。操作如下:

cp ~/gcc-3.4.5/gcc/config/arm/t-linux ~/gcc-3.4.5/gcc/config/arm/t-linux.orig

vim ~/gcc-3.4.5/gcc/config/arm/t-linux

給TARGET_LIBGCC2_CFLAGS = 增加操作參數

-Dinhibit_libc -D__gthr_posix_h

保存退出。

讓我們來重新配置、編譯它......

export PATH=$PATH:/usr/local/arm/bin

(如果/usr/local/arm/bin已經包含在PATH,此步驟省略)

cd ~/gcc-3.4.5

make clean

make distclean

./configure --target=arm-pc-linux --prefix=/usr/local/arm --disable-threads --disable-shared --enable-languages=c

(由於上面我們把交叉編譯頭文件拷貝到了gcc的默認sys-include目錄,因此不需要定義--with-headers參數。實際測試中,定義--with-headers反而不能make通過,不知道是否bug)

make

(痛苦的除bug過程!)

(如遇錯誤終止,看第3部份是否有解答,並且強烈建議你從make clean開始!)

make install

如果安裝成功,我們就有了能編譯C語言的ARM交叉編譯工具gcc了。如果你只是用ARM交叉編譯工具編譯ARM核心,OK!你可以就此打住。如果想編譯用戶級代碼,繼續進入下階段......

2.5、編譯、安裝GLIBC

glibc是個C庫,幾乎所有的應用程序都需要共享它提供的功能(除了kernel、bootload、和其它完全不用C庫的功能代碼),因此glibc的存在有利益小系統或嵌入系統縮減系統總代碼尺寸與存放空間(盡管單個的glibc庫是比較大的)。所以,最後的工作就是:構造ARM交叉編譯系統的glibc庫。

2.5.1、解壓源代碼

首先解壓glibc代碼,再解壓linuxthreads代碼到glibc代碼的源碼目錄下......

tar -jxvf glibc-2.3.6.tar.bz2 -C ~

tar -jxvf glibc-linuxthreads-2.3.6.tar.bz2 -C ~/glibc-2.3.6

2.5.2、glibc配置、編譯、安裝

閱讀glibc源代碼下的文件:README、FAQ和INSTALL,獲得更多的配置、編譯和安裝幫助。

export PATH=$PATH:/usr/local/arm/bin

(如果/usr/local/arm/bin已經包含在PATH,此步驟省略)

export CC=arm-pc-linux-gcc

(定義用剛生成的ARM交叉編譯工具編譯。否則,生成的glibc庫是本地機代碼庫,而不是ARM指令集代碼庫!!!)

警告:不能在源代碼目錄下操作(為什麽?問GNU吧,我也不知道!)......

mkdir ~/temp

cd ~/temp

make clean

make distclean

~/glibc-2.3.6/configure --host=arm-pc-linux

--build=i686-pc-linux-gnu

--with-headers=/usr/local/arm/arm-pc-linux/sys-include

--enable-add-ons=linuxthreads

--enable-shared

--prefix=/usr/local/arm/arm-pc-linux

(你可能注意到glibc的--prefix值與gcc的配置不一樣!是的,你必須這樣定義,否則,後面gcc的make過程將因找不到glibc的公用頭文件或庫而錯誤終止!)

make

(痛苦的除bug過程!)

(如遇錯誤終止,看第3部份是否有解答,並且強烈建議你從make clean開始!)

make install

如果安裝成功,我們就有了能編譯C語言的ARM交叉編譯工具gcc了。如果你只是用ARM交叉編譯工具編譯arm核心,OK!你可以就此打住。如果想編譯用戶級代碼,繼續進入下階段......

2.5、編譯、安裝GLIBC

glibc是個C庫,幾乎所有的應用程序都需要共享它提供的功能(除了kernel、bootload、和其它完全不用C庫的功能代碼),因此glibc的存在有利益小系統或嵌入系統縮減系統總代碼尺寸與存放空間(盡管單個的glibc庫是比較大的)。所以,最後的工作就是:構造arm交叉編譯系統的glibc庫。

2.5.1、解壓源代碼

首先解壓glibc代碼,再解壓linuxthreads代碼到glibc代碼的源碼目錄下......

tar -jxvf glibc-2.3.6.tar.bz2 -C ~

tar -jxvf glibc-linuxthreads-2.3.6.tar.bz2 -C ~/glibc-2.3.6

2.5.2、glibc配置、編譯、安裝

閱讀glibc源代碼下的文件:README、FAQ和INSTALL,獲得更多的配置、編譯和安裝幫助。

export PATH=$PATH:/usr/local/arm/bin

(如果/usr/local/arm/bin已經包含在PATH,此步驟省略)

export CC=arm-pc-linux-gcc

(定義用剛生成的ARM交叉編譯工具編譯。否則,生成的glibc庫是本地機代碼庫,而不是arm指令集代碼庫!!!)

警告:不能在源代碼目錄下操作......

mkdir ~/temp

cd ~/temp

make clean

make distclean

~/glibc-2.3.6/configure --host=arm-pc-linux

--build=i686-pc-linux-gnu

--with-headers=/usr/local/arm/arm-pc-linux/sys-include

--enable-add-ons=linuxthreads

--enable-shared

--prefix=/usr/local/arm/arm-pc-linux

(你可能注意到glibc的--prefix值與gcc的配置不一樣!是的,你必須這樣定義,否則,後面gcc的make過程將因找不到glibc的公用頭文件或庫而錯誤終止!)

make

(如遇錯誤終止,看第3部份是否有解答,並且強烈建議你從make clean開始!)

make install

Copyright © Linux教程網 All Rights Reserved