1. 程式人生 > >建立嵌入式 Linux 開發環境

建立嵌入式 Linux 開發環境

基於 linux-3.0.3、binutils-2.21.1、glibc-2.13、glibc-ports-2.13、gcc-4.6.1、gmp-5.0.2、mpfr-3.0.1、mpc-0.9 構建。

轉載請註明出處:http://hi.baidu.com/busybox/

1.建立宿主機編譯環境
# apt-get install build-essential libncurses5-dev

建立setbuildenv.sh指令碼
setbuildenv.sh
+--------------setbuildenv.sh-----------------+
#!/bin/sh
export PRJROOT=/home/mini/arm
export TARGET=arm-linux
export PREFIX=${PRJROOT}/tools
export TARGET_PREFIX=${PREFIX}/${TARGET}
export PATH=${PREFIX}/bin:${PATH}
+--------------------------------------------------+
$ source setbuildenv.sh
$ cd
$ mkdir arm
$ cd ${PRJROOT}
$ mkdir build-tools tools kernel
$ cd ${PRJROOT}/build-tools
$ mkdir build-binutils build-boot-gcc build-gcc build-glibc  build-glibc-headers
$ cd ${PRJROOT}/tools
$ mkdir arm-linux

2.安裝核心標頭檔案


$ cd ${PRJROOT}/kernel
$ wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.0.3.tar.gz
$ tar xvf linux-3.0.3.tar.gz
$ cd linux-3.0.3
$ cp arch/arm/configs/s3c2410_defconfig ./.config
$ make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-
$ mkdir -p ${TARGET_PREFIX}/include
$ cp -r include/linux/ ${TARGET_PREFIX}/include
$ cp -r include/asm-generic/ ${TARGET_PREFIX}/include
$ cp -r arch/arm/include/asm/ ${TARGET_PREFIX}/include
################################################################################
$ make ARCH=arm CROSS_COMPILE=arm-linux-
此步的目的是生成 include/linux/version.h 檔案,而不是真正的編譯,忽略所有錯誤。
################################################################################

3.編譯 binutils

$ cd ${PRJROOT}/build-tools
$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.21.1.tar.gz
$ tar xvf binutils-2.21.1.tar.gz
$ cd build-binutils
$ ../binutils-2.21.1/configure --target=${TARGET} --prefix=${PREFIX}
$ make
$ make install

4.安裝 glibc 標頭檔案
$ cd ${PRJROOT}/build-tools
$ wget http://ftp.gnu.org/pub/gnu/glibc/glibc-2.13.tar.gz
$ wget http://ftp.gnu.org/pub/gnu/glibc/glibc-ports-2.13.tar.gz
$ tar xvf glibc-2.13.tar.gz
$ tar xvf glibc-ports-2.13.tar.gz
$ mv glibc-ports-2.13 ./glibc-2.13/ports
$ cd build-glibc-headers
$ ../glibc-2.13/configure --host=${TARGET} --prefix="/usr" --enable-add-ons --with-headers=${TARGET_PREFIX}/include
$ make cross-compiling=yes install_root=${TARGET_PREFIX} prefix="" install-headers
################################################################################
錯誤:

