小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

一步一步建立基于ARM Linux的cross toolchain - 嵌入式開(kāi)發(fā)環(huán)境建立

 darkhero 2006-11-23


1 引言

由于一般嵌入式開(kāi)發(fā)系統(tǒng)存儲(chǔ)容量有限,在裁減和定制Linux,運(yùn)用于嵌入式系統(tǒng)前,通常需要在PC機(jī)上建立一個(gè)用于目標(biāo)機(jī)的交叉編譯環(huán)境,也就是將各種二進(jìn)制工具程序集成為工具鏈,其中包括如GNU的鏈接器(ld)、GNU的匯編器(as)、ar(產(chǎn)生修改和解開(kāi)一個(gè)存檔文件)、C編譯器(gcc)以及C鏈接庫(kù)(glibc)。本文以在Linux系統(tǒng)上針對(duì)目標(biāo)機(jī)arm為例,介紹了跨平臺(tái)開(kāi)發(fā)工具鏈的建立過(guò)程。

2 基本概念

2.1 什么是交叉編譯?

簡(jiǎn)單地說(shuō),交叉編譯就是在一個(gè)平臺(tái)上生成在另一個(gè)平臺(tái)上執(zhí)行的代碼。這里的平臺(tái)包括體系結(jié)構(gòu)(Architecture)和操作系統(tǒng)(OS)。同一個(gè)體系結(jié)構(gòu)可以運(yùn)行不同的操作系統(tǒng),同樣,同一個(gè)操作系統(tǒng)也可以在不同的體系結(jié)構(gòu)上運(yùn)行。舉例來(lái)說(shuō),x86 Linux平臺(tái)是Intel x86 體系結(jié)構(gòu)和Linux for x86操作系統(tǒng)的統(tǒng)稱。

2.2 為什么要用交叉編譯?

原因有兩個(gè)。一是目標(biāo)平臺(tái)所需要的bootloader以及OS核心還沒(méi)有建立時(shí),需要作交叉編譯。二是目標(biāo)機(jī)設(shè)備不具備一定的處理器能力和存儲(chǔ)空間,即單獨(dú)在目標(biāo)板上無(wú)法完成程序開(kāi)發(fā),所以只好求助宿主機(jī)。這樣可以在宿主機(jī)上對(duì)即將在目標(biāo)機(jī)上運(yùn)行的應(yīng)用程序進(jìn)行編譯,生成可以在目標(biāo)機(jī)上運(yùn)行的代碼格式,然后移植到目標(biāo)板上,也就是目前嵌入式程序開(kāi)發(fā)的Host/Target模式。

2.3 對(duì)于i386的理解

如果單純說(shuō)i386i686,就是指平時(shí)所說(shuō)的CPU類(lèi)型。從Linux內(nèi)核設(shè)計(jì)上講,i386是架構(gòu),i486/586/686這些CPU的架構(gòu)都是i386,所以很多linux方面的設(shè)計(jì)都是基于i386。簡(jiǎn)單地說(shuō),i386ppc,alpha,arm等放在一起時(shí)就是指架構(gòu),跟i586i686放在一起指處理器型號(hào),一個(gè)是橫向的,一個(gè)是縱向的。

3 建立過(guò)程

3.1 選定軟件版本

要想選用適當(dāng)?shù)陌姹?,以保證建立的工具鏈可用,就必須找到適合主機(jī)和目標(biāo)板的組合。這些可以自己測(cè)試,也可以從網(wǎng)上尋找已經(jīng)測(cè)試過(guò)的版本組合,即binutils、gccglibc的版本組合。我用的宿主機(jī)為redhat-9.0,目標(biāo)機(jī)arm,選擇的版本如下:

--------------------------------------------------------------------------------

binutils-2.11.2.tar.gz  包含有ldar、as等一些產(chǎn)生或者處理二進(jìn)制文件的工具。

gcc-core-2.95.3.tar.gz  包含GCC的主體部分。

gcc-g++2.95.3.tar.gz  可以使GCC編譯C++程序。

glibc-2.2.4.tar.gz  libc是很多用戶層應(yīng)用都要用到的庫(kù),即C鏈接庫(kù)。

glibc-linuxthreads-2.2.4.tar.gz  libc用于支持Posix線程單獨(dú)發(fā)布的壓縮包。

linux-2.4.21.tar.gz+rmk1  Linux的內(nèi)核及其支持ARM的補(bǔ)丁包。

--------------------------------------------------------------------------------

