keropoの備忘録

しらべたことをメモるブログ

ARMクロスコンパイラ作成

ARM上での組込みLinuxコンパイルする為のARMクロスコンパイラの構築方法メモ

 (eglibcのコンパイル時にソース修正が必要だったが、とりあえず構築できた)

(2013.4.17 追記)eglibcとkernelに修正が必要なのは、kernelのバージョンが古すぎることが原因と分かったのでkernel-3.2.35を使用するように修正。

使用したソース

前準備

とりあえず、コンパイルに必要そうなツール類をyumでインストール。

  • yum -y install zlib-devel
  • yum -y install glib2-devel
  • yum -y install SDL-devel
  • yum -y install texinfo
  • yum -y install libtool
  • yum -y install autoconf
  • yum -y install ncurses
  • yum -y install ncurses-devel

以下の環境変数を設定

 $export TARGET=arm-unknown-linux-gnueabi

 $export CROSS=~/toolchain

 $export ROOTDIR=$CROSS/$TARGET

 binutilsコンパイル

   binutilsをダウンロードして、解凍したフォルダ内にビルド用のフォルダ(buildフォルダ)を生成してビルドする。binutilsコンパイルのときだけに限らず、gccやeglibcなどのコンパイルの時も解凍したフォルダ内にbuildフォルダを作成し、そこでコンパイル作業を行う。

  $cd   binutils-2.23.2/build

  $../configure --target=$TARGET --prefix=$CROSS --with-sysroot=$ROOTDIR

  $make

  $make install

 gmpのコンパイル

 $cd gmp-5.1.1/build

 $../configure --prefix=$CROSS

 $make

 $make install

mpfrのコンパイル

$cd mpfr-3.1.2/build 

$../configure --prefix=$CROSS --with-gmp=$CROSS

 $make

 $make install

mpcコンパイル

 $cd mpc-0.8.2/build

 $../configure --prefix=$CROSS --with-gmp=$CROSS --with-mpfr=$CROSS

 $make

 $make install

 

gccコンパイル(1回目)

 gccコンパイルする前に、gmp,mpfr, mpcコンパイルによって作成されたsoファイルがあると、gccコンパイル時のリンク処理で失敗するので削除

 $rm -f $CROSS/lib/*.so

soファイルを削除し終わったら、コンパイル実行

  $cd gcc-4.5.3/build

  $../configure \

        --target=$TARGET \

        --prefix=$CROSS \

        --without-headers \

        --without-ppl \

        --with-newlib \

        --disable-shared \

        --disable-threads \

        --disable-libssp \

        --disable-libgomp \

        --disable-libmudflap \

        --disable-nls \

        --with-gmp=$CROSS \

        --with-mpfr=$CROSS \

        --with-mpc=$CROSS \

        --enable-languages=c

  $make

  $make install

カーネルヘッダーの作成

  $cd  linux-2.6.19

  $cd linux-3.2.35

  $make mrproper

  $make headers_install ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- INSTALL_HDR_PATH=$ROOTDIR/usr

 上記を実行した際、「getline」の定義が重複しているエラーになる場合は以下のソースのgetlineをget_lineに置換してやる。

  scripts/unifdef.c

eglibcのコンパイル(ヘッダー生成のみ)

  $cd eglibc-2_13

  $cp -r ports libc

  $cd build

  $export PATH=$PATH:$CROSS/bin

  $BUILD_CC=gcc \

    CC=$TARGET-gcc \

    CXX=$TARGET-g++ \

    AR=$TARGET-ar \

    RANLIB=$TARGET-ranlib \

    ../libc/configure \

        --prefix=/usr \

        --with-headers=$ROOTDIR/usr/include \

        --host=$TARGET \

        --disable-profile \

        --without-gd \

        --without-cvs \

        --enable-add-ons

  $make install-headers install_root=$ROOTDIR install-bootstrap-headers=yes

下記コマンドで作成されるcrt1.o crti.o crtn.oを$ROOTDIR/usr/libにコピーする。

  $make csu/subdir_lib

  $mkdir -p $ROOTDIR/usr/lib

  $cp csu/crt1.o csu/crti.o csu/crtn.o $ROOTDIR/usr/lib

最後にlibc.soを生成し、 $ROOTDIR/usr/libに出力

 $ ${TARGET}-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $ROOTDIR/usr/lib/libc.so

 gccコンパイル(2回目)

  $cd gcc-4.5.3/build

  $ rm -rf *

  $../configure \

        --target=$TARGET \

        --prefix=$CROSS \

        --with-sysroot=$ROOTDIR \

        --disable-libssp --disable-libgomp --disable-libmudflap \

        --with-gmp=$CROSS \

        --with-mpfr=$CROSS \

        --with-mpc=$CROSS \

        --enable-languages=c

  $make

  $make install

eglibcのコンパイル

インストール時に必要になるので、以下のツールをインストールする。

  #yum -y install gperf

また、単純にビルドすると、コンパイルエラーが発生するので、以下の部分を修正する。

  •  ./libc/sysdeps/unix/sysv/linux/ifaddrs.c

   #include <linux/if_addr.h>を追加

  •  ./libc/sysdeps/unix/sysv/linux/check_pf.c

   #include <linux/if_addr.h>を追加

  下記、3ファイルに、define定義を追加

  •      ./libc/sysdeps/unix/sysv/linux/if_index.c
  •      ./libc/sysdeps/unix/sysv/linux/ifaddrs.c
  •      ./libc/sysdeps/unix/sysv/linux/check_pf.c
   #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
     #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
     #define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
     #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))


  $cd  eglibc-2_13/build

  $rm -rf *

  $BUILD_CC=gcc \

    CC=$TARGET-gcc \

    CXX=$TARGET-g++ \

    AR=$TARGET-ar \

    RANLIB=$TARGET-ranlib \

    ../libc/configure \

        --prefix=/usr \

        --with-headers=$ROOTDIR/usr/include \

        --host=$TARGET \

        --disable-profile \

        --without-gd \

        --without-cvs \

        --enable-add-ons

  $make

 $make install install_root=$ROOTDIR

gccコンパイル(完成)

  $cd gcc-4.5.3/build

  $ rm -rf *

  $../configure \

        --target=$TARGET \

        --prefix=$CROSS \

        --with-sysroot=$ROOTDIR \

        --disable-libssp --disable-libgomp --disable-libmudflap \

        --with-gmp=$CROSS \

        --with-mpfr=$CROSS \

        --with-mpc=$CROSS \

        --enable-languages=c,c++

  $make

  $make install

以上で、ARMクロスコンパイラの完成!