ARMクロスコンパラUpdate(gcc-5.4.0)
以前作成したクロスコンパイラがちょっと古くなったのでUpdate
事前
- BISON
バージョンが3.0以上だと、eglibcのビルドに失敗するので、2.7にバージョンダウン
- MAKE
MAKEのバージョンが4.X台だと、eglibcのconfigureに失敗する。
configureを修正するか、makeのバージョンを3.XX台にダウングレード
ソース修正
eglibcのソースはちょっと修正が必要
cd ${GLIBC_SRC}/libc/ports/sysdeps/unix/sysv/linux/arm/nptl
mv unwind-forcedunwind.c unwind-forcedunwind.c.org
mv unwind-resume.c unwind-resume.c.org
sed -e "25s/;/ __attribute_used__;/" unwind-forcedunwind.c.org > unwind-forcedunwind.c
sed -e "23s/;/ __attribute_used__;/" unwind-resume.c.org > unwind-resume.c
ビルド
gccのビルド以外は前回と同じ。
gcc1回目から3回目までのビルド手順は以下
gcc 1回目
$../configure \
--target=$TARGET \
--prefix=$CROSS \
--without-headers \
--without-ppl \
--with-newlib \
--disable-shared \
--disable-threads \
--disable-libssp \
--disable-libgomp \
--disable-libmudflap \
--disable-libquadmath \
--disable-libatomic \
--disable-nls \
--with-gmp=$CROSS \
--with-mpfr=$CROSS \
--with-mpc=$CROSS \
--enable-languages=c
$make
$make install
gcc 2回目
$../configure \
--target=$TARGET \
--prefix=$CROSS \
--with-sysroot=$ROOTDIR \
--with-headers=$ROOTDIR/usr/include \
--with-libs=$ROOTDIR/usr/lib \
--disable-multilib \
--disable-libstdcxx-pch \
--disable-libssp \
--disable-libgomp \
--disable-libmudflap \
--disable-libquadmath \
--disable-libatomic \
--with-gmp=$CROSS \
--with-mpfr=$CROSS \
--with-mpc=$CROSS \
--enable-languages=c
$make
$make install
gcc 3回目
$../configure \
--target=$TARGET \
--prefix=$CROSS \
--with-headers=${ROOTDIR}/usr/include \
--with-libs="${ROOTDIR}/usr/lib ${ROOTDIR}/lib" \
--disable-multilib \
--disable-libstdcxx-pch \
--disable-libssp \
--disable-libgomp \
--disable-libmudflap \
--disable-libquadmath \
--disable-libatomic \
--with-gmp=$CROSS \
--with-mpfr=$CROSS \
--with-mpc=$CROSS \
--enable-languages=c,c++
$make
$make install
理由はちょっと不明だが、configureのoptionで、「--with-sysroot」を指定していると、libstdc++-v3のconfigureで
link tests are not allowed after GCC_NO_EXECUTABLES
となり、失敗する。libcが見えていないみたい。
"--with-sysroot"で、クロスコンパイラのルートパスを指定しているのに理由不明
結局、"--with-sysroot"の指定は削除し、以下を追加した。l
--with-headers=${ROOTDIR}/usr/include \
--with-libs="${ROOTDIR}/usr/lib ${ROOTDIR}/lib" \
Linuxデバイスドライバ基礎② procインタフェース
procインタフェースを利用してユーザランドからカーネル(ドライバ)と通信するサンプル
procfs.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
MODULE_LICENSE("GPL");
#define PROC_NAME "driver/example"
static int proc_open(struct inode *node, struct file *fp)
{
printk("open\n");
return 1;
}
static ssize_t proc_read(struct file *fp, char *buf, size_t size, loff_t *off)
{
printk("read\n");
return size;
}
static ssize_t proc_write(struct file *fp, const char *buf, size_t size, loff_t *off)
{
printk("write\n");
return size;
}
static struct file_operations example_proc_fops = {
.owner = THIS_MODULE,
.open = proc_open,
.read = proc_read,
.write = proc_write,
};
static __init int procfs_init(void)
{
struct proc_dir_entry *ent;
ent = proc_create(PROC_NAME, S_IRUGO | S_IWUGO | S_IXUGO, NULL, &example_proc_fops);
if (ent == NULL)
{
return -ENOMEM;
}
printk("proc example loaded\n");
return 0;
}
static __exit void procfs_exit(void)
{
printk("delete dirver\n");
remove_proc_entry(PROC_NAME, NULL);
}
module_init(procfs_init);
module_exit(procfs_exit);
Linuxデバイスドライバ基礎①
クロスコンパイラでデバイスドライバをビルドする時のサンプルMakefileとスケルトン
まあ、簡単なので、特に説明なしです。
Makefile
KERNEL_SRC=${カーネルソースフォルダ}
obj-m := hogehoge.o
CROSS_COMPILE=arm-unknown-gnueabi- ※クロスコンパイラのプレフィックス
ARCH=arm ※アーキテクチャ
MAKE_CMD=$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)
all:
$(MAKE_CMD) -C $(KERNEL_SRC) -M $(PWD) modules
clean:
$(MAKE_CMD) -C $(KERNEL_SRC) -M $(PWD) clean
hogehoge.c
#include <linux/module.h> #include <linux/init.h> static init __init hoge_init(void) { printk("hello hoge_init\n"); return 0; } static void __exit hoge_exit(void) { printk("hoge goodby\n"); } module_init(hoge_init); module_exit(hoge_exit); MODULE_AUTHOR("keropo"); MODULE_DESCRIPTION("hogehoge"); MOUDLE_LICENSE("GPL");
v8 engineのサンプルプログラム
せっかく、v8をコンパイルしたので、サンプルプログラムをオフィシャルサイト等々を参考に作成してみた。
APIの仕様だったり、クラスのメンバー関数の構造が変わったらしく、ネットでよく見かけるサンプルプログラムではコンパイルが通らなかった。
一応、試行錯誤しながら、動くものが完成した。
サンプルとしては、v8にオリジナルの関数とクラスを組み込むサンプルになります。
/* * v8 javascript engine simple sample program. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <v8.h> using namespace v8; class ShellArrayBufferAllocator : public ArrayBuffer::Allocator { public: virtual void* Allocate(size_t length) { void *data = AllocateUninitialized(length); return data == NULL ? data : memset(data, 0, length); } virtual void* AllocateUninitialized(size_t length) { return malloc(length); } virtual void Free(void* data, size_t) { free(data); } }; class TObject { private: int ident; public: explicit TObject(int value = 0) :ident(value) { } int GetIdent() const { return ident; } Persistent<Object> *holder; }; class TObjectIF { private: static TObject* GetThis(const Local<Object> handle) { void *This = Local<External>::Cast(handle->GetInternalField(0))->Value(); return static_cast<TObject*>(This); } static void New(const FunctionCallbackInfo<Value> &args) { TObject *p = NULL; if (args.Length() > 0) { p = new TObject(args[0]->Int32Value()); } else { p = new TObject(); } Local<Object> thisObject = args.This(); thisObject->SetInternalField(0, External::New(args.GetIsolate(), p)); Persistent<Object> *holder = new Persistent<Object>(args.GetIsolate(), thisObject); holder->SetWeak<TObject>(p, TObjectIF::Dispose); p->holder = holder; } static void Dispose(const WeakCallbackData<Object, TObject> &data) { TObject *p = data.GetParameter(); Persistent<Object> *holder = p->holder; //release instance. holder->Reset(); if (p != NULL) { delete p; } } static void GetIdent(const FunctionCallbackInfo<Value> &args) { TObject *p = GetThis(args.This()); args.GetReturnValue().Set(p->GetIdent()); } public: static void InitializeTemplate(Isolate *isolate, Handle<ObjectTemplate> global) { Local<FunctionTemplate> clazz = FunctionTemplate::New(isolate, TObjectIF::New); clazz->SetClassName(String::NewFromUtf8(isolate, "TObject")); Local<ObjectTemplate> instTemplate = clazz->InstanceTemplate(); instTemplate->SetInternalFieldCount(1); Local<ObjectTemplate> protoTemplate = clazz->PrototypeTemplate(); protoTemplate->Set( String::NewFromUtf8(isolate, "getIdent"), FunctionTemplate::New(isolate, TObjectIF::GetIdent)); global->Set(String::NewFromUtf8(isolate, "TObject"), clazz); } }; void Print(const FunctionCallbackInfo<Value> &args) { HandleScope handle_scope(args.GetIsolate()); for (int i = 0; i < args.Length(); i++) { String::Utf8Value str(args[i]); printf("%s", *str); } printf("\n"); args.GetReturnValue().Set(0); } Handle<Context> InitBuildinFunction(Isolate *isolate) { Handle<ObjectTemplate> global = ObjectTemplate::New(isolate); global->Set(String::NewFromUtf8(isolate, "print"), FunctionTemplate::New(isolate, Print)); TObjectIF::InitializeTemplate(isolate, global); return Context::New(isolate, NULL, global); } int main(int argc, char **argv) { V8::InitializeICU(); V8::SetFlagsFromCommandLine(&argc, argv, true); ShellArrayBufferAllocator array_buffer_allocator; V8::SetArrayBufferAllocator(&array_buffer_allocator); Isolate *isolate = Isolate::New(); Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); Handle<Context> context = InitBuildinFunction(isolate); Context::Scope context_scope(context); Handle<String> source = String::NewFromUtf8(isolate, "var p = new TObject(10); print(p.getIdent());"); Handle<Script> script = Script::Compile(source); Handle<Value> result = script->Run(); String::Utf8Value utf8(result); printf("%s", *utf8); V8::Dispose(); return 0; }
google v8 javascript engineをコンパイル
google v8 javascript engineをビルド手順メモ
ソース取得
$svn checkout http://v8.googlecode.com/svn/trunk/ v8 $cd v8 $svn co http://gyp.googlecode.com/svn/trunk build/gyp $svn checkout --force https://src.chromium.org/chrome/trunk/deps/third_party/icu46 third_party/icu --revision 214189
一部ソースを修正
src/typing.cc +#pragma GCC diagnostic ignored "-Wuninitialized" void AstTyper::VisitVariableProxy(VariableProxy* expr) {
Webkitgtk for ARMでブラウザ表示成功
仕事やら何やらで忙しく、全然更新していなかったけど、久しぶりに更新。
arm-qemu上でWebKitGtkを動かせはしたが、文字表示が変だったのと、URLにファイルシステムのパスを指定して事項すると、HTML表示できなかったが、一応、動くようになったので、メモ。
文字表示
前回、文字化けしていた理由はどうやらフォントがqemuのファイルシステムイメージになかったためだった。
なので、今回は、ホスト(CentOS)にあるフォントをqemuのファイルシステムイメージにコピー
$cp -r /usr/share/fonts/default ${qemuルート}/usr/share/fonts/
あとは、rcSで以下のコマンドを発行して、フォントをキャッシュ化する。
fc-cache -vfs
また、関連設定ファイルも修正
/etc/pango/pangorc
[Pango] ModulesPath=/usr/lib/pango/1.6.0/modules ModuleFiles=/etc/pango/pango.modules [PangoFT2] FontPath=/usr/share/fonts/default/Type1
ファイルシステム内のHTML表示
shared-mime-infoというパッケージを追加する。
$wget http://freedesktop.org/~hadess/shared-mime-info-0.51.tar.bz2
$su - #yum -y install intltool cpan #cpan XML:Parser
$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
あとは組込みLinuxのrcSで、以下のコマンドを実行すればOK
/usr/bin/update-mime-database -V /usr/share/mime

WebKit on DirectFB をARM cross compileの続き。
WebKitの動作確認
前回(WebKit on DirectFB をARM cross compile - keropoの備忘録)コンパイルしたWebKitをarm-qemu上で動かしてみる。
ターゲットの設定
/etc/init.d/rcS
以下の環境変数を追加
$vi ${ターゲットルート}/etc/init.d/rcS
export PANGO_RC_FILE=/etc/pango/pangorc
export FONTCONFIG_FILE=/etc/fonts/fonts.conf
export GTK2_RC_FILES=/etc/gtk-2.0/gtkrc
export GDK_PIXBUF_MODULE_FILE=/etc/gtk-2.0/gdk-pixbuf.loaders
/etc/pango/pangorc
pangorcを新規作成
$vi ${ターゲットルート}/etc/pango/pangorc
[Pango]
ModuleFiles=/etc/pango/pango.modules
pangoのロードモジュール情報の作成
$pango-querymodules > ${ターゲットルート}/etc/pango/pango.modules
/etc/gtk-2.0/gtkrc
$vi ${ターゲットルート}/etc/gtk-2.0/gtkrc
gtk-font-name="sans 10"
gdk-pixbufのロードモジュール情報を作成
$gdk-pixbuf-query-loaders > ${ターゲットルート}/etc/gtk-2.0/gdk-pixbuf.loaders
/etc/fonts
${ターゲットルート}/etc/fonts/fonts.confを開き、キャッシュフォルダのパスにコンパイル時のprefixの値が設定されているので、/var/cache/fontconfigに変更する。
実行
さて、この状態でqemu上でGtkLauncherを実行させたら、一応、ブラウザらしき画面が表示された。

う~~ん、文字が全部□で表示されている。
ログをみると、フォントが選択されてないとかなんとか言われている。
原因はなんだろ?j