你可以嘗試選定更新的版本,編譯無(wú)法通過(guò)時(shí),依次使用較舊的版本。即時(shí)發(fā)現(xiàn)新版本組合能夠編譯成功,仍然需要測(cè)試建立的工具鏈?zhǔn)欠窨梢允褂谩?/span>

你可以從FTP網(wǎng)站ftp://ftp.gnu.org/gnu/或者任何其他的鏡像網(wǎng)站下載GNU工具鏈的各個(gè)組件:binutils包位于binutils目錄,gcc包位于gcc目錄,而glibc包與glibc-linuxthreads包放在glibc目錄。下面給出上面選用的各個(gè)版本的下載路徑。

--------------------------------------------------------------------------------

binutils-2.11.2.tar.gz

ftp://ftp.gnu.org/gnu/binutils/binutils-2.11.2.tar.gz

gcc-core-2.95.3.tar.gz

ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz

gcc-g++2.95.3.tar.gz

ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz

glibc-2.2.4.tar.gz

ftp://ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz

glibc-linuxthreads-2.2.4.tar.gz

ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz

linux-2.4.21.tar.gz+rmk1

ftp://ftp.kernle.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz

ftp://ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.4/patch-2.4.21-rmk1.gz

--------------------------------------------------------------------------------

3.2   建立工作目錄

我的用戶名為lqm,所以所有的工作都在/home/lqm下面建立完成。

************************************************************

$cd /home/lqm              進(jìn)入工作目錄

$pwd                     查看當(dāng)前目錄

/home/lqm

$mkdir embedded-system      創(chuàng)建工具鏈文件夾

$ls                        查看/home/lqm建立的所有文件

embedded-system

************************************************************

現(xiàn)在已經(jīng)建立了頂層文件夾embedded-system,下面在此文件夾下建立如下幾個(gè)目錄:

--------------------------------------------------------------------------------

setup-dir  存放下載的壓縮包

src-dir  存放binutils、gcc、glibc解壓之后的源文件

kernel  存放內(nèi)核文件,對(duì)內(nèi)核的配置和編譯工作也在此完成

build-dir  編譯src-dir下面的源文件。這是GNU推薦的源文件目錄與編譯目錄分離的做法。

tool-chain  交叉編譯工具鏈的安裝位置

program 存放編寫(xiě)程序

doc  說(shuō)明文檔和腳本文件

--------------------------------------------------------------------------------

下面建立目錄,并且下載源文件。

************************************************************

$pwd

/home/lqm/

$cd embedded-system

$mkdir setup-dir src-dir kernel build-dir tool-chain program doc

$ls

build-dir doc kernel program setup-dir src-dir tool-chain

$cd setup-dir

$wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.11.2.tar.gz   下載源文件

$wget ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz

$wget ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz

$wget ftp://ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz

$wget ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz

$wget ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz

$wget ftp://ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.4/ patch-2.4.21-rmk1.gz

$ls

binutils-2.11.2.tar.gz gcc-g++-2.95.3.tar.gz glibc-linuxthreads-2.2.4.tar.gz

patch-2.4.21-rmk1.gz gcc-core-2.95.3.tar.gz glibc-2.2.4.tar.gz linux-2.4.21.tar.gz

$cd ../build-dir

$mkdir build-binutils build-gcc build-glibc  建立編譯目錄

************************************************************

3.3     輸出環(huán)境變量

在建立與使用某些工具程序時(shí),可能會(huì)用到這些目錄的路徑,如果設(shè)計(jì)一個(gè)簡(jiǎn)短的命令腳本,設(shè)定適當(dāng)?shù)沫h(huán)境變量,則可以簡(jiǎn)化操作過(guò)程。下面就建立命令腳本hjbl

************************************************************

$pwd

/home/lqm/embedded-system/build-dir

$cd ../doc

$mkdir scripts

$cd scripts

$emacs hjbl   用文本編輯器emacs編譯環(huán)境變量腳本

--------------------------------------------------------------------------------

在隨后打開(kāi)的emacs編輯窗口中輸入下面內(nèi)容(如果在命令行界面下,則必須要用到vi文本編輯器,emacs則不可以):

export  PRJROOT=/home/lqm/embedded-system

export  TARGET=arm-linux

export  PREFIX=$PRJROOT/tool-chain

export  TARGET_PREFIX=$PREFIX/$TARGET

export  PATH=$PREFIX/bin:$PATH

保存后關(guān)閉emacs窗口,如果要在目前的窗口中執(zhí)行此腳本,即讓環(huán)境變量生效,還需要執(zhí)行下面的語(yǔ)句:

--------------------------------------------------------------------------------

$. hjbl(注意:在點(diǎn)和hjbl之間有一個(gè)空格)

$cd $PRJROOT  驗(yàn)證環(huán)境變量是否生效

