arm なカーネルの DeviceTree を確認すべく (3)

日中もリベンジ対応ってことでスキマで云々。

とりあえず

debootstrap に --arch というオプションがあるらしいので以下。

$ sudo debootstrap \
        --arch=armel \
        --keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg \
        --verbose \
        --foreign \
        precise \
        ./

これで処理が開始されている模様。

debootstrap 終了

nfs-kernel-server 再起動して qemu 起動してみたのですがやはり kernel panic します。ただし朝とちょっぴり状況は変わってて、_not syncing: Attempted to kill init!_というナニになってます。
色々確認するに CONFIG_AEABI なコンパイルスイッチが云々という情報あり。

がしかし確認してみたところ、無問題。

$ grep AEABI .config
CONFIG_AEABI=y
$

色々微妙な部分あり。

  • CROSS_COMPILE に指定してるのが arm-linux-gnueabihf- だったり
  • うぶんつな arm のターゲットがどうなのか不明 (今のは、precise で debootstrap してます)

あと起動時に以下な出力がコマンドライン上に出てきてます。qemu が吐いてるものと思われます。

l2x0_priv_write: Bad offset 900
l2x0_priv_write: Bad offset 904
l2x0_priv_write: Bad offset 908
l2x0_priv_write: Bad offset 90c
l2x0_priv_write: Bad offset 910
l2x0_priv_write: Bad offset 914
l2x0_priv_write: Bad offset 918
l2x0_priv_write: Bad offset 91c
l2x0_priv_write: Bad offset 920
l2x0_priv_write: Bad offset 924
l2x0_priv_write: Bad offset 928
l2x0_priv_write: Bad offset 92c
l2x0_priv_write: Bad offset 930
l2x0_priv_write: Bad offset 934
l2x0_priv_write: Bad offset 938
l2x0_priv_write: Bad offset 93c

うーん。

とりあえず

ハロワをコンパイルして実行してみるか。ちなみに /sbin/init の file の結果が以下。

$ file sbin/init
sbin/init: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), \
dynamically linked (uses shared libs), for GNU/Linux 2.6.31, \
BuildID[sha1]=0xc0a7046e446b418f574d0ddb966ce6d2e63f4839, stripped
$

カーネルのバージョンがあからさまに違うんですが。

つうか

カーネルを arm-linux-gnueabihf- で云々してるのが悪い気がしてきた。ケツに hf が付くのって何がどう違うのかとか全然分かってないし。
つうかとりあえずカーネルは作り直そ。あからさまにマズそげ。とりあえず以下。

$ sudo apt-get install gcc-4.6-arm-linux-gnueabi 

で、以下。

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j3

ちょっと gcc-arm-linux-gnueabi パケジの導入云々でハマりました。別途コンパイル完了後のソレは出力の方向にて。

このエントリに

@tetsu_koba さんからフォロー頂きました。曰く、

arm-linux-gnueabihf か arm-linux-gnueabi- はカーネルをビルドするぶんにはあまり関係ありませんね。なぜならカーネルはそれ自身で完結していて、外部のライブラリを使っていないからです。それよりも /sbin/init を逆アセンブルしてみてください。おそらくThumb2でビルドされていると思います。カーネルのコンフィグでThumb2のバイナリを実行できるようにしているかも確認してみてください。

とのこと。ありがとうございます。確認します。

と言いつつ

Thumb2 でビルドされているかどうかの判断記述がアレ。

とりあえづ

再度コメント頂いた以下を参考に

qemu 1.2.0
Linux 3.7-rc7
rootfsはLinaroのnano
qemu-system-arm -nographic -no-reboot -redir tcp:55555::23 -M vexpress-a15 -kernel zImage -dtb vexpress-v2p-ca15-tc1.dtb -m 512 -append ”root=/dev/nfs rw nfsroot=192.168.x.yy:/export/nano/root ip=dhcp console=ttyAMA0”
で無事に起動しました。

Linaro の nano らしきソレを入手し

これを nfs root にして起動してみたところ、init は正常起動しているらしいことは確認できました。
別途以下を確認させて頂く方向で、とりあえず別件フォローに戻ります (ぇ

  • 最初に動作確認してたツリーの init が Thumb2 でビルドされていることの確認
  • カーネル config で Thumb2 バイナリが実行できるようになっているかどうか
  • カーネル作り直して実行できるかどうか確認
  • 入手したソレでも正常起動はしてないので正常動作を確認したい

ともあれ、諸々フォローありがとうございました! > id:embedded さん (@tetsu_koba さん)

追記

現実トウヒとも言います。@tetsu_koba さん tweet にて以下なフォローを頂きました。

ARM命令は32bit固定長。Thumb命令は16bit固定長。Thumb2は32/16混在なので逆アセンブルしたらすぐにわかる。なおarmv7以降のThumbは全てThumb2扱い。

http://twitter.com/tetsu_koba/status/273348447673933824 より引用
Guide to using objdump for disassembly なサイトにて

  • A standard ARM dissassembly for a raw binary file

という項と

  • To get the disassembly to use thumb-mode for the ARM instructions, add -Mforce-thumb

という項がありましたので、それぞれに /sbin/init を吸わせてみました。まずARM 命令なナニが以下。

$ arm-linux-gnueabi-objdump -D --target binary -marm sbin/init

sbin/init:     file format binary


Disassembly of section .data:

00000000 <.data>:
       0:       464c457f                        ; <UNDEFINED> instruction: 0x464c457f

いきなり UNDEFINED なソレが出てきます。以降もぼつぼつ出てきてます。

     1a0:       574d0ddb                        ; <UNDEFINED> instruction: 0x574d0ddb
     1a4:       966ce6d2                        ; <UNDEFINED> instruction: 0x966ce6d2
     1a8:       e63f4839                        ; <UNDEFINED> instruction: 0xe63f4839

次は Thumb 命令なソレ。

$ arm-linux-gnueabi-objdump -D --target binary -marm \
-Mforce-thumb sbin/init

sbin/init:     file format binary


Disassembly of section .data:

00000000 <.data>:
       0:       457f            cmp     r7, pc
       2:       464c            mov     r4, r9
       4:       0101            lsls    r1, r0, #4
       6:       0001            movs    r1, r0
        ...
      10:       0003            movs    r3, r0

命令長が 16bit ですね。こっちは無事かと思いきや、UNDEFINED な出力があります。

     2e6:       de41                            ; <UNDEFINED> instruction: 0xde41
     2e8:       8a4f            ldrh    r7, [r1, #18]
     2ea:       9340            str     r3, [sp, #256]  ; 0x100
     2ec:       af00            add     r7, sp, #0
     2ee:       e834 7879                       ; <UNDEFINED> instruction: 0xe8347879

ということで 16bit/32bit な命令が混在しているということで、Thumb2 な命令が使われている、という結論を下すことができる模様です。

ちなみに

arm の thumb なソレって色々な意味でぼんやりとしか認識できてなかったりしてorz
と、ゆーことでコンパイルスイッチ的に以下らしいので

# CONFIG_THUMB2_KERNEL is not set

こいつを云々して動作確認してみたいと思います。あと手元に arm-none-linux-gnueabi-gdb があるみたいなので起動直後らへんのソレを確認してみたいと。