keropoの備忘録

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

WebKit on DirectFB をARM cross compile

目的

arm-qemu&DirectFB上で動くWebブラウザを構築しようと、WebKitをクロスコンパイルした際のめも。
ネットでいろいろ調べたけど、DirectFB向けのWebKitコンパイル情報がなかなかない。あまり需要がないのかなぁ~?
それにしてもWebKitコンパイルするまでが非常に大変。全て終わった時の達成感は半端なかった。
他にもっと簡単にできる方法があったら、教えてほしい・・・。

使用パッケージ

WebKit on DirectFBのARMクロスコンパイルのため、今回は以下のパッケージをダウンロード。

パッケージ URL
atk-1.26.0 http://ftp.gnome.org/pub/gnome/sources/atk/1.26/atk-1.26.0.tar.gz
cairo-1.8.6 http://cairographics.org/releases/cairo-1.8.6.tar.gz
DirectFB-1.4.1 http://directfb.org/downloads/Core/DirectFB-1.4/DirectFB-1.4.1.tar.gz
expat-2.1.0 http://downloads.sourceforge.net/expat/expat-2.1.0.tar.gz
fontconfig-2.5.0 http://www.freedesktop.org/software/fontconfig/release/fontconfig-2.5.0.tar.gz
freetype-2.4.11 http://downloads.sourceforge.net/freetype/freetype-2.4.11.tar.bz2
giflib-4.1.6 http://sourceforge.net/projects/giflib/files/giflib-4.x/giflib-4.1.6/giflib-4.1.6.tar.bz2
glib-2.24.0 http://ftp.gnome.org/pub/gnome/sources/glib/2.24/glib-2.24.0.tar.bz2
gperf-3.0.4 http://ftp.gnu.org/pub/gnu/gperf/gperf-3.0.4.tar.gz
gtk+-2.16.2 http://ftp.gnome.org/pub/gnome/sources/gtk+/2.16/gtk+-2.16.2.tar.bz2
jpegsrc.v9 http://www.ijg.org/files/jpegsrc.v9.tar.gz
libpng-1.2.50 http://download.sourceforge.net/libpng/libpng-1.2.50.tar.gz
libsoup-2.26.0 http://ftp.gnome.org/pub/gnome/sources/libsoup/2.26/libsoup-2.26.0.tar.bz2
libtool-2.2.2 http://ftp.gnu.org/gnu/libtool/libtool-2.2.2.tar.bz2
libxml2-2.7.8 http://xmlsoft.org/sources/libxml2-2.7.8.tar.gz
libxslt-1.1.24 http://xmlsoft.org/sources/libxslt-1.1.24.tar.gz
pango-1.24.0 http://ftp.gnome.org/pub/gnome/sources/pango/1.24/pango-1.24.0.tar.bz2
pixman-0.14.0 http://cairographics.org/releases/pixman-0.14.0.tar.gz
pkg-config-0.23 http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz
sqlite-autoconf-3080002 http://www.sqlite.org/2013/sqlite-autoconf-3080002.tar.gz
icu4c-4_4_2 http://download.icu-project.org/files/icu4c/4.4.2/icu4c-4_4_2-src.tgz
tiff-3.8.2 http://download.osgeo.org/libtiff/tiff-3.8.2.tar.gz
WebKit-r35620 http://builds.nightly.webkit.org/files/trunk/src/WebKit-r35620.tar.bz2

事前にインストールしたパッケージ

  yum -y install gettext
  yum -y install gettext-libs

環境変数設定

  export CTARGET=arm-unknown-linux-gnueabi
  export CROSS=${クロスコンパイラのルートパス}
  export ROOTFS_DIR=$CROSS/$CTARGET/sysroot
  export PATH=$PATH:$CROSS/bin
  export PKG_CONFIG_PATH=${ROOTFS_DIR}/usr/lib/pkgconfig

glib

  $tar jxvf glib-2.24.0.tar.bz2 
  $cd glib-2.24.0
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  glib_cv_stack_grows=no \
  glib_cv_uscore=no \
  ac_cv_func_posix_getpwuid_r=no \
  ac_cv_func_posix_getgrgid_r=no \
  ./configure \
  --host=$TARGET \
  --prefix=$ROOTFS_DIR/usr \
  --disable-static \
  --disable-selinux \
  --disable-dependency-tracking
  $make
  $make install

atk

  $tar xvfz atk-1.26.0.tar.gz
  $cd atk-1.26.0
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
  --host=$CTARGET \
  --prefix=$ROOTFS_DIR/usr \
  --disable-static \
  --disable-glibtest
  $make
  $make install