+--------------------------------------------------+
configure: error: GNU libc requires kernel header files from Linux 2.0.10 or later to be installed before configuring.
+--------------------------------------------------+
解決方法:
在安裝核心標頭檔案的過程中,在設定好核心配置以後,沒有使用相應的命令生成 include/linux/version.h 檔案。
$ cd ${PRJROOT}/kernel/linux-3.0.3/
$ make ARCH=arm CROSS_COMPILE=arm-linux-
$ cp -r include/linux/ ${TARGET_PREFIX}/include
$ cp -r include/asm-generic/ ${TARGET_PREFIX}/include
################################################################################
錯誤:
+--------------------------------------------------+
/usr/bin/install: cannot stat `/home/mini/arm/build-tools/build-glibc-headers/gnu/lib-names.h':  No such file or directory
+--------------------------------------------------+
解決方法:
方法一:
$ su -
# aptitude purge mawk
# apt-get install gawk
# exit
$ cd ${PRJROOT}/build-tools/build-glibc-headers
$ ../glibc-2.13/configure --host=${TARGET} --prefix="/usr" --enable-add-ons --with-headers=${TARGET_PREFIX}/include
$ make cross-compiling=yes install_root=${TARGET_PREFIX} prefix="" install-headers
方法二:
$ su -
# apt-get install gawk
# exit
$ cd ${PRJROOT}/build-tools/build-glibc-headers
$ vi config.make
找到如下行:
AWK = mawk
將其修改為:
AWK = gawk
################################################################################

5.安裝 gcc 引導編譯器
$ cd ${PRJROOT}/build-tools
$ wget http://ftp.gnu.org/pub/gnu/gcc/gcc-4.6.1/gcc-4.6.1.tar.gz
$ wget http://ftp.gnu.org/gnu/gmp/gmp-5.0.2.tar.gz
$ wget http://www.mpfr.org/mpfr-current/mpfr-3.0.1.tar.gz
$ wget http://www.multiprecision.org/mpc/download/mpc-0.9.tar.gz
$ tar xvf gcc-4.6.1.tar.gz
$ tar xvf gmp-5.0.2.tar.gz
$ tar xvf mpfr-3.0.1.tar.gz
$ tar xvf mpc-0.9.tar.gz
$ mv gmp-5.0.2 ./gcc-4.6.1/gmp
$ mv mpfr-3.0.1 ./gcc-4.6.1/mpfr
$ mv mpc-0.9 ./gcc-4.6.1/mpc
$ cd build-boot-gcc
$ mkdir -p ${TARGET_PREFIX}/include/gnu
$ touch ${TARGET_PREFIX}/include/gnu/stubs.h
$ ../gcc-4.6.1/configure --target=${TARGET} --prefix=${PREFIX} --disable-shared --without-headers --with-newlib --enable-languages=c
$ make all-gcc all-target-libgcc
$ make install-gcc install-target-libgcc
################################################################################
錯誤:
+--------------------------------------------------+
../../../gcc-4.6.1/libgcc/../gcc/gthr-posix.h:41:21: fatal error: pthread.h: No such file or directory
+--------------------------------------------------+
解決方法:
如果沒有安裝 glibc 標頭檔案,就開始安裝 gcc 引導編譯器,需要在 configure 後面加上 --disable-threads 選項。
$ cd ${PRJROOT}/build-tools/build-boot-gcc
$ ../gcc-4.6.1/configure --target=${TARGET} --prefix=${PREFIX} --disable-shared --disable-threads --without-headers --with-newlib --enable-languages=c
################################################################################
錯誤:
+--------------------------------------------------+
/home/mini/arm/tools/arm-linux/include/features.h:381:23: fatal error: gnu/stubs.h: No such file or directory
+--------------------------------------------------+
解決方法:
$ mkdir -p ${TARGET_PREFIX}/include/gnu
$ touch ${TARGET_PREFIX}/include/gnu/stubs.h
################################################################################

6.安裝 glibc
$ cd ${PRJROOT}/build-tools
$ cd build-glibc
$ CC=arm-linux-gcc ../glibc-2.13/configure --host=${TARGET} --prefix="/usr" --enable-add-ons --with-headers=${TARGET_PREFIX}/include libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes
$ ln -s ${PREFIX}/lib/gcc/arm-linux/4.6.1/libgcc.a ${PREFIX}/lib/gcc/arm-linux/4.6.1/libgcc_eh.a
$ make
$ make install_root=${TARGET_PREFIX} prefix="" install
################################################################################
錯誤:
+--------------------------------------------------+
configure: error: forced unwind support is required
+--------------------------------------------------+
解決方法:
在 configure 後面加上 libc_cv_forced_unwind=yes 選項。
$ cd ${PRJROOT}/build-tools/build-glibc
$ CC=arm-linux-gcc ../glibc-2.13/configure --host=${TARGET} --prefix="/usr" --enable-add-ons --with-headers=${TARGET_PREFIX}/include libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes
################################################################################
錯誤:
+--------------------------------------------------+
configure: error: the compiler must support C cleanup handling
+--------------------------------------------------+
解決方法:
在 configure 後面加上 libc_cv_c_cleanup=yes 選項。
$ cd ${PRJROOT}/build-tools/build-glibc
$ CC=arm-linux-gcc ../glibc-2.13/configure --host=${TARGET} --prefix="/usr" --enable-add-ons --with-headers=${TARGET_PREFIX}/include libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes
################################################################################
錯誤:
+--------------------------------------------------+
../sysdeps/unix/sysv/linux/sys/syscall.h:25:24: fatal error: asm/unistd.h: No such file or directory
+--------------------------------------------------+
解決方法:
$ cd ${PRJROOT}/kernel/linux-3.0.3
$ cp -r arch/arm/include/asm/ ${TARGET_PREFIX}/include
################################################################################
錯誤:
+--------------------------------------------------+
../ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S:30: Error: previous CFI entry not closed (missing .cfi_endproc)
/tmp/cc9oYU9g.s: Error: open CFI at the end of file; missing .cfi_endproc directive
+--------------------------------------------------+
解決方法:
$ cd ${PRJROOT}/build-tools/build-glibc
$ vi ../glibc-2.13/ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S
找到如下行:
ENTRY(__default_sa_restorer)
在其下新增:
END(__default_sa_restorer)
找到如下行:
ENTRY(__default_rt_sa_restorer)
在其下新增:
END(__default_rt_sa_restorer)
################################################################################
錯誤:
+--------------------------------------------------+
/bin/sh: cannot create /home/mini/arm/build-tools/build-glibc/posix/config-name.h.new: Directory nonexistent
+--------------------------------------------------+
解決方法:
$ cd ${PRJROOT}/build-tools/build-glibc
$ mkdir posix
################################################################################
錯誤:
+--------------------------------------------------+
../sysdeps/unix/syscall-template.S:82: Error: CFI instruction used without previous .cfi_startproc
+--------------------------------------------------+
解決方法:
$ cd ${PRJROOT}/build-tools/build-glibc
$ vi ../glibc-2.13/sysdeps/unix/syscall-template.S
找到如下行:
#define T_PSEUDO(SYMBOL, NAME, N)                PSEUDO (SYMBOL, NAME, N)
在其上新增:
#define PSEUDO(name, syscall_name, args)                                      \
  .text;                                                                                                    \
  ENTRY (name);                                                                                  \
    DO_CALL (syscall_name, args);                                                      \
    cmn r0, $4096;
方法來源:
../glibc-2.13/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
################################################################################
錯誤:
+--------------------------------------------------+
/home/mini/arm/tools/lib/gcc/arm-linux/4.6.1/../../../../arm-linux/bin/ld: cannot find -lgcc_eh
+--------------------------------------------------+
解決方法:
$ ln -s ${PREFIX}/lib/gcc/arm-linux/4.6.1/libgcc.a ${PREFIX}/lib/gcc/arm-linux/4.6.1/libgcc_eh.a
################################################################################
錯誤:
+--------------------------------------------------+
../sysdeps/ieee754/dbl-64/s_fma.c:152:15: error: 'FE_TOWARDZERO' undeclared (first use in this function)
../sysdeps/ieee754/dbl-64/s_fma.c:152:15: note: each undeclared identifier is reported only once for each function it appears in
../sysdeps/ieee754/dbl-64/s_fma.c:159:36: error: 'FE_INEXACT' undeclared (first use in the function)
+--------------------------------------------------+
解決方法:
$ cd ${PRJROOT}/build-tools/build-glibc
$ vi ../glibc-2.13/sysdeps/ieee754/dbl-64/s_fma.c
找到如下行:
#include <ieee754.h>
在其下新增:
#define FE_TOWARDZERO 0xc00000
#define FE_INEXACT 16
方法來源:
../glibc-2.13/ports/sysdeps/arm/eabi/bits/fenv.h
################################################################################
錯誤:
+--------------------------------------------------+
../sysdeps/ieee754/dbl-64/s_fmaf.c:39:15: error: 'FE_TOWARDZERO' undeclared (first use in this function)
../sysdeps/ieee754/dbl-64/s_fmaf.c:39:15: note: each undeclared identifier is reported only once for each function it appears in
../sysdeps/ieee754/dbl-64/s_fmaf.c:43:39: error: 'FE_INEXACT' undeclared (first use in the function)
+--------------------------------------------------+
解決方法:
$ cd ${PRJROOT}/build-tools/build-glibc
$ vi ../glibc-2.13/sysdeps/ieee754/dbl-64/s_fmaf.c
找到如下行:
#include <ieee754.h>
在其下新增:
#define FE_TOWARDZERO 0xc00000
#define FE_INEXACT 16
方法來源:
../glibc-2.13/ports/sysdeps/arm/eabi/bits/fenv.h
################################################################################

7.安裝 gcc 編譯器
cd ${PRJROOT}/build-tools/build-gcc
../gcc-4.6.1/configure --target=${TARGET} --prefix=${PREFIX} --enable-shared --enable-languages=c,c++
make all
make install
################################################################################
錯誤:
+--------------------------------------------------+
/lib/libc.so.6: file not recognized: File format not recognized
+--------------------------------------------------+
解決方法:
$ cd ${TARGET_PREFIX}/lib
$ cp ./libc.so ./libc.so.bak
修改 libc.so 檔案,除掉它列舉的連結庫的絕對路徑。基本上,將需要除掉所有連結庫檔名中的 /lib/ 字樣。
$ vi libc.so
找到如下行:
GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) )
將其修改為:
GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.2 ) )
################################################################################
錯誤:
+--------------------------------------------------+
configure: error: Pthreads are required to build libgomp
+--------------------------------------------------+
解決方法:
$ cd ${TARGET_PREFIX}/lib
$ cp ./libpthread.so ./libpthread.so.bak
修改 libpthread.so 檔案,除掉它列舉的連結庫的絕對路徑。基本上,將需要除掉所有連結庫檔名中的 /lib/ 字樣。
$ vi libpthread.so
找到如下行:
GROUP ( /lib/libpthread.so.0 /lib/libpthread_nonshared.a )
將其修改為:
GROUP ( libpthread.so.0 libpthread_nonshared.a )
################################################################################