$ls

build-dir doc kernel program setup-dir src-dir tool-chain

************************************************************

該環(huán)境變量的作用時(shí)間僅僅在Terminal當(dāng)前窗口,如果將窗口關(guān)閉,開(kāi)啟一個(gè)新的窗口,則環(huán)境變量實(shí)效,需要重新執(zhí)行下面的命令:

$. /home/lqm/embedded-system/doc/scripts/hjbl

說(shuō)明:

TARGET變量用來(lái)定義目標(biāo)板的類(lèi)型,以后會(huì)根據(jù)此目標(biāo)板的類(lèi)型來(lái)建立工具鏈。參看表1。目標(biāo)板的定義與主機(jī)的類(lèi)型是沒(méi)有關(guān)系的,但是如果更改TARGET的值,GNU工具鏈必須重新建立一次。

PREFIX變量提供了指針,指向目標(biāo)板工具程序?qū)⒈话惭b的目錄。

TARGET_PREFIX變量指向與目標(biāo)板相關(guān)的頭文件和鏈接庫(kù)將被安裝的目錄。

PATH變量指向二進(jìn)制文件(可執(zhí)行文件)將被安裝的目錄。

                    1 TARGET變量值

實(shí)際的目標(biāo)板

TARGET變量值

PowerPC

powerpc-linux

ARM

arm-linux

MIPS(big endian)

mips-linux

MIPS(little endian)

mipsel-linux

SuperH 4

sh4-linux

 

3.4  內(nèi)核頭文件的配置

內(nèi)核頭文件的配置是建立工具鏈的第一步。它與后面將要執(zhí)行的其他步驟有著類(lèi)似性,大多需要執(zhí)行下面幾步操作:

1、  解壓縮包

2、  為跨平臺(tái)開(kāi)發(fā)設(shè)定包的配置

3、  建立包

4、  安裝包

************************************************************

$pwd

/home/lqm/embedded-system/

$cd kernel

$tar xvzf ../setup-dir/ linux-2.4.21.tar.gz                解壓縮

$gunzip ../setup-dir/ patch-2.4.21-rmk1.gz

$cd linux-2.4.21

$patch –p1 < ../../setup-dir/patch-2.4.21-rmk1            Linux內(nèi)核打補(bǔ)丁

$make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig   配置

$make dep

--------------------------------------------------------------------------------

變量ARCHCROSS_COMPILE的值與目標(biāo)板的架構(gòu)類(lèi)型有關(guān)。如果使用PPC目標(biāo)板,則ARCH=ppc CROSS_COMPILE=ppc-linux-。如果使用i386目標(biāo)板,則ARCH=i386 CROSS_COMPILE=i386-linux-。

make menuconfig是以文本菜單方式配置。

make xconfig是以圖形界面方式配置。

       make config是純文本方式界面配置。

一般選擇make menuconfig,注意在選項(xiàng)System Types中選擇正確的硬件類(lèi)型。配置完退出并保存,檢查一下的內(nèi)核目錄中的 kernel/linux-2.4.21/include/linux/version.h autoconf.h 文件是不是生成了,這是編譯glibc是要用到。version.h autoconf.h 文件的存在,說(shuō)明你生成了正確的頭文件。

然后,建立工具鏈需要的include目錄,并將內(nèi)核頭文件復(fù)制過(guò)去。

--------------------------------------------------------------------------------

$cd include

$ln -s asm-arm asm #可以查看一下,經(jīng)過(guò)編譯可以自動(dòng)生成。如果已經(jīng)生成連接,則不必寫(xiě)

$cd asm

$ln -s arch-epxa arch  #同上說(shuō)明

$ln -s proc-armv proc  #同上說(shuō)明

                    #這些是針對(duì)makefile文件作出的修改

$mkdir –p $TARGET_PREFIX/include

$cp –r $PRJROOT/kernel/linux-2.4.21/include/linux $TARGET_PREFIX/include

$cp –r $PRJROOT/kernrl/linux-2.4.21/include/asm-arm $TARGET_PREFIX/include/asm

************************************************************

注意:

1、不必再每次重新設(shè)定內(nèi)核配置之后重建工具鏈,除非你變更了處理器或系統(tǒng)的類(lèi)型。工具鏈只需要一組可供目標(biāo)板使用的有效頭文件即可,這些頭文件在前面的程序中早就已經(jīng)提供了。