jpegsrc.v9

  $tar xvfz jpegsrc.v9.tar.gz
  $cd jpeg-9
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
   --host=$CTARGET \
   --enable-shared \
   --disable-static \
   --prefix=${ROOTFS_DIR}/usr
  $make
  $make install

libpng

  $tar xvfz libpng-1.2.50.tar.gz
  $cd libpng-1.2.50
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --host=$CTARGET --disable-static --prefix=${ROOTFS_DIR}/usr
  $make 
  $make install

freetype

  $tar jxvf freetype-2.4.11.tar.bz2
  $cd freetype-2.4.11
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --host=$CTARGET --prefix=${ROOTFS_DIR}/usr
  $make
  $make instal

libxml2

  $tar xvfz libxml2-2.7.8.tar.gz
  $cd libxml2-2.7.8
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --host=$CTARGET --prefix=${ROOTFS_DIR}/usr --disable-rebuild-docs --without-debug --disable-static
  $make
  $make install

fontconfig

  $tar xvfz fontconfig-2.5.0.tar.gz
  $cd fontconfig-2.5.0
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" \
  CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --enable-libxml2 \
  --with-freetype-config=${ROOTFS_DIR}/usr/bin/freetype-config \
  --with-arch=arm
  $make
  $make install

tiff

  $tar xvfz tiff-3.8.2.tar.gz
  $cd tiff-3.8.2
  $CC=$CTARGET-gcc CXX=$CTARGET-g++ LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --host=$CTARGET --prefix=${ROOTFS_DIR}/usr --without-x --enable-cxx
  • ソースを一時修正
  $vi $ROOTFS_DIR/usr/include/jmorecfg.h
  typedef enum { FALSE = 0 , TRUE = 1 } boolean;
    ↓
  typedef enum { false= 0 , true= 1 } boolean;
  $make
  $make install

giflib

  $tar jxvf giflib-4.1.6.tar.bz2
  $cd giflib-4.1.6
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --host=$CTARGET --prefix=${ROOTFS_DIR}/usr --without-x
  $make
  $make install

pkg-config

  $tar xvfz pkg-config-0.23.tar.gz
  $cd pkg-config-0.23
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --host=$CTARGET --prefix=${ROOTFS_DIR}/usr --with-installed-glib
  $make
  $make install

zlib

  $tar jxvf zlib-1.2.7.tar.bz2
  $cd zlib-1.2.7
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --shared --prefix=${ROOTFS_DIR}/usr
  $make 
  $make install

DirectFB

  $tar xvfz DirectFB-1.4.1.tar.gz
  $cd DirectFB-1.4.1
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure --host=$CTARGET --prefix=${ROOTFS_DIR}/usr \
  --disable-static --disable-osx --enable-shared --disable-vnc\
  --disable-sdl --disable-mmx --disable-sse \
  --disable-x11 --enable-sysfs \
  --enable-fbdev --enable-jpeg --enable-zlib \
  --enable-png --enable-gif --enable-freetype \
  --disable-libtool-lock \
  --with-inputdrivers=linuxinput,keyboard,ps2mouse
  • ソースを修正
  $vi $ROOTFS_DIR/usr/include/jmorecfg.h
  typedef enum { false= 0 , true= 1 } boolean;
    ↓
  typedef enum { FALSE = 0 , TRUE = 1 } boolean;

  $vi gfxdrivers/davinci/davinci_c64x.c
  →「#include 」を追加
  $make
  $make install

pixman

  $tar xvfz pixman-0.14.0.tar.gz
  $cd pixman-0.14.0
  $CC=$CTARGET-gcc LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  png_CFLAGS="-I$ROOTFS_DIR/usr/include/libpng12" png_LIBS="-lpng"
  ./configure --host=$CTARGET --prefix=${ROOTFS_DIR}/usr \
  --disable-simd \
  --disable-vmx --disable-static \
  --disable-mmx --disable-sse2 \
  --disable-gtk
  $make
  $make install

cairo

  $tar xvfz cairo-1.8.6.tar.gz
  $cd cairo-1.8.6
  $CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  pixman_CFLAGS="-I$ROOTFS_DIR/usr/include/pixman-1" pixman_LIBS="-lpixman-1" \
  png_REQUIRES=libpng12 \
  png_CFLAGS="-I$ROOTFS_DIR/usr/include/libpng12" png_LIBS="-lpng" \
  directfb_CFLAGS="-I$ROOTFS_DIR/usr/include/directfb" directfb_LIBS="-ldirectfb" \
  FREETYPE_CFLAGS="-I$ROOTFS_DIR/usr/include/freetype2" FREETYPE_LIBS="-lfreetype" \
  FONTCONFIG_CFLAGS="-I$ROOTFS_DIR/usr/include/fontconfig" FONTCONFIG_LIBS="-lfontconfig" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --disable-xlib \
  --disable-xlib-xrender \
  --disable-static \
  --disable-some-floating-point \
  --enable-test-surfaces \
  --disable-quartz \
  --disable-quartz-font \
  --disable-quartz-image \
  --disable-win32 \
  --disable-win32-font \
  --disable-os2 \
  --disable-beos \
  --enable-png \
  --enable-directfb \
  --enable-ft \
  --without-x \
  --enable-svg
  $make
  $make install

