2011年7月9日

q5 : SLSI_SC6410

SmartQ5のソースファイルを見ていると、"SLSI_SC6410"というキーワードが出てくる。
SC6410というのは、SmartQ5で使われているチップだ。


どうでもいいけど、こういうときに何と呼ぶのかよくわからん。
ARMは、コアだ。
CPUでいいのかな?
今の仕事で使うものは、マイコン、と呼んでいるが、それは"CPU"だけでなく、周辺機器の機能も多分に含んでいるからだ。
まあ、メモリも外にあるし、CPUでいいかな。


SC6410というのは、SmartQ5で使われているCPUだ。
つまり"SLSI_SC6410"というのは、SC6410用に変更した箇所ですよ、といいたいのだろう。
Sは"Samsung"なのかな。

気になったのは、このマクロをどこで定義しているのか。
device/か? ・・・ない。
build/か? ・・・ない。
prebuilt/か? ・・・ない。
えーい、全部grepしてしまえ!

・・・一例をあげよう。

./external/alsa-utils/Android.mk:LOCAL_CFLAGS  += -DSLSI_S3C6410

そう、各々で指定しているのだ。
えー、そうなのー、と思った私である。

q5 : EGLのLoader

EGLの部分はいったいどこが呼ばれているんだろう?というところをやっている。

コンストラクタで/system/lib/egl/egl.cfgをオープンしている。
これがなければ、デフォルトのconfigを使う。
ログにはなかったので、これは読み込まれている。
ファイルの中身は、こうなっていた。

0 1 fimg

意味としては"dpy, impl, tag"となっている。
dpyはディスプレイ番号

さて、このegl.cfgだが、SmartQ5用に提供されている。
他にも、
  • lib/hw/copybit
  • lib/egl/egl.cfg
  • lib/egl/libEGL_fimg.so
  • lib/egl/libGLESv1_CM_fimg.so
  • lib/libGLESv1_CM_fimg.so
  • lib/libChunkAlloc.so
が提供されている。
ファイルとしてはlibGLESv2_fimg.soもあるのだが、これはコピーされていない。


Loader::open()では、いよいよライブラリをオープンしている。
ログでは、こうなっている。

D/libEGL  ( 1890): loaded /system/lib/egl/libEGL_fimg.so
D/libEGL  ( 1890): loaded /system/lib/egl/libGLESv1_CM_fimg.so

つまり、さっきのegl.cfgにあったfimgが使われているのだ。
tagってのは、そういう意味を持つようである。


さて、cnxってのは、このライブラリから持ってきているようだ。
getProcAddress()とかでエントリポイントを取得するのかな?
libEGL.soをnmで見ると。。。symbolがないのでわからない。
代わりに、自前でビルドした方を見てみる。

00003201 T eglGetConfigAttrib

これが呼ばれているんだろうな。
うーん、思ったよりも大事になってきたなあ。。

q5 : 2つのeglGetConfigAttrib()

EGLUtils::selectConfigForPixelFormat()からeglGetConfigAttrib()を呼び出している。
検索すると、eglGetConfigAttrib()は2箇所にあった。

frameworks/base/opengl/libs/EGL/egl.cppにある方が最初に呼ばれていると思う。
その中からさらに、frameworks/base/opengl/libagl/egl.cppにある方が呼ばれているのだと思う。
そしてそこから同ファイルにあるgetConfigAttrib()が呼ばれているはず。
ログ出したりして確認すればいいんだろうけど、それは予想と違ったときにしよう。

・・・違ったので確認しよう。
frameworks/base/opengl/libs/EGL/egl.cppの方は、呼ばれている。
しかしlibaglは呼ばれていない。
cnx->egl.eglGetConfigAttrib()で足取りが途切れてしまった。


たぶん、だが、opengl/libs/EGL/Loader.cppのLoader::open()あたりではないかな。

q5 : mNativeWindow.get()はFramebufferNativeWindowのアドレスを返す

前回の続き。
mNativeWindow.get()が590200という値を返しているが、これはRGB565なので4になるべきでは?
その疑問を抱いたので、調べることにした。

mNativeWindowは、FramebufferNativeWindowクラス。
frameworks/base/include/ui/FramebufferNativeWindow.hにある。
が、この中にget()はいない。
しかし、getなんていう曖昧な名前は勘弁して欲しい。。。

ここからが大変だ。
定義はこうなっている。

class FramebufferNativeWindow
    : public EGLNativeBase<
        ANativeWindow,
        FramebufferNativeWindow,
        LightRefBase >