2、asm-linux文件夾放到目標(biāo)文件夾$TARGET_PREFIX/include/時(shí)要更改名稱為asm,因?yàn)榕渲梦募?/span>include包含都是<asm/*.h>方式。這也是交叉編譯的不同之處。否則就會(huì)出現(xiàn)類(lèi)似下面的錯(cuò)誤提示:

--------------------------------------------------------------------------------

   .........

    done

    _udivsi3

    _divsi3

    _umodsi3

    _modsi3

    _dwmd_lnx

    libgcc1.s:438:asm/unistd.h:No such file or directory

make [1] *** [libgcc1-asm.a] error 1

--------------------------------------------------------------------------------

3.5  binutils(二進(jìn)制工具程序)的設(shè)置

    binutils包中的工具常用來(lái)操作二進(jìn)制目標(biāo)文件。該包中最重要的兩個(gè)工具就是GNU匯編器as和鏈接器ld。

************************************************************

$cd $PRJROOT/src-dir

$tar xvzf ../setup-dir/binutils-2.11.2.tar.gz

$cd $PRJROOT/build-dir/build-binutils

$../../src-dir/binutils-2.11.2/configure --target=$TARGET --prefix=$PREFIX

$make

$make install

$ls $PREFIX/bin           驗(yàn)證安裝的結(jié)果是否正確

arm-linux-addr2line  arm-linux-ld  arm-linux-readelf

arm-linux-ar  arm-linux-nm  arm-linux-size

arm-linux-as  arm-linux-objcopy  arm-linux-strings

arm-linux-c++filt  arm-linux-objdump  arm-linux-strip

arm-linux-gasp  arm-linux-ranlib

************************************************************

    注意:每個(gè)工具的文件名的前綴都是前面為TARGET變量設(shè)定的值。如果目標(biāo)板是i386-linux,那么這些工具的文件名前綴就會(huì)是i386-linux-。這樣就可以根據(jù)目標(biāo)板類(lèi)型找到正確的工具程序。

3.6  初始編譯器的建立

開(kāi)始只能建立支持C語(yǔ)言的引導(dǎo)編譯器,因?yàn)槿鄙?/span>C鏈接庫(kù)(glibc)的支持。等到glibc編譯好之后,可以重新編譯gcc并提供完整的C++支持。

************************************************************

$cd $PRJROOT/setup-dir

$mv gcc-core-2.95.3.tar.gz gcc-2.95.3.tar.gz  #重命名

$cd $PRJROOT/src-dir

$tar xvzf ../setup-dir/gcc-2.95.3.tar.gz

$cd $PRJROOT/build-dir/build-gcc

$../../src-dir/gcc-2.95.3/configure --target=$TARGET --prefix=$PREFIX --without-headers
--enable-languages=c

--------------------------------------------------------------------------------

    因?yàn)槭墙徊婢幾g器,還不需要目標(biāo)板的系統(tǒng)頭文件,所以需要使用 --without-headers這個(gè)選項(xiàng)。--enable-language=c用來(lái)告訴配置腳本,需要產(chǎn)生的編譯器支持何種語(yǔ)言,現(xiàn)在只能支持C語(yǔ)言。--disable-threads是因?yàn)?/span>threads需要glibc的支持。

    準(zhǔn)備好了Makefile文件,進(jìn)行編譯之前,需要修改src-dir/gcc-2.95.3/gcc/config/arm/t-linux文件,在TARGET_LIBGCC2_CFLAGS中添加兩個(gè)定義:-Dinhibit_libc -D__gthr_posix_h,否則會(huì)報(bào)錯(cuò)。

--------------------------------------------------------------------------------

$make

$make install

************************************************************

3.7  建立C庫(kù)(glibc

    這一步是最為繁瑣的過(guò)程。目標(biāo)板必須靠它來(lái)執(zhí)行或者是開(kāi)發(fā)大部分的應(yīng)用程序。glibc套件常被稱為C鏈接庫(kù),但是glibc實(shí)際產(chǎn)生很多鏈接庫(kù),其中之一是C鏈接庫(kù)libc。因?yàn)榍度胧较到y(tǒng)的限制,標(biāo)準(zhǔn)GNU C鏈接庫(kù)顯得太大,不適合應(yīng)用在目標(biāo)板上。所以需要尋找C鏈接庫(kù)的替代品,比如uClibc。在這里,現(xiàn)以標(biāo)準(zhǔn)GNU C為例建立工具鏈。

************************************************************

$cd $PRJROOT/src-dir

$tar xvzf ../setup-dir/glibc-2.2.4.tar.gz

$tar xvzf ../setup-dir/glibc-linuxthreads-2.2.4.tar.gz --directory=glibc-2.2.4

$cd $PRJROOT/build-dir/build-glibc

$CC=arm-linux-gcc ../../src-dir/glibc-2.2.4/configure --host=$TARGET --prefix=”/usr”
--enable-add-ons --with-headers=$TARGET_PREFIX/include

$make

$make install_root=$TARGET_PREFIX prefix=”” install

--------------------------------------------------------------------------------

在這里設(shè)定了install_root變量,指向鏈接庫(kù)組件目前所要安裝的目錄。這樣可以讓鏈接庫(kù)及其頭文件安裝到通過(guò)TARGET_PREFIX指定的與目標(biāo)板有關(guān)的目錄,而不是建立系統(tǒng)本身的/usr目錄。因?yàn)橹笆褂?/span>--prefix選項(xiàng)來(lái)設(shè)定prefix變量的值,而且prefix的值會(huì)被附加到install_root的值之后,成為鏈接庫(kù)組件的安裝目錄,所以需要重新設(shè)定prefix的值。這樣所有的glibc組件將會(huì)安裝到$TARGET_PREFIX指定的目錄下。

--------------------------------------------------------------------------------

$cd $TARGET_PREFIX/lib

$cp ./libc.so ./libc.so.orig

--------------------------------------------------------------------------------

編輯文件libc.so,更改如下:

/* GNU ld script

  Use the shared library,but some functions are only in

  the static library,so try that secondarily.*/