pango

  $tar jxvf pango-1.24.0.tar.bz2
  $cd pango-1.24.0
  $CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  LIBS="-lgobject-2.0 -lgmodule-2.0 -lgio-2.0" \
  FONTCONFIG_CFLAGS="-I$ROOTFS_DIR/usr/include/fontconfig" FONTCONFIG_LIBS="-lfontconfig" \
  FREETYPE_CFLAGS="-I$ROOTFS_DIR/usr/include/freetype2" FREETYPE_LIBS="-lfreetype" \
  CAIRO_CFLAGS="-I$ROOTFS_DIR/usr/include/cairo" CAIRO_LIBS="-lcairo" \
  GLIB_CFLAGS="-I$ROOTFS_DIR/usr/include/glib-2.0" GLIB_LIBS="-lglib-2.0" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --without-x
  $make
  $make install

gtk+

コンパイル時にgdk-fixbuf-csourceというコマンドがないと怒られるのでインストールする。

  #yum -y install gtk2-devel

gtk+コンパイル

  $tar jxvf gtk+-2.16.2.tar.bz2
  $cd gtk+-2.16.2
  $gio_can_sniff=no \
  CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" \
  CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --with-gdktarget=directfb \
  --without-xinput \
  --with-libpng \
  --with-libjpeg \
  --with-libtiff \
  --without-libjasper \
  --without-x \
  --enable-debug=yes
  $make
  $make install

libxslt

  $tar xvfz libxslt-1.1.24.tar.gz
  $cd libxslt-1.1.24
  $CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --disable-static
  xml2-configというコマンドが使用され、configureで失敗するので、以下のパッケージを追加
     #yum -y install libxml2 libxml2-devel
  $make
    失敗する。「xmlDebugDumpNode」や「xmlXPathDebugDumpObject」がないと言われる。
  そもそもlibxml2はwithout-debugオプションを付けてコンパイルしているので、debug系の関数
  がないし、includeにも「LIBXML_DEBUG_ENABLED」スイッチがOFFになっているのに、コンパイル
  時はホスト側の/usr/includeの方が参照され、スイッチがONにされる見たい。
  いろいろオプションを試してみたが、なぜか/usr/includeが参照される。
  強制的にdebug関数を参照している箇所をコメントアウトして対応。
   [LIBXML_DEBUG_ENABLED]を検索し、該当箇所を全てコメントアウト
  $make
  $make install

gperf

  $tar xvfz gperf-3.0.4.tar.tar
  $cd gperf-3.0.4
  $ CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" \
  CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --disable-static
  $make
  $make install