テンプレートだ。。。

template
class EGLNativeBase : public NATIVE_TYPE, public REF

第1と第3のクラスを継承している。
第1はANativeWindow、第3はまたテンプレートだが、これはラッパのようだ。
よくわからないが、そういう書き方をするのだろう。

が、ここまでみていってもget()がない。
なんでだ??

そこでようやく、mNativeWindowの定義を見た。

sp<FramebufferNativeWindow> mNativeWindow;

なんと、spだ。
shared pointerの略なのかな? newすれどdelete不要っていう参照カウンタで管理してくれるやつだ。
で、sp<>.get()は、本体のアドレスを返す。
つまり、mNativeWindow.get()はアドレスなのだ。
それをintでデバッグ表示させていたので、数値が違ったのだな。
なんで間違ったかというと、見る関数を1つ飛ばしていたからだ。
あーあ、ばからしい。


ただしく。

init()はEGLUtils::selectConfigForNativeWindow()を呼び、その中でNATIVE_WINDOW_FORMATを取得し、その値でselectConfigForPixelFormat()を呼び出している。
値を確認すると、4。
ちゃんとしてますな。

問題なのは、eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID)が0を返すというところにある。
次はそこを見ていきましょう。

q5 : EGL

画面が出ない件の調査中。

E/SurfaceFlinger( 1888): couldn't find an EGLConfig matching the screen format

まずはこれを追っていこう。

frameworks/base/services/surfaceflinger/DisplayHardware.cppのinit()。
ここで、EGLUtils::selectConfigForNativeWindow()がエラーを返している。

EGLUtils::selectConfigForNativeWindow()はlibs/ui/EGLUtils.cppにある。
eglChooseConfig()でconfigを取得し、eglGetConfigAttrib()で属性を取得し、期待するformatと一致するconfigを探す、という動作。

ということはわかるのだが、そもそもeglChooseConfig()とかeglGetConfigAttrib()とかがわからん。
OpenGL関係っぽいことは名前からわかるのだが。。。
関数の頭にeglって書いてあるから、EGLっていうものがあるんだろう。

まずは、EGLが何なのかを知らねば。

-------------------------------------------------------------------------------------------------
EGL。
OpenGL|ESのようなAPIとネイティブ環境の描画をつなぐ層みたいだ。
peer層みたいなものか。
つまり、OpenGL|ESの詳細な実装方法は知らなくても、EGLの各API仕様を満たすように実装しさえすればOpenGL|ESが動かせる、ということになる。
ネイティブとつなぐ部分だから、今回のようにハードウェア環境が違うと手を入れなくてはならないのだろう。


簡単に使い方を知りたいので検索すると、こちらのサイトが見つかった。
うん、今回の処理部分は、ここに書いてある初期化部分と同じ流れだ。
参考にして読み進めよう。


まず、eglChooseConfig()。
init()からはattribとしてEGL_SURFACE_TYPEとEGL_WINDOW_BITを指定している。
これが検索対象ということだろう。
検索値は、format、しかないな。
mNativeWindow.get()は"590200"という値。
なんだこれは・・・。

frameworks/include/ui/PixelFormat.hに定義がある。
型はint32_tで、内容はenumで定義してある。
しかし・・・590200に相当する値がない。
SmartQ5を見ると、ここが拡張されていた。
マージ漏れか。。

いや、ちょっと待て。
うちのSmartQ5はこんな感じだ。

I/gralloc ( 1888): using (fd=25)
I/gralloc ( 1888): id           = s3cfb
I/gralloc ( 1888): xres         = 800 px
I/gralloc ( 1888): yres         = 480 px
I/gralloc ( 1888): xres_virtual = 800 px
I/gralloc ( 1888): yres_virtual = 960 px
I/gralloc ( 1888): bpp          = 16
I/gralloc ( 1888): r            = 11:5
I/gralloc ( 1888): g            =  5:6
I/gralloc ( 1888): b            =  0:5
I/gralloc ( 1888): upper_margin = 10
I/gralloc ( 1888): lower_margin = 35
I/gralloc ( 1888): left_margin  = 40
I/gralloc ( 1888): right_margin = 216
I/gralloc ( 1888): pixclock     = 33358920
I/gralloc ( 1888): width        = 800 mm (25.400000 dpi)
I/gralloc ( 1888): height       = 480 mm (25.400000 dpi)
I/gralloc ( 1888): refresh rate = 60.00 Hz

