歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

交叉工具鏈制作至尊寶典

一些必須知道的基礎知識

  • Debian 操作系統 以及 aptitude 命令
  • autoconf and automake
  • 什麼是交叉編譯,configure 的幾個參數 build host target

    build:
    編譯代碼的機器,的CPU指令集

    host:
    編譯生成的東西,的CPU指令集(目標板上的CPU的指令集)

    target:
    編譯生成的東西,他編譯生成的的東西,的指令集(所以此選項一般不用,大多只有在做交叉工具鏈時使用)

    0、以Expert mode 安裝Debian

    不要升級,確保環境是一個純淨的環境

    1、聲明環境變量 

     
    1. export IS_TARGET=arm-linux  
    2. export DIR_SRC=/root/cross_toolchains/src  
    3. export PREFIX=/opt/cross_toolchains/arm  
    4. export CONFIGURE_BASE="../configure --prefix=$PREFIX --with-sysroot=$PREFIX"  

    2、下載制作交叉工具鏈所必須的的代碼

     
    1. binutils  
    2. ftp://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.gz  
     
    1. gcc  
    2. ftp://ftp.gnu.org/gnu/gmp/gmp-5.0.2.tar.gz  
    3. ftp://ftp.gnu.org/gnu/mpfr/mpfr-3.0.1.tar.gz  
    4. http://www.multiprecision.org/mpc/download/mpc-0.9.tar.gz  
    5. ftp://ftp.gnu.org/gnu/gcc/gcc-4.6.1/gcc-4.6.1.tar.gz  
     
    1. glibc  
    2. ftp://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz  
    3. ftp://ftp.gnu.org/gnu/glibc/glibc-ports-2.13.tar.gz  
     
    1. linux kernel  
    2. http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.2.tar.bz2  

    3、安裝(卸載)必要的的軟件包

     
    1. aptitude install build-essential automake bison flex texinfo gawk g\+\+  
    2. aptitude remove mawk  

    4、解壓、歸檔軟件包

     
    1. cd $DIR_SRC  
    2. tar -xf binutils-2.21.tar.gz  
    3. tar -xf gmp-5.0.2.tar.gz  
    4. tar -xf mpc-0.9.tar.gz  
    5. tar -xf mpfr-3.0.1.tar.gz  
    6. tar -xf gcc-4.6.1.tar.bz2  
    7. tar -xf glibc-2.14.tar.gz  
    8. tar -xf glibc-ports-2.13.tar.gz  
    9. tar -xf linux-2.6.39.2.tar.bz2  
     
    1. mv gmp-5.0.2 gcc-4.6.1/gmp  
    2. mv mpc-0.9 gcc-4.6.1/mpc  
    3. mv mpfr-3.0.1 gcc-4.6.1/mpfr  
    4. mv glibc-ports-2.13 glibc-2.14/ports  

    5、編譯 BINUTILS

     
    1. cd $DIR_SRC  
    2. cd binutils-2.21  
    3. mkdir build  
    4. cd build  
    5. $CONFIGURE_BASE --target=$IS_TARGET --disable-nls --enable-shared --disable-multilib  
     
    1. make configure-host  
    2. make  
    3. make install  
     
    1. export PATH=$PATH:$PREFIX/bin  

    問題:
    編譯binutils一般不會遇到什麼問題,但是,如果前面步驟3中安裝的軟件不全會出現問題

    6、建立用於編譯C庫的GCC

     
    1. cd $DIR_SRC  
    2. cd gcc-4.6.1  
    3. mkdir build   
    4. cd build  
    5. $CONFIGURE_BASE \  
    6. --target=$IS_TARGET \  
    7. --disable-nls \  
    8. --disable-shared \  
    9. --without-headers \  
    10. --with-newlib \  
    11. --enable-languages=c \  
    12. --disable-threads \  
    13. --disable-multilib \  
    14. --disable-decimal-float \  
    15. --disable-libgomp \  
    16. --disable-libmudflap \  
    17. --disable-libssp  
     
    1. make all-gcc all-target-libgcc  
    2. make install-gcc install-target-libgcc  
     
    1. 值得注意的幾個configure選項  
    2. --target  
    3. --disable-shared  
    4. --without-headers  
    5. --with-newlib  
    6. --enable-language-c  
    7. --disable-thread  
     
    1. cd $PREFIX/lib/gcc/$IS_TARGET/4.6.1  
    2. ln -s libgcc.a libgcc_eh.a  
     
    1. 有建議修改 gcc/config/t-linux 這個文件  
    2. 增加 -D__gthr_posix_h -Dinhibit_libc 兩個宏,但我這裡沒這樣做,是因為:  
    3. 在configure後,編譯使用的命令並不是 make 或者是 make all 而是 make all-gcc 和 make all-target-libgcc,所以很多問題不會出現  
    4. -with-newlib,這個選項不會迫使我們必須使用newlib  
     
    1. libgcc.mvars: No such file or directory  
    2. 不能在 GCC 的源代碼目錄進行configure,必須在另外的目錄進行configure make 等工作  
    3. 所以這裡在代碼所在目錄下 mkdir build 並 cd build 再進行 ../configure 等工作  
     
    1. configure: error: C compiler cannot create executables  
    2. 如果使用 make 或 make all 會出現這樣的問題,因為我們還未編譯出目標指令集的 C 庫  
    3. 所以只能先使用 make all-gcc make all-target-libgcc  
     
    1. ../../../../arm-linux/bin/ld: cannot find -lgcc  
    2. ../../../../arm-linux/bin/ld: cannot find -lgcc_eh  
    3. 很多資料都只寫了 make all-gcc 而沒有寫 make all-target-libgcc 這樣只建立了gcc,沒有建立libgcc.a會出現以上第一個錯誤  
    4. 如果沒手工建立鏈接文件 libgcc_eh.a 則會出現第二個錯誤  

    7、配置內核生成必要的頭文件

     
    1. cd $DIR_SRC  
    2. cd linux-2.6.39.2  
    3. make ARCH=arm CROSS_COMPILE=$IS_TARGET- menuconfig  
    4. make ARCH=arm CROSS_COMPILE=$IS_TARGET-  
     
    1. mkdir -p $PREFIX/include  
    2. cd $PREFIX/include  
    3. ln -s $DIR_SRC/linux-2.6.39.2/arch/arm/include/asm asm  
    4. ln -s $DIR_SRC/linux-2.6.39.2/include/linux linux  
    5. ln -s $DIR_SRC/linux-2.6.39.2/include/asm-generic asm-generic  
     
    1. 這裡並沒有將內核的頭文件復制到交叉工具鏈的安裝目錄  
    2. 編譯C庫的時候,需要對應的CPU指令集的匯編代碼所以做了鏈接處理  
     
    1. 編譯內核在執行 make ARCH=arm CROSS_COMPILE=$IS_TARGET- 時如果出錯,是沒有關系的,這裡只要生成了對應的 version.h autoconf.h就可以了  

    8、編譯C庫

     
    1. cd $DIR_SRC  
    2. cd glibc-2.9  
    3. mkdir build  
    4. cd build  
     
    1. vi ../configure  
    2. vi ../ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S  
    3. vi ../sysdeps/unix/syscall-template.S   
    4. vi ../nptl/allocatestack.c   
    5. vi ../elf/dl-tls.c  
    6. vi ../sysdeps/ieee754/dbl-64/s_fma.c  
    7. vi ../sysdeps/ieee754/dbl-64/s_fmaf.c  
    8.   
    9. 具體的修改,我寫在下面(覺得還是要說清楚為什麼修改,所以就沒用sed命令或是做一些patch文件了,請向下看)  
     
    1. CC=$IS_TARGET-gcc \  
    2. $CONFIGURE_BASE \  
    3. --host=$IS_TARGET \  
    4. -enable-add-ons \  
    5. --with-binutils=$PREFIX/bin \  
    6. --with-headers=$PREFIX/include \  
    7. libc_cv_forced_unwind=yes \  
    8. libc_cv_c_cleanup=yes  
     
    1. 值得注意的幾個configure選項  
    2. --host  
    3. --with-headers  
    4. lib_cv_forced_unwind  
    5. lib_cv_c_cleanup  
     
    1. make  
    2. make install   
     
    1. 這裡編譯的時候並有選擇TARGET為EABI,所以在制作交叉工具鏈時會有很多問題需要修改  
     
    1. *** These critical programs are missing or too old: as ld  
    2. *** Check the INSTALL file for required versions.  
    3. vi ../configure   
    4. 查找  "$AS --version" 將 2.1[3-9] 修改為 2.[1-2][0-9]  
    5. 查詢  "$LD --version" 將 2.1[3-9] 修改為 2.[1-2][0-9]  
     
    1. Error: previous CFI entry not closed (missing .cfi_endproc)  
    2. vi ../ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S  
    3. ENTRY(__default_sa_restorer) 下增加  
    4. END(__default_sa_restorer)  
    5. ENTRY(__default_rt_sa_restorer) 下增加  
    6. END(__default_rt_sa_restorer)  
     
    1. syscall-template.S:82: Error: CFI instruction used without previous .cfi_startproc  
    2. vi ../sysdeps/unix/syscall-template.S   
    3. 這個問題的修改我也不是十分確定,我是這樣來思考的  
    4. 看到 syscall-template.S 中 有 #include <sysdep.h>  
    5. 去查看 ports/sysdeps/unix/sysv/linux/arm/sysdep.h  
    6. 看到如下代碼  
    7. #ifdef __ASSEMBLER__  
    8. #undef  PSEUDO  
    9.   
    10. #define PSEUDO(name, syscall_name, args)                                      \  
    11.   .text;                                                                      \  
    12.   ENTRY (name);                                                               \  
    13.     DO_CALL (syscall_name, args);                                             \  
    14.     cmn r0, $4096;  
    15.   
    16. 猜測是__ASSEMBLER__宏未打開,以至於未能找到PSEUD0函數的聲明,則將  
    17.   
    18. #define PSEUDO(name, syscall_name, args)                                      \  
    19.   .text;                                                                      \  
    20.   ENTRY (name);                                                               \  
    21.     DO_CALL (syscall_name, args);                                             \  
    22.     cmn r0, $4096;  
    23.   
    24. 這段代碼 添加至 ../sysdeps/unix/syscall-template.S 中  
     
    1. LS_DTV_UNALLOCATED  undeclared (first use in this function)  
    2. vi ../nptl/allocatestack.c  
    3. vi ../elf/dl-tls.c   
    4. 這個錯誤會出現在編譯以上兩個文件的時候,這個宏的定義我grep了整個glibc的所有代碼,沒找到ARM相關的聲明及定義,按照其他指令集的定義猜測著修改如下  
    5. 在以上兩個C文件中增加相應的定義  
    6.   
    7. #define TLS_DTV_UNALLOCATED      ((void *) -1l)  
     
    1. E_TOWARDZERO undeclared (first use in this function)  
    2. E_INEXACT undeclared (first use in this function)  
    3. 以上兩個錯誤會出現在以下兩個文件的的編譯過程中  
    4. vi ../sysdeps/ieee754/dbl-64/s_fma.c  
    5. vi ../sysdeps/ieee754/dbl-64/s_fmaf.c  
    6. 參考 ports/sysdeps/arm/eabi/bits/fenv.h中的定義  
    7. 在兩個文件中添加  
    8. #define FE_TOWARDZERO 0xc00000  
    9. #define FE_INEXACT 16  
     
    1. mawk: scripts/gen-sorted.awk: line 19: regular expression compile failed   
    2. 所以要 aptitude install gawk 所以也順帶著 aptitude remove mawk  
     
    1. configure: error: forced unwind support is required   
    2. configure 中增加配置參數 libc_cv_forced_unwind=yes   
     
    1. error: the compiler must support C cleanup handlin  
    2. configure 中增加配置參數libc_cv_c_cleanup=yes   
     
    1. --enable-add-ons 為 C 庫 增加 thread 支持,目前默認使用的是 nptl 所以這裡沒有去下載 glibc-threads 相關的代碼  
     
    1. --with-headers 指定內核頭文件所在的目錄  
  • Copyright © Linux教程網 All Rights Reserved