icu4c

  $tar xvfz icu4c-4_4_2-src.gz
  ・一部ソースを修正する。
  ---------------------------------------------------------------
  icu/source/tools/toolutil/pkg_genc.c
    } assemblyHeader[] = {
    {"gcc",
    ".globl %s\n"
  - "\t.section .note.GNU-stack,\"\",@progbits\n"
  + "\t.section .note.GNU-stack,\"\",%%progbits\n"
    "\t.section .rodata\n"
    "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */
  - "\t.type %s,@object\n"
  + "\t.type %s,%%object\n"
    "%s:\n\n",
  
    ".long ","",HEX_0X
  -------------------------------------------------------------------
  次にhost用とtarget用とビルドフォルダを作成する。
  $mkdir -p icu_build1 icu_build2
  ・ホスト側のコンパイル
  $cd icu_build1
   $../icu/source/runConfigureICU Linux
   $make

  ・ターゲット側のコンパイル
   $cd icu_build2
   $AR=$CTARGET-ar \
    CC=$CTARGET-gcc \
    CPP=$CTARGET-cpp \
    CXX=$CTARGET-g++ \
    RUNLIB=$CTARGET-runlib \
    LD=$CTARGET-ld \
    LDFLAGS="-L$ROOTFS_DIR/usr/lib" \
    CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
    ../icu/source/configure \
    --host=$CTARGET \
    --prefix=${ROOTFS_DIR}/usr \
    --disable-static \
    --with-cross-build=/home/xappuser/opensource/webkit/icu_build1
   $make
   $make install

libsoup

  $tar jxvf libsoup-2.26.0.tar.bz2
  $cd libsoup-2.26.0
  $CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" \
  CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --without-gnome \
  --disable-static \
  --disable-glibtest
  $make
  $make install

sqlite-autoconf

  $tar xvfz sqlite-autoconf-3080002.tar.gz
  $cd sqlite-autoconf-3080002
  $CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" \
  CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  ./configure \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr
  $make
  $make install

WebKit

そして最後のWebKit
でもこれも一筋縄にはいかなかった・・・。

  • bisonのダウングレード

bison2.4だと問題が発生する為、2.3にダウングレードする。

  #yum remove bison
  #wget http://ftp.gnu.org/gnu/bison/bison-2.3.tar.bz2
  #tar jxvf bison-2.3.tar.bz2
  #./configure
  #make; make install
  #ln -s /usr/local/bin/bison /usr/bin/bison
  $tar jxvf WebKit-r35620.tar.bz2
  $cd WebKit-r35620
  $CC=$CTARGET-gcc \
  LDFLAGS="-L$ROOTFS_DIR/usr/lib" \
  CPPFLAGS="-I$ROOTFS_DIR/usr/include" \
  UNICODE_CFLAGS="-I$ROOTFS_DIR/usr/includ" \
  UNICODE_LIBS="-licudata -licui18n -licuio -licule -liculx -licutest -licutu -licuuc" \
  ./autogen.sh \
  --host=$CTARGET \
  --prefix=${ROOTFS_DIR}/usr \
  --with-target=directfb \
  --with-http-backend=soup \
  --with-font-backend=pango \
  --disable-video
  $make

いろいろエラーが発生し、その都度修正

  • configureの修正

UNICODE_CFLAGSが入力された時はicu-configチェックしないようにする。

  $vi configure
   if test "$unicode_backend" = "icu"; then
     if test "$os_darwin" = "yes"; then
      UNICODE_CFLAGS="-I\$(srcdir)/JavaScriptCore/icu -I\$(srcdir)/WebCore/icu"
      UNICODE_LIBS="-licucore"
    elif test "$os_win32" = "yes"; then
      UNICODE_CFLAGS=""
      UNICODE_LIBS="-licuin -licuuc"
    else
  + if test "x$UNICODE_CFLAGS" = "x" -o "x$UNICODE_LIBS" = "x"; then
      :
      :
      :
  + fi
    fi
  $vi WebCore/platform/text/TextBreakIterator.h
  - class TextBreakIterator; 
  + typedef struct UBreakIterator TextBreakIterator;
   $vi ${ROOTFS_DIR}/usr/include/jmorecfg.h
   //typedef enum { FALSE = 0, TRUE = 1 } boolean;
      ↓
    typedef unsigned char boolean;
  $vi WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
  →include文を追加
  #include <stdio.h>
  #include <stdlib.h>
 コンパイルが終わったら、インストール
 $make install

これでWebKitコンパイルが完了!
WebKit-r35620/Programs/.lib/GtkLauncharというプログラムが作成されていて、こいつをARM環境で叩けばブラウザが立ち上がるっぽい。
実動作はまた今度。

DirectFBでARM環境をグラフィカル表示~その②

サンプルプログラム

DirectFBでARM環境をグラフィカル表示~その① - keropoの備忘録の続き。
ARMクロスコンパイルしたDirectFBのライブラリ群が完成したので、それを利用してqemuで動かす為のサンプルプログラムを作成する。
作成したのは赤・緑・青のタスキ表示するプログラム(main.c)。

#include <stdio.h>
#include <unistd.h>
#include <directfb.h>

#define DFBCHECK(x...)                                         \
  {                                                            \
    DFBResult err = x;                                         \
                                                               \
    if (err != DFB_OK)                                         \
      {                                                        \
        fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
        DirectFBErrorFatal( #x, err );                         \
      }                                                        \
  }


int main(int argc, char **argv) {
        IDirectFB *dfb = NULL;
        IDirectFBSurface *primary = NULL;
        int width = 0;
        int height = 0;
        int i = 0;

        DFBSurfaceDescription dsc;
        /*init directfb*/
        DFBCHECK(DirectFBInit(&argc, &argv));
        /*create interface*/
        DFBCHECK(DirectFBCreate(&dfb));

        /*フルスクリーン表示設定*/
        DFBCHECK(dfb->SetCooperativeLevel(dfb, DFSCL_FULLSCREEN));

        /*サーフェスの内容を設定*/
        dsc.flags = DSDESC_CAPS;
        dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;

        /*サーフェスの作成*/
        DFBCHECK(dfb->CreateSurface(dfb, &dsc, &primary));

        /*画面サイズを取得*/
        DFBCHECK(primary->GetSize(primary, &width, &height));

        /*赤・緑・青を表示*/
        primary->SetColor(primary, 0xff, 0, 0, 0x7f);
        DFBCHECK(primary->FillRectangle(primary, 0, 0, 215, height));
        primary->SetColor(primary, 0, 0xff, 0, 0x7f);
        DFBCHECK(primary->FillRectangle(primary, 216, 0, 430, height));
        primary->SetColor(primary, 0, 0, 0xff, 0x7f);
        DFBCHECK(primary->FillRectangle(primary, 431, 0, width, height));
        DFBCHECK(primary->Flip(primary, NULL, 0));

        sleep(10);

        primary->Release(primary);
        dfb->Release(dfb);

        return 0;
}

作成したサンプルプログラムをコンパイル

export TARGET=arm-unknown-linux-gnueabi
export CROSS=${クロスコンパイラのルートパス}
export SYSROOT=$CROSS/$TARGET/sysroot
export PATH=$PATH:$CROSS/bin

arm-unknown-linux-gnueabi-gcc -o samplefb main.c \
  -I${SYSROOT}/usr/include/directfb \
  -I${SYSROOT}/usr/include/directfb-internal \
  -L${SYSROOT}/usr/lib -lpthread -ldirect -ldirectfb -lfusion

qemu実行環境の作成

作成したサンプルプログラムをqemuで実行する為、qemu実行用のルートファイルシステムイメージにDirectFD用のライブラリをコピーする。
ただ、DirectFBのライブラリだけコピーするのはめんどくさいので、DirectFBでARM環境をグラフィカル表示~その① - keropoの備忘録でクロスコンパイラのライブラリフォルダにDirectFBのライブラリも出力されているので、全てのライブラリをルートファイルシステムイメージにコピーしてしまう。

 $cp -Rp ${SYSROOT}/lib/*.so* ${ルートイメージ}/lib
 $cp -Rp $CROSS/$TARGE/lib/*.so* ${ルートイメージ}/lib
 $cp -Rp ${SYSROOT}/usr/lib/*.so* ${ルートイメージ}/usr/lib
 $cp -Rp ${SYSROOT}/usr/lib/directfb-1.4-0 ${ルートイメージ}/usr/lib

そして、ルートにdirectfbの設定ファイルを作成する。

  $vi ${ルートイメージ}/.directfbrc
  system=fbdev
  module-dir=/usr/lib/directfb-1.4-0/
  fbdev=/dev/fb0
  mode=640x480
  depth=16

最後にルートに作成したサンプルプログラムをコピー

  $cp samplefb ${ルートイメージ}

実行

実行した結果は以下のような感じ。

いろいろ出来るみたいなので、もう少しdirectFBで遊んでみる予定。

STM32VLDとSTBee Miniのコンパイル環境

経緯

組込みLinuxをメインで調べていたけど、ちょっと脱線してSTM32というARMのワンチップマイコンについて調べていたので、その際のコンパイル方法のメモ。
ネットでしらべるとEclipseとCode Sourcery Liteで開発環境を構築するのが主流みたいだけど、せっかくARMクロスコンパイラ作成 - keropoの備忘録でARMクロスコンパイラを作成したので、これを使って手元にあるマイコンボードのSTM32 Value Line DiscoveryとSTBee mini用にクロスコンパイルしてみた際のメモ。

サンプルソース

とりあえず、クロスコンパイル実験用のソースコードとして、ストロベリーリナックスからSTBee mini用のサンプルソースを落としてきた。

  wget http://strawberry-linux.com/pub/mini-demo.zip

Makefileの書き換え

ダウンロードしてきたファイルのMakefileを見ると、Code Sourcery Liteでのコンパイラプレフィックスが指定さているので、自分の環境に合わせて変更する。
vi等でMakefileを開き、「arm-none-eabi」を「arm-unknown-linux-gnueabi」に全て置換。

コンパイル

以下のコマンドを実行して、コンパイル

  $make clean
  $make

正常に終了し、「mini-demo.hex」というファイルが生成された。
あとはこのファイルをST-Link等で書き込めば完了。
結構苦労するかと思いきや、すんなりコンパイルできてしまった・・・。

DirectFBでARM環境をグラフィカル表示~その①

はじめに

DirectFBを利用して、QEMUでグラフィカルな画面を表示してみる。
今回は、DirectFBを動かす上で必要なライブラリをクロスコンパイルする手順をメモ。

DirectFBとは

DirectFBは、Direct Frame Bufferという意味で、組込みLinuxでの利用を前提に開発されたフレームバッファを利用したグラフィカル表示を行う為のライブラリ群。
単純なグラフィカルライブラリではなく、入力デバイスの管理やウィンドウシステムなどもサポートしているらしい。
デジタルテレビのGUI環境のライブラリとしても使用されていたらしい。今も使われているのだろうか?

環境変数の設定

ロスコンパイラへのパスなどの環境変数を設定する。
自分の環境では以下のように設定

export CROSS=${クロスコンパイラのルートフォルダ}
export TARGET=arm-unknown-linux-gnueabi
export SYSROOT=$CROSS/$TARGET/sysroot
export PAHT=$PATH:$CROSS/bin

zlibのクロスコンパイル

 $tar xvfz zlib-1.2.8.tar.gz
 $cd zlib-1.2.8
 $CC=$TARGET-gcc ./configure --shared --prefix=$SYSROOT/usr
 $make
 $make install

libpngのクロスコンパイル

新しめのlibpng-1.6.1を利用しようとしたが、これを使うとDirectFBのコンパイルが上手くいかないので、とりあえず古めのソースを落としてきた。

 $tar xvfz libpng-1.2.50.tar.gz
 $cd libpng-1.2.50
 $CC=$TARGET-gcc ./configure --host=$TARGET --prefix=$SYSROOT/usr
 $make
 $make install

libjpegのクロスコンパイル

 $tar xvfz jpegsrc.v9.tar.gz
 $cd jpegsrc-9
 $CC=$TARGET-gcc ./configure --host=$TARGET --prefix=$SYSROOT/usr
 $make
 $make install

freetypeのクロスコンパイル

 $tar jxvf freetype-2.4.11.tar.bz2
 $cd freetype-2.4.11
 $CC=$TARGET-gcc ./configure --host=$TARGET --prefix=$SYSROOT/usr
 $make
 $make install

DirectFBのクロスコンパイル

いよいよ本体のクロスコンパイル。
ただ、ちょっとだけソースの修正が必要

 $tar xvfz DirectFB-1.4.1.tar.gz
 $cd DirectFB-1.4.1

gfxdrivers/davinci/davinci_c64x.cを開き、下記include文を適当な位置に追加

  #include <sys/stat.h>

後はコンパイルを実行

 $CC=$TARGET-gcc \
   FREETYPE_CFLAGS="-I$SYSROOT/usr/include/freetype2" \
   FREETYPE_LIBS="-lfreetype" \
   ./configure \
   --host=$TARGET \
   --prefix=$SYSROOT/usr \
   --enable-shared \
   --disable-x11 \
   --disable-libtool-lock

 $make
 $make install

$SYSROOT/usr/libの配下に「libdirectfb・・・」というライブラリができていればOK。
次回は、このライブラリを利用したプログラムを作成して、QEMU上で動かしてみます。

qemuとbusyboxでhttpサーバ起動

qemu上にbusyboxhttpdで、簡易HTTPサーバを立ち上げた際のメモ。

前準備

qemu上にHTTPサーバを起動し、ホストOS又は別PCからhttpアクセスさせるには、qemuがネットワークにアクセスできるようにする為にホストOS側でTUN/TAPデバイスの使用するための設定をする必要がある。
まずは必要なツール(bridge-utils)がホストOSにインストールされているか確認

  #yum list installed | grep bridge-utils

インストールされていなければ、yumでインストールする。

  #yum -y install bridge-utils

/dev/net/tunというデバイスファイルが存在するか確認し、なければ作成する。

  #mknod /dev/net/tun c 10 200

ブリッジ接続設定

ホストOS側のネットワークにブリッジ接続の設定を行う。
まず、ブリッジさせたいNICスクリプトファイル(今回はeth0)をブリッジ用にコピーする。

  #cd /etc/sysconfig/network-scripts
 #cp ifcfg-eth0 ifcfg-br0

それぞれ修正

ifcfg-br0

下記の項目をブリッジ用に修正

 DEVICE=br0
 NM_CONTROLLED=no
 TYPE=Bridge
ifcfg-eth0

下記項目をコメントアウト

 IPADDR
 NETMASK
 GATEWAY
 DNS1
 DNS2
 DEFROUTE
 IPV4_FAILURE_FATAL
 IPV6INIT

下記項目を追加

  BRIDGE=br0

ネットワークをリスタート

  #service network restart

ブリッジが張れたことを確認。
brctl showと叩き、以下のように出力されていればOK。

 # brctl show
 bridge name     bridge id               STP enabled     interfaces
 br0             8000.000c29a4aec7       no              eth0

TAPの設定

qemu用にTAP起動スクリプトを作成する。

 $vi ~/qemu-ifup
  #!/bin/sh
  /sbin/ifconfig $1 0.0.0.0 promisc up
  /usr/sbin/brctl addif br0 $1 
 $chmod +x ~/qemu-ifup

qemu起動

作成したTAPスクリプト指定して、起動する。
TAPを設定してqemuを実行する場合、ルートユーザでないと起動が失敗するようなので、ルートになって実行

  $su
  #qemu-system-arm -M versatilepb -m 256 -kernel zImage -hda rootfs.img -serial stdio  -append "root=/dev/sda rw console=ttyAMA0 init=/sbin/init" -net nic -net tap,ifname=tap0,script=~/qemu-ifup

ゲストOS(qemu上の組込みLinux側)のネットワーク設定

qemuが起動し、組込みLinuxが起動したら、ネットワーク設定を行う。
ホストOSのIPが192.168.137.105でデフォルトゲートウェイが192.168.137.1なので、ゲスト側は以下に設定。

 #ifconfig eth0 192.168.137.100
 #route add default gw 192.168.137.1

HTTPサーバ起動(qemu側)

とりあえず、ブラウザからアクセスされたときの為に簡単なHTMLを作成

  #mkdir -p /var/www
 #vi /var/www/index.html
   <html>
   <body>
   <h1>hello linux</h1>
   </body>
  </html>

下記コマンドでHTTPサーバを起動

  #httpd -h /var/www

後は実際にホストOSや他のネットワークが繋がっているPCからアクセスすれば、index.htmlが参照できるはず。

  http://192.168.137.100/

一応、今回は、htmlを表示してみるだけだったが、busyboxhttpdにはリバースプロキシなどの機能もあるので、結構色々なことができるようです。
使い方はbusyboxのソース(networking/httpd.c)に書かれています。

qemuでjpegを表示

LinuxカーネルをARMでクロスコンパイルしてqemu上で動くまでいったが、とりあえずグラフィック表示してみないと面白くないということで、jpegエンコード・デコードライブラリであるlibjpegをクロスコンパイルして、これまで構築した組込みLinuxカーネル上で動かしてみた。

libjepgのダウンロード

以下のコマンドでlibjpegのソースをダウンロード

  http://www.ijg.org/files/jpegsrc.v9.tar.gz

libjpegのクロスコンパイル

ロスコンパイラの環境変数設定

 export TARGET=arm-unknown-linux-gnueabi
 export CROSS=%{クロスコンパイラフォルダ}
 export SYSROOT=$CROSS/$TARGET/sysroot

 export PATH=$PATH:$CROSS/bin

コンフィグレーションの実行

ダウンロードしてきたlibjpegソース圧縮ファイルを解凍して、コンフィグレーションを実行する。

  $CC=$TARGET-gcc ./configure --host=$TARGET --prefix=$SYSROOT

コンパイル実行

  $make
  $make install

make installが正常に終了すると、$SYSROOT/libフォルダ配下に以下のファイルが出来ているはず。

  libjpeg.a
  libjpeg.so
  libjpeg.so.9
  libjpeg.so.9.0.0

サンプルプログラムのクロスコンパイル

FrameBufferを利用してjpegを画面に表示するサンプルプログラム(下記URLからダウンロード)をクロスコンパイルする。
http://ux.getuploader.com/kero_bimouroku/download/1/libjpegex.zip

 $ $TARGET-gcc -c image.c -I$SYSROOT/include
 $ $TARGET-gcc -c main.c -I$SYSROOT/include
 $ $TARGET-gcc -o sjpg *.o -ljpeg

組込みLinux用ルートファイルシステムイメージにライブラリとサンプルプログラムを配置

libjpegコンパイルで作成された.soファイルを組込みLinux用のルートファイルシステムイメージのlibフォルダにコピーする。
また、サンプルプログラムは表示するjpegファイルと共にルートファイルシステムイメージ内の適当なフォルダにコピーする。

qemuで実行確認

実際にqemuを起動して、作成したサンプルプログラムを実行し、jpegが表示されることを確認する。
以下が実際に実行した例
f:id:keropo:20130503230828p:plain

ちょっとカーソル部分が欠けてしまっているけど、とりあえずFrameBufferを利用してjpegが表示できた。

qemuで組込みLinuxを起動

BusyBoxのコンパイル - keropoの備忘録で作成したコマンドを使って、実際にルートファイルシステムを作成し、qemu上で実際にコマンドが打てる状態にするための手順。
カーネルlinuxカーネルのコンパイル - keropoの備忘録で作成したものを使用。

ルートフォルダの作成

とりあえず、適当な場所にqemuで起動するLinuxのルートフォルダを作成する。
一応、自分の環境では以下に設定

  $export ROOTFS=~/rootfs
  mkdir -p $ROOTFS

BusyBoxをコピー

作成したルートフォルダにBusyBoxのコマンド類をコピーする。

  $cp -Rp ${BusyBoxフォルダ}/_install/* ${ROOTFS}

ツールチェーンからライブラリ群をコピー

カーネルBusyBoxをクロスコンパイルしたツールチェーンからライブラリ群をコピーする。

  $cp -Rp ${CROSS}/arm-unknown-linux-guneabi/sysroot/lib ${ROOTFS}
  $cp -Rp ${CROSS}/arm-unknown-linux-guneabi/sysroot/usr/lib ${ROOTFS}/usr

その他、必要なフォルダ作成

  $mkdir -p ${ROOTFS}/dev/input
  $mkdir -p ${ROOTFS}/etc/init.d
 $mkdir proc
 $mkdir sys

デバイスファイルの作成

とりあえず、最低限必要そうなデバイスファイルを作成しておく。
スーパーユーザでないとmknodeコマンドは叩けないので注意

    #mknod dev/null c 1 3
    #mknod dev/zero c 1 5
    #mknod dev/fb0 c 29 0
    #mknod dev/sda b 8 0
    #mknod dev/sda1 b 8 1
    #mknod dev/sda2 b 8 2
    #mknod dev/sda3 b 8 3
    #mknod dev/sda4 b 8 4
    #mknod dev/sr0 b 11 0
    #mknod dev/tty c 5 0
    #mknod dev/tty0 c 4 0
    #mknod dev/tty1 c 4 1
    #mknod dev/tty2 c 4 2
    #mknod dev/tty3 c 4 3
    #mknod dev/tty4 c 4 4
    #mknod dev/ttyAMA0 c 204 64
    #mknod dev/ttyAMA1 c 204 65
    #mknod dev/ttyS0 c 4 64
    #mknod dev/ttyS1 c 4 65
    #mknod dev/input/mouse0 c 13 32
    #mknod dev/input/mouse1 c 13 33
    #mknod dev/input/mouse2 c 13 34
    #mknod dev/input/mouse3 c 13 35
    #mknod dev/input/misc c 13 63
    #mknod dev/input/event0 c 13 64
    #mknod dev/input/event1 c 13 65
    #mknod dev/input/event2 c 13 66
    #mknod dev/input/event3 c 13 67
    #mknod dev/input/event4 c 13 68

inittabの作成

initプロセスで参照されるinittabをとりあえず、下記のように作成

vi etc/inittab
  ::sysinit:/bin/mount -t proc proc /proc
  ::sysinit:/bin/mount -t sysfs sysfs /sys
  ::sysinit:/etc/init.d/rcS
  ::respawn:/bin/sh
  ::ctrlaltdel:/sbin/reboot

起動スクリプト作成

inittabで定義した起動スクリプト(/etc/init.d/rcS)を作成

vi etc/init.d/rcS
  #!/bin/ash

  export PATH=/bin:/sbin/usr/bin:/usr/sbin
  export LD_LIBRARY_PATH=/lib:/usr/lib

  echo "==================================="
  echo "  Linux system initialize         "
  echo "==================================="

  exit 0

スクリプトを作成したら、実行権限をつけておくこと。

ディスクイメージを作成

ディクスイメージを作成して、ルートフォルダをまるっとコピー。

  ##125Mのイメージを作成
  #dd if=/dev/zero of=rootfs.img bs=1M count=125

 ##ext2ファイルシステムでフォーマット
 #mkfs.ext2 -F rootfs.img

  ##適当にマウントしてルートフォルダをコピー
 #mount -text2 -o loop rootfs.img /mnt/sd
  #cp -Rp ${ROOTFS}/* /mnt/sd
  #umount /mnt/sd

qemuを起動し、動作を確認

以下のコマンドで動作を確認してみる。

 $qemu-system-arm -M versatilepb -m 256 -kernel zImage -hda rootfs.img -serial stdio  -append "root=/dev/sda rw console=ttyAMA0 init=/sbin/init"

起動の様子は以下。モニタ側にはペンギンロゴのみ出力され、起動ログはシリアル側(ここでは、ターミナル側)に出力されるようにしている。
f:id:keropo:20130422225614j:plain