在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統 > 設計應用 > Linux ARM交叉編譯工具鏈制作過程

            Linux ARM交叉編譯工具鏈制作過程

            作者: 時間:2016-11-21 來源:網絡 收藏
            一、下載源文件
            源代碼文件及其版本與下載地址:
            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/

            一般一個完整的交叉編譯器涉及到多個軟件,主要包括binutils、gcc、glibc等。其中,binutils主要生成一些輔助工具;gcc是用來生成交叉編譯器,主要生成arm-linux-gcc交叉編譯工具,而glibc主要提供用戶程序所需要的一些基本函數庫。

            二、建立工作目錄
            編譯所用主機型號 FC12.i686
            第一次編譯時用的是root用戶(第二次用一般用戶karen,該用戶可以使用sudo指令)
            所有的工作目錄都在/home/Karen/cross下面建立完成,首先在/home/karen目錄下建立cross目錄
            [root@localhost karen] mkdir cross
            進入工作目錄:
            [root@localhost root]#cd /home/karen/cross
            查看當前目錄:
            [root@localhost cross]# pwd
            /home/karen/cross
            創(chuàng)建工具鏈文件夾:
            [root@localhost cross]# mkdir embedded-toolchains
            在建立了頂層文件夾embedded- toolchains,下面在此文件夾下建立如下幾個目錄:
            Ø setup-dir,存放下載的壓縮包;
            Ø src-dir,存放binutils、gcc、glibc解壓之后的源文件;
            Ø kernel,存放內核文件,對內核的配置和編譯工作也在此完成;
            Ø build-dir,編譯src-dir下面的源文件,這是GNU推薦的源文件目錄與編譯目錄分離的做法;
            Ø tool-chain,交叉編譯工具鏈的安裝位;
            Ø program,存放編寫程序;
            Ø doc,說明文檔和腳本文件;
            下面建立目錄,并拷貝源文件。
            [root@localhost cross] #cd embedded- toolchains
            [root@localhost embedded- toolchains] #mkdir setup-dir src-dir kernel build-dir tool-chain program doc
            [root@localhost embedded- toolchains] #ls
            build-dir doc kernel program setup-dir src-dir tool-chain
            [root@localhost embedded- toolchains] #cd setup-dir
            拷貝源文件:
            這里我們采用直接拷貝源文件的方法,首先應該修改setup-dir的權限
            [root@localhost embedded- toolchains] #chmod 777 setup-dir
            然后直接拷貝/home/karen目錄下的源文件到setup-dir目錄中,如下圖:



            建立編譯目錄:
            [root@localhost setup-dir] #cd ../build-dir
            [root@localhost build -dir] #mkdir build-binutils build-gcc build-glibc
            三、輸出環(huán)境變量
            輸出如下的環(huán)境變量方便我們編譯。
            為簡化操作過程。下面就建立shell命令腳本environment-variables:
            [root@localhost build -dir] #cd ../doc
            [root@localhost doc] #mkdir scripts
            [root@localhost doc] #cd scripts
            用編輯器vi編輯環(huán)境變量腳本envionment-variables:
            [root@localhost scripts] #vi envionment-variables
            exportPRJROOT=/home/mxl/diliuzhang/embedded- toolchains
            exportTARGET=arm-linux
            exportPREFIX=$PRJROOT/tool-chain
            exportTARGET_PREFIX=$PREFIX/$TARGET
            exportPATH=$PREFIX/bin:$PATH
            截圖如下:


            %% Q:為什么用了source ./environment-variables才正常執(zhí)行,去掉source就沒有執(zhí)行? %%
            %% 如果用source 執(zhí)行, 不需要腳本有執(zhí)行權限, 權限為664也可以,執(zhí)行命令如下:%%
            %% Source environment-variables %%

            說明:
            TARGET變量用來定義目標板的類型,以后會根據此目標板的類型來建立工具鏈。參
            看表6-1所示。目標板的定義與主機的類型是沒有關系的,但是如果更改TARGET的值,
            GNU工具鏈必須重新建立一次。
            PREFIX變量提供了指針,指向目標板工具程序將被安裝的目錄。
            TARGET_PREFIX變量指向與目標板相關的頭文件和鏈接庫將被安裝的目錄。
            PATH變量指向二進制文件(可執(zhí)行文件)將被安裝的目錄。
            如果不慣用環(huán)境變量的,可以直接用絕對或相對路徑。如果不用環(huán)境變量,一般都用絕對路徑,相對路徑有時會失敗。環(huán)境變量也可以定義在.bashrc文件中,這樣就不用老是export這些變量了。
            體系結構和TAEGET變量的對應如下表6-1所示:
            表6-1 體系結構和TAEGET變量的對應
            體系結構TARGET變量的值
            PowerPCPowerpc-linux
            ARMarm-linux
            MIPS(big endian)mips-linux
            MIPS(little endian)mipsel-linux
            MIPS64mips64-linux
            SuperH3sh3-linux
            SuperH4sh4-linux
            I386i386-linux
            Ia64ia64-linux
            M68km68k-linux
            M88km88k-linux
            Alphaalpha-linux
            Sparcsparc-linux
            Sparc64sparc64-linux
            四、建立二進制工具(binutils)
            Binutils是GNU工具之一,它包括連接器、匯編器和其他用于目標文件和檔案的工具,它是二進制代碼的處理維護工具。安裝Binutils工具包含的程序有addr2line、ar、as、c++filt、gprof、ld、nm、objcopy、objdump、ranlib、readelf、size、strings、strip、libiberty、libbfd和libopcodes。對這些程序的簡單解釋如下。
            Ø addr2line 把程序地址轉換為文件名和行號。在命令行中給它一個地址和一個可執(zhí)行文件名,它就會使用這個可執(zhí)行文件的調試信息指出在給出的地址上是哪個文件以及行號。
            Ø ar 建立、修改、提取歸檔文件。歸檔文件是包含多個文件內容的一個大文件,其結構保證了可以恢復原始文件內容。
            Ø as 主要用來編譯GNU C編譯器gcc輸出的匯編文件,產生的目標文件由連接器ld連接。
            Ø c++filt 連接器使用它來過濾 C++ 和 Java 符號,防止重載函數沖突。
            Ø gprof 顯示程序調用段的各種數據。
            Ø ld 是連接器,它把一些目標和歸檔文件結合在一起,重定位數據,并連接符號引用。通常,建立一個新編譯程序的最后一步就是調用ld。
            Ø nm 列出目標文件中的符號。
            Ø objcopy 把一種目標文件中的內容復制到另一種類型的目標文件中。
            Ø objdump 顯示一個或者更多目標文件的信息。使用選項來控制其顯示的信息,它所顯示的信息通常只有編寫編譯工具的人才感興趣。
            Ø ranlib 產生歸檔文件索引,并將其保存到這個歸檔文件中。在索引中列出了歸檔文件各成員所定義的可重分配目標文件。
            Ø readelf 顯示elf格式可執(zhí)行文件的信息。
            Ø size 列出目標文件每一段的大小以及總體的大小。默認情況下,對于每個目標文件或者一個歸檔文件中的每個模塊只產生一行輸出。
            Ø strings 打印某個文件的可打印字符串,這些字符串最少4個字符長,也可以使用選項-n設置字符串的最小長度。默認情況下,它只打印目標文件初始化和可加載段中的可打印字符;對于其它類型的文件它打印整個文件的可打印字符。這個程序對于了解非文本文件的內容很有幫助。
            Ø strip 丟棄目標文件中的全部或者特定符號。
            Ø libiberty 包含許多GNU程序都會用到的函數,這些程序有getopt、obstack、strerror、strtol和strtoul。
            Ø libbfd 二進制文件描述庫。
            Ø libopcode 用來處理opcodes的庫,在生成一些應用程序的時候也會用到它。
            Binutils工具安裝依賴于Bash、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Perl、Sed、Texinfo等工具
            下面將分步介紹安裝binutils-2.19.2的過程。
            [root@localhost script] # cd $PRJROOT/src-dir
            [root@localhost src-dir] # tar jxvf ../setup-dir/binutils-2.19.tar.bz2
            [root@localhost src-dir] # cd $PRJROOT/build-dir/build-binutils
            創(chuàng)建Makefile:
            [root@localhost build-binutils] #../../src-dir/binutils-2.19/configure --target=$TARGET --prefix=$PREFIX
            在build-binutils目錄下面生成Makefile文件,然后執(zhí)行make,make install。完成后可以在$PREFIX/bin下面看到我們的新的binutil。
            注意:每個工具的文件名的前綴都是前面為TARGET變量設定的值。如果目標板arm-linux,那么這些工具的文件名前綴就會是arm-linux-。這樣就可以根據目標板類型找到正確的工具程序。



            五、建立內核頭文件
            在這里我們使用時2.6.29的內核版本,因為交叉工具鏈工具鏈是針對特定的處理器和操作系統的,因此在編譯之前就需要對linux內核進行配制,可以通過“make config”或“make menuconfig”命令對內核進行配制,配制完成后,在linux源文件的目錄下就會生成一個.config文件,這就是我們所需要的文件。
            Note: 目標板的內核版本是2.6.29

            [root@localhost embedded- toolchains] #cd kernel
            [root@localhost kernel] #tar jxvf ../setup-dir/ linux-2.6.29.tar.bz2
            [root@localhost kernel] #bunzip2 ../setup-dir/ patch-2.6.29.bz2
            [root@localhost kernel] #cd linux-2.6.29
            給Linux內核打補丁:
            [root@localhost linux-2.6.29] #patch –p1 < ../../setup-dir/patch-2.6.29
            然后就是配置內核,第一步是修改Makefile
            修改 Makefile:
            ARCH = arm
            CROSS_COMPILE = arm-linux- menuconfig
            接著使用make menuconfig進入內核配置菜單
            或者直接寫:
            # make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig,注意在配置時一定要選擇處理器的類型,比如我的目標機使用的處理器是OMAP類型的,就選TI OMAP:
            System Type -à
            ARM System Type -à
            (x) TI OMAP
            配置完退出并保存。
            配置完須執(zhí)行make,參數如下:
            [root@localhost linux-2.6.29]# make ARCH=arm CROSS_COMPILE=arm-linux- (執(zhí)行過程中有錯誤出現也沒關系,主要目的是產生頭文件version.h和autoconf.h)
            執(zhí)行完檢查一下內核目錄中的/kernel/linux-2.6.29/include/linux/version.h和autoconf.h文件是不是生成了,這是編譯glibc要用到的。version.h 和 autoconf.h 文件的存在,說明你生成了正確的頭文件。
            接下來建立工具鏈需要的include目錄,并將內核頭文件復制過去。
            [root@localhost linux-2.6.29] #cd include
            [root@localhost include] #ln -s asm-arm asm
            可以查看一下,經過編譯可以自動生成。如果已經生成鏈接,則不必重新鏈接。(2.6.29已自動生成)
            [root@localhost include] #cd asm
            [root@localhost asm] #ln -s arch-epxa arch
            [root@localhost asm] #ln -s proc-armv proc
            可以查看一下,經過編譯可以自動生成。如果已經生成鏈接,則不必重新鏈接。
            復制頭文件到交叉編譯工具鏈的安裝目錄:
            [root@localhost asm] #mkdir –p $TARGET_PREFIX/include
            [root@localhost asm] #cp –r $PRJROOT/kernel/linux-2.6.29/include/linux $TARGET_PREFIX/include
            [root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/include/asm-arm $TARGET_PREFIX/include/asm
            [root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/include/asm-generic $TARGET_PREFIX/include
            root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/arch/arm/include/asm $TARGET_PREFIX/include
            root@localhost asm] #cp –r $PRJROOT/ kernel /linux-2.6.29/arch/arm/mach-omap2/include/mach $TARGET_PREFIX/include/asm
            Note: mach-xxx是根據目標板所用的cpu類型來選擇的

            六、建立初始編譯器 (boot strap gcc)
            這一步的目的主要是建立arm-linux-gcc工具,注意這個gcc沒有glibc庫的支持,所以只能用于編譯內核、BootLoader等不需要C庫支持的程序,后面創(chuàng)建C庫也要用到這個編譯器,所以創(chuàng)建它主要是為創(chuàng)建C庫做準備,如果只想編譯內核和BootLoader,那么安裝完這個就可以到此結束。安裝過程如下:
            [root@localhost build-binutils] #cd $PRJROOT/setup-dir
            重命名:
            [root@localhost setup-dir] #mv gcc-core-4.4.4.tar.bz2 gcc-4.4.4.tar.bz2
            [root@localhost setup-dir] #cd $PRJROOT/src-dir
            [root@localhost src-dir] #tar jxvf ../setup-dir/gcc-4.4.4.tar.bz2
            從 GCC-4.3起,安裝GCC將依賴于GMP-4.1以上版本和MPFR-2.3.2以上版本。如果將這兩個軟件包分別解壓到GCC源碼樹的根目錄下,并分別命名為"gmp"和"mpfr",那么GCC的編譯程序將自動將兩者與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
            •因為是交叉編譯器,還不需要目標板的系統頭文件,所以需要使用 --without-headers這個選項。否則會有很多*.h頭文件找不到的報錯
            •--enable-language=c用來告訴配置腳本,需要產生的編譯器支持何種語言,現在只需支持C語言。雖然配置為c,c++也可以的
            •--disable-threads 是因為threads需要libc的支持。
            •--disable-decimal-float,需要libc的支持,而我們在初步編譯的時候尚未生成libc,否則出現以下的報錯:
            ../../../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交叉編譯工具,那么本機的glibc支持的應該是本機的編譯工具庫,而不是ARM交叉編譯工具庫。forces GCC to link its internal libraries statically,沒有這個選項,會有 crti.o: No such file: No such file or directory collect2: ld returned 1 exit status
            注:由于沒有arm的glibc,需要使用--disable-libmudflap --disable-libssp,禁止兩個邊界檢查使用的庫。
            同樣,由于第一次安裝ARM交叉編譯工具,那么支持的libc庫的頭文件也沒有,src-dir/gcc-4.4.4/gcc/config/arm/t-linux文件,在TARGET_LIBGCC2_CFLAGS中添加兩個定義:-Dinhibit_libc –D__gthr_posix_h
            原文:
            TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer –fPIC
            改后:
            TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D_gthr_posix.h
            編譯:
            [root@localhost src-dir] #cd $PRJROOT/build-dir/build-gcc
            [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
            [root@localhost build-gcc]# make all-gcc
            [root@localhost build-gcc]# make install-gcc
            [root@localhost build-gcc]# make all-target-libgcc
            [root@localhost build-gcc]# make install-target-libgcc
            注:很多資料中之有前面兩項,這只建立了gcc,沒有建立libgcc.a,這樣會在glibc的編譯中出現-lgcc沒有找到的錯誤。報告:
            ……/build-tools/build-glibc/libc_pic.a
            i586-linux-gcc -nostdlib -nostartfiles -r -o /home/wei/workspace/mywork/moblin/build-tools/build-glibc/elf/librtld.map.o -Wl,-( /home/wei/workspace/mywork/moblin/build-tools/build-glibc/elf/dl-allobjs.os /home/wei/workspace/mywork/moblin/build-tools/build-glibc/libc_pic.a -lgcc -Wl,-) -Wl,-Map,/home/wei/workspace/mywork/moblin/build-tools/build-glibc/elf/librtld.mapT
            /workspace/wei/mywork/moblin/tools/bin/../lib/gcc/arm-linux/4.4.4/../../../../ram-linux/bin/ld: cannot find -lgcc
            在glibc的編譯中,還需要libgcc_eh.a(否則出現錯誤:-lgcc_eh沒有找到……bin/ld: cannot find -lgcc_eh),使用了--disable-shared的選項,將不會生成libgcc_eh.a,可以通過對libgcc.a的鏈接來實現。
            [root@localhost build-gcc]# ln -vs libgcc.a `arm-linux-gcc -print-libgcc-file-name | sed s/libgcc/&_eh/`
            Note:arm-linux-gcc與-print-libgcc-file-name之間有一個空格  
            運行報告:
            “/workspace/wei/mywork/moblin/tools/bin/../lib/gcc/i586-linux/4.3.3/libgcc_eh.a” -> “libgcc.a”
            裝完成后,查看結果:
            [root@localhost build-gcc] #ls $PREFIX/bin


            如果arm-linux-gcc等工具已經生成,表示boot trap gcc工具已經安裝成功
            七、編譯glibc
            這一步是最為繁瑣的過程,目標板必須靠它來執(zhí)行或者是開發(fā)大部分的應用程序。glibc套件常被稱為C鏈接庫,但是glibc實際產生很多鏈接庫,其中之一是C鏈接庫libc。因為嵌入式系統的限制,標準GNU C鏈接庫顯得太大,不適合應用在目標板上。所以需要尋找C鏈接庫的替代品,在這里現以標準GNU C為例建立工具鏈。
            [root@localhost build-gcc] #cd $PRJROOT/src-dir
            [root@localhost src-dir] # tar jxvf ../setup-dir/glibc-2.11.2.tar.bz2
            [root@localhost src-dir] # tar jxvf ../setup-dir/glibc-ports-2.11.tar.bz2
            [root@localhost src-dir] # mv –v glibc-ports-2.11 glibc-2.11.2/ports
            [root@localhost src-dir] # cd glibc-2.11.2
            [root@localhost glibc-2.11.2] # patch –Np1 –i ../../setup-dir/glibc-2.11.2-gcc_fix-1.patch
            [root@localhost glibc-2.11.2] # patch –Np1 –i ../../setup-dir/glibc-2.11.2-makefile_fix-1.patch
            [root@localhost glibc-2.11.2] # cd $PRJROOT/build-dir/build-glibc
            [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
            [root@localhost build-glibc] # make
            [root@localhost build-glibc] # make install

            注:以上完成后,請查看一下$TARGET_PREFIX/lib目錄下的文件libc.so,看看GROUP的內容是否指定到可以用于交叉編譯的庫,如果不是請修改,如下。
            libc.so 文件(所在目錄是$TARGET_PREFIX/lib),將GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a)改為GROUP ( libc.so.6 libc_nonshared.a)
            這樣連接程序 ld 就會在 libc.so 所在的目錄查找它需要的庫,因為你的機子的/lib目錄可能已經裝了一個相同名字的庫,一個為編譯可以在你的宿主機上運行的程序的庫,而不是用于交叉編譯的。
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            經過查看,發(fā)現libc.so中的GROUP已經是交叉編譯鏈的目錄,所以不用更改
            對 libc.so 的修正·

            vi $PREFIX /${TARGET}/lib/libc.so

            去掉絕對路徑,修改后的內容如下:



            OUTPUT_FORMAT(elf32-littlearm)

            GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) )
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            八、建立全套編譯器 (full gcc)
            [root@localhost build-gcc] #../../src-dir/gcc-4.4.4/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ --enable-shared
            [root@localhost build-gcc] #make all
            [root@localhost build-gcc] #make install


            我們再來看看 $PREFIX/bin 里面多了哪些東西。你會發(fā)現多了 arm-linux-g++ 、和 arm-linux-c++ 幾個文件。
            G++-gnu的 c++ 編譯器。
            C++-gnu 的 c++ 編譯器。
            至此,整個交叉編譯環(huán)境就建立完成了。
            九、完成工具鏈的設置
            root@localhost build-gcc] # cd $TARGET_PREFIX/bin
            查看文件是否為二進制文件:
            [root@localhost bin] # file as ar gcc ld nm ranlib strip
            查看缺省的搜尋路徑:
            [root@localhost bin] #arm-linux-gcc -print-search-dirs
            十、測試和驗證交叉編譯工具
            下面編寫一個簡單的C程序,使用建立的工具鏈。、
            [root@localhost bin] #cd $PRJROOT/program
            [root@localhost program] #vi hello.c
            #include
            int main(void)
            {
            printf("hello linux/n");
            return 0;
            }
            [root@localhost program] #arm-linux-gcc hello.c -o hello –static (制作靜態(tài)可執(zhí)行文件)
            制作的可執(zhí)行文件hello可以直接在目標機上運行。




            評論


            技術專區(qū)

            關閉