qemu-arm-static
ARM用のOpenBSDがQEMUで動かないか、調べていたんだ。だって、前回ソース見たら、 動くような事が書いてあった。でも、全くHitしない。そんな馬鹿な事を考えるの おまえぐらいだよーって態度。
でも、検索の途中で面白い物に出くわした。
Raspberry Pi用バイナリをQEMUエミュレータで動かす方法(ユーザーモードエミュレーション
普通ラズパイを動かすには、qemu-system-armを使って(但し、貧乏人用)カーネル から動かすけど、そんな事やってたら、遅くなるじゃん。素のカーネルを使わなければ 、結構早く動くよって事らしい。面白そうなので、追試してみる。(科学は、追試 して再現性が得られて、進歩した)
まずは、http://downloads.raspberrypi.org/raspbian/images/へ行って、必要なのを落としてくる。 回線が細いので、気長に待つ。
sakae@ub:~/ARM-rp$ ls -l -rw-r--r-- 1 sakae sakae 2962227200 Jan 7 2014 2014-01-07-wheezy-raspbian.img -rw-rw-r-- 1 sakae sakae 817931404 Jan 9 2014 2014-01-07-wheezy-raspbian.zip
zipファイルは、unzipすると4倍近く、膨れあがるのね。最新なのが、zipで1.3Gも 有ったから、膨らませると、5Gを超えるのな。
後は、指示書通りに、マウントポイント、rootfsを作成。fdiskで、imgがどうなって いるか確認。
sakae@ub:~/ARM-rp$ mkdir rootfs sakae@ub:~/ARM-rp$ fdisk -l 2014-01-07-wheezy-raspbian.img Disk 2014-01-07-wheezy-raspbian.img: 2.8 GiB, 2962227200 bytes, 5785600 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x000981cb Device Boot Start End Sectors Size Id Type 2014-01-07-wheezy-raspbian.img1 8192 122879 114688 56M c W95 FAT32 2014-01-07-wheezy-raspbian.img2 122880 5785599 5662720 2.7G 83 Linux
Linuxの始まる場所は、122880x512って事なんで、それだけずらした場所をrootfsに マウント。凄い方法だな。そして、そこへqemu-arm-staticを転送。 ld.so.preloadを無効化するとな。
sakae@ub:~/ARM-rp$ sudo mount -o offset=62914560 2014-01-07-wheezy-raspbian.img rootfs sakae@ub:~/ARM-rp$ sudo cp /usr/bin/qemu-arm-static rootfs/usr/bin/ sakae@ub:~/ARM-rp$ sudo sed -i 's/^/#/' rootfs/etc/ld.so.preload
そして、使う石を指示する為、環境変数をセットして、監獄へと入って行く。
sakae@ub:~/ARM-rp$ sudo QEMU_CPU=arm1176 chroot rootfs root@ub:/# uname -a Linux ub 4.4.0-34-generic #53-Ubuntu SMP Wed Jul 27 16:06:28 UTC 2016 armv6l GNU/Linux root@ub:/# df /bin/df: cannot read table of mounted file systems: No such file or directory root@ub:/# ps awx Error: /proc must be mounted To mount /proc at boot you need an /etc/fstab line like: proc /proc proc defaults In the meantime, run "mount proc /proc -t proc" root@ub:/# exit exit
armな石が動いている事は分かるけど、難しい事は、出来ないみたい。armな世界から、 現実の糞石世界に戻るには、監獄から脱獄する事です。老いたら、三食、介護付きの 監獄に入るのも手、かもよ。
何はともあれ、apt-get updateだな。始めたら、こんなエラーを喰らった。
Try running the command gdk-pixbuf-query-loaders > /usr/lib/arm-linux-gnueabihf/gdk-pixbuf-2.0/2.10.0/loaders.cache to make things work again for the time being. Processing triggers for shared-mime-info ... Errors were encountered while processing: /var/cache/apt/archives/wolfram-engine_10.0.2+2015020304_armhf.deb E: Sub-process /usr/bin/dpkg returned an error code (1)
sakae@ub:~/ARM-rp$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 13797456 7938772 5134768 61% / : /dev/loop0 2721336 2627768 0 100% /home/sakae/ARM-rp/rootfs
disk-fullになったんだな。wolfram-engineって馬鹿でかいパッケージだったけど、 お前な何者? 調べてみたら、 Raspberry Pi で Wolfram Language & Mathematica を起動する こういう代物らしい。
使う事もなさそうなので、removeしてDiskの空きを作っておいた。(dfが動かないので 半信半疑ですけどね)
sakae@ub:~/ARM-rp$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 13797456 7938776 5134764 61% / /dev/loop0 2721336 1797644 765740 71% /home/sakae/ARM-rp/rootfs
ああ、親側のdfで代用出来る和。いらない物を消したら、空き地が広がったな。 ちゃんとupdateも出来たし。
sudo raspi-config
とかやると、色々設定出来るらしい。気分はラスビアン?
7 Overclock Configure overclocking for your P 8 Advanced Options Configure advanced settings
はやり、ハードがらみと言うと、オーバークロックが出てくるなあ。8番メニューは sshとかspi,i2cとかの、ハードに使う人用のメニューが並んでいた。
後、参考になりそうなのを挙げておこう。
chrootする前にprocをマウントしとく作戦
$ sudo mount /proc /export/debian_lenny_armel/root/proc -t proc $ sudo chroot /export/debian_lenny_armel/root /bin/bash # ls /proc 1 19631 20 29580 30116 45 8 mdstat 10 19634 20432 29602 30131 48 9 meminfo 1064 19640 21 29779 30132 49 904 misc
DockerでユーザモードQEMUによるARMエミュレーション環境を構築する
余りrootでばかり作業してても、あれ なんで、pi さんになってみる。
root@ub:/# su pi pi@ub / $ cd pi@ub ~ $ ls Desktop ocr_pi.png python_games pi@ub / $ dpkg -l | wc 807 7892 110153 pi@ub ~ $ exit exit root@ub:/#
簡単にarm環境を作る
ARM/BuildEABIChroot - Ubuntu Wiki
これも面白そうなんで試してみる。案内の通りにやったら、ボケ、debootstrap なんて 入っていないわいって言われたので、慌てて入れた。後は、
sudo qemu-debootstrap --arch armhf vivid eabi-chroot
するだけで、ミニマムなシステムがインストールされた。大体200Mぐらいだったよ。 起動は、
sudo chroot eabi-chroot
rootしかユーザーが居ないので、useradd -m sakae して、一般ユーザーを 作っておいた。その後、build-essential gdb emacs24-nox を追加した。 この時点で、
sakae@ub:~$ sudo du -sh eabi-chroot/ 439M eabi-chroot/
duするのに、なんでsudoの必要が有るか? rootの壁でしっかり覆われているので、 中を確認するには、権限が必要なのさ。正に監獄。FreeBSD風に言うと、jailです。
どんな監獄を作れるかと言うと、今の所
amd64) qemu_arch="x86_64" ;; armel|armhf) qemu_arch="arm" ;; arm64) qemu_arch="aarch64" ;; lpia) qemu_arch="i386" ;; powerpc|powerpcspe) qemu_arch="ppc" ;; ppc64el) qemu_arch="ppc64le" ;;
こういうのを作れるようです。ラッパーにそう記されていた。 それはいいんだけど、どういう仕組みで動いているの? 大体、/bootの下が 空っぽなんですけど。
ラッパースクリプトの最後がこうなってた。
eval run debootstrap --arch "$deb_arch" --foreign $opts $args mkdir -p "$target/usr/bin" cp $(which "qemu-$qemu_arch-static") "$target/usr/bin" run chroot "$target" /debootstrap/debootstrap --second-stage
debootstrapスクリプトを使って、欲しいarchのパッケージを取り寄せる。 指定したtargetって言うdirの中に/usr/binを作る。だから、外側ばrootの壁に なるんだな。
それから、qemu_xxx_static を、コピーする。そして、chrootで指定したdir中の debootstrapスクリプトを後処理用に起動するとな。 この環境は、pkgの試験用に使うものらしい。
で、どうやって起動する? まずは、chrootだな。chrootは、第一引数のdirをroot-dirと看做して、コマンドを 実行する。コマンドが指定されていなかったら、/bin/shをインタラクティブ・ シェルとして、隔離された環境で実行する。
7659 pts/3 S 0:00 sudo chroot eabi-chroot/ 7660 pts/3 Sl+ 0:00 /usr/bin/qemu-arm-static /bin/bash -i
うん、マニュアル通りだ。そうすると、bashとqemu-arm-staticの関係は?
root@ub:/# uname -m armv7l root@ub:/# file /bin/bash /bin/bash: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=46943cea38a62570a7f7878d1ccc881fa8e29942, stripped root@ub:/# ldd /bin/bash libtinfo.so.5 => /lib/arm-linux-gnueabihf/libtinfo.so.5 (0x40830000) libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x4085a000) libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x4086d000) /lib/ld-linux-armhf.so.3 (0x40000000)
bashの起動を指示されたはずなのに、何故qemuが動いているのだろう?それより、 bashは、誰が起動してる? 普通に考えれば、カーネルだけど、この場合は そんなの動いていない。
ちょっと実験で、arm環境の中の、qemu-arm-staticをrenameする。そして起動。
sakae@ub:~$ sudo chroot eabi-chroot/ chroot: failed to run command ‘/bin/bash’: No such file or directory sakae@ub:~$ sudo chroot eabi-chroot/ root@ub:/# exit exit
renameしてあると、bashが無いぞエラーで起動失敗。元に戻すと、何喰わぬ顔して 起動成功。
更にしつこく、qemuの実行属性を落としてみると、
root@ub:~# chroot eabi-chroot/ chroot: failed to run command ‘/bin/bash’: Permission denied
まるで、qemu-arm-staticとbashは、一心同体のようだ。qemuは出身が卑しい糞石族、 bashは、ARMなんて言う英国生まれの高貴な族。それが何で癒着してる?
今の予測では、chrootした先の実行しようとしたバイナリー(bash)が、ネイティブな (i386)ものじゃ無い場合、気を利かせて、qemu-arm-static経由で起動するように なってるのかな。だったら、qemu-arm-staticが無いぞとか、属性が落ちてるぞと chrootが報告しても 良さそうなものに。さあ、どうする?
こういう時は、密会現場を押さえるために、探偵を雇って尾行させればいいのかな。 まずは、失敗する条件で、早く落ちて貰おう。
root@ub:~# strace chroot eabi-chroot/ 2>LOG
execve("/usr/sbin/chroot", ["chroot", "eabi-chroot/"], [/* 23 vars */]) = 0 : getcwd("/home/sakae", 4096) = 12 lstat64("/home/sakae/eabi-chroot", {st_mode=S_IFDIR|0755, st_size=4096, ...}) =0 chroot("eabi-chroot/") = 0 chdir("/") = 0 execve("/bin/bash", ["/bin/bash", "-i"], [/* 23 vars */]) = -1 EACCES (Permission denied)
これを見る限り、何ら不審な点は無いな。chrootコマンドが発行されて、それが実行 された。そして、/bin/bashを起動しようとして、失敗。実行属性が無いとな。
ちゃんと動くように設定してからstraceさせると、長い長いログが採取出来た。 んでもって、qemuが含まれるかログ検査。
root@ub:~# grep qemu GOOD open("/etc/qemu-binfmt/arm", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
怪しげなのが有るなあ。ああ、ファイル自体は、存在しないけど。。。 藁にもすがる思いで、qemu-binfmtって何ですかって訪ねてみたら、 QEMUのもうひとつの使い方: ユーザーモードエミュレーションとbinfmtとchrootの組み合わせ なんていう素晴らしい記事を紹介された。
カーネルが余計な口出しして、間に変換器を挟みこめるようなしかけが有るのね。 それを使ってるって訳か。
sakae@ub:~$ update-binfmts --display|grep arm qemu-arm (enabled): interpreter = /usr/bin/qemu-arm-static qemu-armeb (enabled): interpreter = /usr/bin/qemu-armeb-static sakae@ub:~$ update-binfmts --display qemu-arm qemu-arm (enabled): package = qemu-user-static type = magic offset = 0 magic = \x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00 mask = \xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff interpreter = /usr/bin/qemu-arm-static detector =
qemu-user-staticを入れると、カーネルにフックを設定出来る。そして今は、それが 有効になってる。
実行対象のファイルの冒頭から、マジックコードを見ていって、一致してたら、 インタープリターとして、qemu-arm-static上で、実行対象を走らせろ。
root@ub:~# od -t x1z eabi-chroot/bin/bash | head -2 0000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 >.ELF............< 0000020 02 00 28 00 01 00 00 00 b1 aa 02 00 34 00 00 00 >..(.........4...<
Linuxは、節操が無いと言うか、便利ならそれでいいじゃんって態度が素敵。 ああ、分かってほっとしたよ。
FreeBSDとかは、こういう節操の無い事をやってるのかなあ。後で調べてみよう。 それより先に、将来入る(かも知れない)jailの作法を身に付けておくかな。
複数バージョンのFreeBSDをJailで共有させる方法、なんてのが入門には良さそう。
なんせ、FreeBSDでjailがサポートされた時、真っ先に飛びついて、大変な思いを した記憶が有りますから。