GROUP(libc.so.6 libc_nonshared.a)

--------------------------------------------------------------------------------

************************************************************

3.8  完整編譯器的設(shè)置

    現(xiàn)在可以為目標(biāo)板安裝支持CC++的完整編譯器了。這個(gè)步驟相對(duì)于前面來(lái)建立過(guò)程要簡(jiǎn)單一些。

************************************************************

$cd $PRJROOT/build-dir/build-gcc

$../../src-dir/gcc-2.95.3/configure --target=$TARGET --prefix=$PREFIX
--enable-languages=c,c++

$make all

$make install

************************************************************

3.9  完成工具鏈的設(shè)置

************************************************************

$cd $TARGET_PREFIX/bin

$file as ar gcc ld nm ranlib strip   查看文件是否為二進(jìn)制文件

 

$arm-linux-gcc -print-search-dirs  查看缺省的搜尋路徑

 

$mv as ar gcc ld nm ranlib strip $PREFIX/lib/gcc-lib/arm-linux/2.95.3  轉(zhuǎn)移文件

 

$for file in as ar gcc ld nm ranlib strip

>do

>ln -s $PREFIX/lib/gcc-lib/arm-linux/2.95.3/$file

>done

************************************************************

3.10  使用工具鏈

下面編寫(xiě)一個(gè)簡(jiǎn)單的C程序,使用建立的工具鏈。、

************************************************************

$cd $PRJROOT/program

$emacs hello.c

--------------------------------------------------------------------------------

在文本編輯器emacs中編寫(xiě):

#include <stdio.h>

 

int main()

{

       int i;

       for(i=1;i<9;i++)

              printf(“Hello World %d times!\n”,i);

}

保存退出

--------------------------------------------------------------------------------

$gcc -g hello.c -o hello

$gdb

(gdb)file hello

(gdb)l

#include <stdio.h>

 

int main()

{

       int i;

       for(i=1;i<9;i++)

              printf(“Hello World %d times!\n”,i);

}

(gdb)r

(gdb)q

$arm-linux-gcc -g hello.c -o hello-linux

$file hello-linux

hello-linux:ELF 32-bit LSB executable,ARM,version 1(ARM),for GNU/Linux 2.0.0,dynamically linked(uses shared libs),not stripped

************************************************************

上面的輸出說(shuō)明你編譯了一個(gè)能在 arm 體系結(jié)構(gòu)下運(yùn)行的 hello-linux,證明你的編譯工具做成功了。

4 總結(jié)

通過(guò)上面的操作,已經(jīng)能夠建立全功能的跨平臺(tái)開(kāi)發(fā)工具鏈,在以后的嵌入式開(kāi)發(fā)中將會(huì)經(jīng)常用到。

 

 

 

說(shuō)明:-----之間為說(shuō)明文字

      ***之間為源程序

參考:

[1] http://www./arm/arm-2004.htm

[2] 構(gòu)建嵌入式LINUX系統(tǒng),中國(guó)電力出版社

[3] http://www-128.ibm.com/developerworks/cn/linux/l-embcmpl/ 如何為嵌入式開(kāi)發(fā)建立交叉編譯環(huán)境,梁元恩

[4] http://www./oldsite/armlinux//docs/toolchain/toolchHOWTO/t2.html The GNU Toolchain for ARM targets HOWTO

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多