RGB565なのだから、PIXEL_FORMAT_RGB_565=HAL_PIXEL_FORMAT_RGB_565=4のはずだ。
mNativeWindow.get()は何を返しているんだ?

これは別の調査としよう。

2011年7月8日

「かざしてログオン」は、たぶんだませる

かざしてログオンのことが出ていたので、ちょっと思い出した。
記事で書いていたような気がしたけど、出てこなかった。。。
何かというと、だまし方だ。

同じようなことを書くことになりそうだが、まあ年寄りのことだからと我慢しておくれ。


FeliCaのカードがある。
これを出退勤のタイムスタンプ代わりにしたいとしよう。
授業の出欠でもいいし、鍵の代わりでもいい。
つまり、カードが身分証明の代わりを果たすような場合と考えてもらおう。

さて、どうやるのが一番確実だろうか?

私が一番確実だと思うのは、FeliCaカード(FeliCa Liteではなく)を使い、共通領域なり他の領域なりのシステムを割り当て、エリアを割り当て、鍵をかけたブロックが用意することだ。
たとえば、Suica。
これはサイバネ領域を使っていて、アクセスもたぶん縮退鍵などでアクセスするようなところにある。
自前の領域なので、読み書きができる。
一致した鍵を持った人が近づくと見えるコインロッカーみたいなものか(あるのか?)。


次は・・・どれだろう。
FeliCa Liteで片側認証する場合だろうか。
FeliCaでは共通領域になるだろうけど、ドコモみたいに開放しているところは少ないだろう。
もし共通領域を使うなら、前者の方法をとるだろうし。
コインロッカーの前に人がいて、鍵が自分のところのものか調べるような感じかしら。


その次は、誰でもアクセスできる領域に、自分で暗号化を掛けたデータを書き込むこと。
この場合のセキュリティは、FeliCaのものではない。
「解読できるならやってみろ」とネット上にファイルを置くようなイメージかな。


それ以下なのが、書き込みできない状態で認識する方法だ。
よくやりがちなのは、IDmを見る方法。
非常に手軽なんだけど、IDmは重複する可能性があるので危険だ。
それだけだと不安だと思えば、読み取れるブロックを読んでおく、なんて方法もある。
自前のカードを用意しない場合は、この方式しか取れない。
「住所と表札が一緒だから、きっとこの人だろう」と家に上がり込むような感じか。


「かざしてログオン」は、もちろん最後の方法となる。
IDmだけではないのだが、まあ読み取っておける情報であることには違いがない。

そしてこれだけのことがわかり、あとPaSoRiを使いこなすことができれば、だませる。
かざしてログオンだけではなく、同種の方法をとっているもの全てを、だ。

必要なのは、PaSoRiと、相手に登録されているFeliCaカード。
それとPaSoRiを操作するソフトが組めるパソコン。
Linuxとかcygwinがあれば何とかなる。
たぶん、USB Host APIが使えれば、Androidでもできるだろう。


詳細は、説明しない。
それほど親切ではないが、だいたい予想が付くんじゃなかろうかね。
今やっているSmartQ5のが落ち着いたら、それに載せてみたいものだ。

この方法が採れるのは、FeliCaというかNFC-Fというか、それだけである。
NFC-A系は、少なくともできなかったはず。
カードになったとしても、UIDを3byteしか指定できないからだ。
わざとなんかねぇ。
怖いので、個人的にはFeliCaからも一部をマスクするような制限を付けてほしいものだ。

2011年7月3日

[q5]画面が出らんが、よくわからん

I/DEBUG ( 1820): #00 pc 0000314c /system/lib/libEGL.so
I/DEBUG ( 1820): #01 pc 000041fe /system/lib/libEGL.so

なので、見てみた。

$ addr2line -e libEGL.so 0000314c
frameworks/base/opengl/libs/EGL/egl.cpp:503

validate_display_config()の、ここ。

egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(config)].impl];


その前は、eglCreateWindowSurface()。
うーん。。。よくわからない。。。
もっと前に出ている、

E/SurfaceFlinger( 1888): couldn't find an EGLConfig matching the screen format

これかいな?
オリジナルと比較すると、ここのように思う。
しかし・・・どれが影響しているのかよくわからん。
来週だ、来週。

[q5]起動したっぽいが、画面が全然でらん

あれからもやっていたが、いくつか解決できた。

libcameraserviceに、命令エラーが出た。
illegal operation、だったか。
わからんが、私のlibcameraserviceはOpenCVと接続していて、それはBeagleBoard用にビルドしている。
ARMの系列が異なるから、なんかあるのかも。
とりあえず、USE_CAMERA_STUBを有効にして、カメラは捨てた。

libEGL_fimgでprelink mapがどうのこうのというエラーが出た。
SmartQ5のbuild/core/prelink-linux-arm.mapを見ると、確かに違いがある。
よくわからんなりに、マージしたら動くようになった。

Javaで数値に変換できない例外が出た。
これはinit.rcに不備があったためだ。
Gingerbreadで追加されたroをinit.rcに追加すると、進んだ。


ここまではよかった。
今起動させると、apkファイルをどんどん読んでいってるようなlogcatが確認できている。
タッチパネルは触っていないが、ボタンは動いているような感触もある。
だが・・・画面が出ない。
音が出ないのは、ALSA関係を無効にしたからなので、まあよかろう。

I/DEBUG   ( 1820): pid: 1906, tid: 1910  >>> /system/bin/bootanimation <<<
I/DEBUG   ( 1820): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr f905a660

まあ、これがすべての原因というわけではないだろうが、最初の面画が出ないのはこれだ。

I/DEBUG   ( 1820):          #00  pc 0000314c  /system/lib/libEGL.so
I/DEBUG   ( 1820):          #01  pc 000041fe  /system/lib/libEGL.so
I/DEBUG   ( 1820):          #02  pc 0000b3c4  /system/bin/bootanimation

こうなっているから、libEGL関係だろう。
ここら辺は、やりたくないんだよな。。。。
copybitをなくしてしまえば、いいのかもしれんが、それでは解決にならん。
とはいえ、どっから手をつけたものだか。。。

initでkernel panicになっていたが、init.rcの書き方が悪かった

SmartQ5だが、FLASH起動はあきらめた。
とりあえず、SDカードでブートさせよう。そっちの方がやりやすい。

そう思ってやっていたのだが、initでkernel panicが発生した。
特に書き換えたわけでもないので、変なことにはならないはず。

system/core/initにいろいろとログを追加していくと、init.rcの解析は終わっていて、それを実行している段階でおかしくなっている。
というよりも、ある地点に差し掛かると、おかしい。

どうやら、init.rcの書き方がよくなかったようだ。
引っかかっていたのは「on fs」のようなセクションの開始あたり。
init.rcは、

on XXX
    command...

のような構成になっている。
今回、on fsだったのだが、コメントアウトしていくうちにcommandが1つもなくなっていたのだ。
それでおかしくなったらしい。
on fsもコメントアウトすることで動くようになった。

ほほー。

[q5]ビルド

こんばんは。
二日酔いで昼頃起きたけど、うだうだして昼寝して夜になったので眠くない、なんてわけではありませんよ。

そんなわけで(?)、SmartQ5のビルドについてちょっと書いておこう。
以前やってたサイトのときには書いたんだけど、こっちに移ってきてからは書いてなかったと思う。
それに、ソース提供されてからの情報じゃないしね。


まず、準備。
gitとかrepoがいる。
コンパイラはAndroidに入っているものを使うので、準備しなくてよいだろう。
あと、mkimageがいる。これはu-bootを使っているからだ。
# sudo apt-get install uboot-mkimage
たぶん、こんな感じでインストールできたはず。

ソースのダウンロードができたら、あとは手順どおり。
最初は、kernelのビルドも確認した方がよいと思う。
というのは、私がkernelのビルドができていないことに気づいていなかったから。

# source myenv
# cd linux-2.6.29-s3c-smartQ5
# make zImage
# cp arch/arm/boot/zImage ../nami-smartq5-upgrade/firmware_files/zimage
# sudo ./buildfs.sh

コンパイラがない、みたいなエラーが出るときは、Makefileを変更しよう。
私は 2.3.4環境なので、こうなった。
なければ、それぞれの環境でそれっぽいものに置きかえるとよかろう。
CROSS_COMPILE  := ../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-


普通は、このくらいでよい。

# source myenv
# make
# sudo ./buildfs.sh

私は、buildspec.mkを用意し、build/envsetup.shをちょっと書き換えて使っている。
まあ、普通にビルドすればいいでしょう。
-jとか使えば、ビルドが早くなることでしょうが、CPUをガンガン使うので熱を気にしながらやってください。

# source build/envsetup.sh
# m -j5
# sudo ./buildfs.sh