2017年2月8日水曜日

ブートイメージからカーネル、rootfs、configを取り出す

image.ub ファイルからカーネル、rootfs、/proc/configを取り出す

SDSoC 2016.3に含まれる ZYBO 向け Software Platform からカーネル、 rootfs、/proc/config を取り出したかったので取り出した。

そもそも image.ub ってなんだ


ARMで使えるブートローダu-bootが扱うイメージフォーマットらしい。

$ mkimage -l image.ub
FIT description: PetaLinux arm uImage with single Linux kernel and FDT blob
Created:         Fri Nov 18 04:07:34 2016
 Image 0 (kernel@1)
  Description:  PetaLinux Kernel
  Created:      Fri Nov 18 04:07:34 2016
  Type:         Kernel Image
  Compression:  gzip compressed
  Data Size:    8747883 Bytes = 8542.85 kB = 8.34 MB
  Architecture: ARM
  OS:           Linux
  Load Address: 0x00008000
  Entry Point:  0x00008000
  Hash algo:    crc32
  Hash value:   252654ca
 Image 1 (fdt@1)
  Description:  Flattened Device Tree blob
  Created:      Fri Nov 18 04:07:34 2016
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    13962 Bytes = 13.63 kB = 0.01 MB
  Architecture: ARM
  Hash algo:    crc32
  Hash value:   66629950
 Default Configuration: 'conf@1'
 Configuration 0 (conf@1)
  Description:  PetaLinux Boot Linux kernel with FDT blob
  Kernel:       kernel@1
  FDT:          fdt@1


カーネルを取り出す


まずこのイメージからカーネルを取り出す。 mkimage -l の結果から gzip compressed であることがわかっているので、 magic を頼りに探すと 240バイト目から gzip データがあることがわかる。 mkimage の結果からファイルは 8747883 バイトであることがわかる。

$ grep -P -a -b  --only-matching $'\x1F\x8B\x08' image.ub
240:

なので

$ dd if=image.ub of=linux.bin.gz bs=1 skip=240 count=8747883
8747883+0 records in
8747883+0 records out
8747883 bytes (8.7 MB, 8.3 MiB) copied, 6.91697 s, 1.3 MB/s

$ file linux.bin.gz
linux.bin.gz: gzip compressed data, was "linux.bin",
  last modified: Thu Nov 17 19:07:33 2016, max compression, from Unix


カーネルの中から gzip データを取り出す


さらにこのアーカイブの中にrootfsが含まれている。cpioフォーマットで入っているかと思い、cpioフォーマットのヘッダである"070707"をgrepしたら発見... と思ったがハズレだった。これはcpioアーカイブじゃなくてcpioアーカイブを探すプログラムが参照している文字列っぽい。ということは...

$ grep -P -a -b  --only-matching $'\x1F\x8B\x08' linux.bin
6278680:
8588960:
9923536:

gzip のヘッダらしきものが3つ見つかった。まずひとつ目は...

$ dd if=linux.bin skip=6278680 bs=1 | gzip -dc > hoge

gzip: stdin: decompression OK, trailing garbage ignored

toor@gpusv:~/zynq7/extract_initramfs$ file hoge
hoge: Linux make config build file, ASCII text

ASCIIだと!?

$ head hoge
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 4.6.0 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_MIGHT_HAVE_PCI=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_NO_IOPORT_MAP=y

...config.gz だった。まあ、ついでなので保存。

$ mv hoge config


では次。

$ dd if=linux.bin skip=8588960 bs=1 | gzip -dc > hoge
gzip: stdin: decompression OK, trailing garbage ignored

toor@gpusv:~/zynq7/extract_initramfs$ file hoge
hoge: ASCII cpio archive (SVR4 with no CRC)

toor@gpusv:~/zynq7/extract_initramfs$ cat hoge | cpio -it | head
cpio: Substituting `.' for empty member name
.
dev
dev/pts
etc
etc/opkg
etc/opkg/arch
etc/rpm
etc/rpm/sysinfo
etc/rpm-postinsts
etc/network

今回は間違いなくinitrdイメージだ。

$ mv hoge initrd


目的な達成したけど、3つめはなんじゃらほい。
dd if=linux.bin skip=9923536 bs=1 | gzip -dc > hoge
gzip: stdin has flags 0xce -- not supported


これは有効なgzipじゃなかった。"070707" 同様に gzip をデコードするルーチンが参照している定数かも。

2017年1月19日木曜日

Oculus Rift CV1 に近視レンズを組み込んだ


Oculus Rift CV1 用のレンズアダプターで近視レンズを組み込んだので、久々にブログにまとめようかと。

皆さんの VR ライフ満喫していますか?

実は... 私はあまり満喫できていませんでした。眼鏡男子の私にとって Oculus Rift CV1 の利用それほど手軽ではなかったからです。

普段、私は乱視矯正・近視矯正の両方が入った眼鏡をかけています。例外的に、冬にスノーボードを楽しむ時にはワンデータイプのコンタクトレンズを使っています。このため、 Oculus Rift CV1 で何か VR コンテンツを楽しむにあたっても、 Lucky's Tale 程度のコンテンツなら裸眼で問題ないとはいえ、 EVE: Valkyrie にょうな UI であったり、細かい文字を読み取らないといけないようなコンテンツではコンタクトレンズを装着しないと楽しめない状況でした。また、私が利用しているのはワンデータイプのコンタクトレンズです。ふらっと Oculus Rift で遊ぶときにワンデーコンタクトを消費するとなると、心理的なハードルはさらに高くなります。

CV1 用レンズアダプターを入手!

そんなことを思っていたら、Oculus Rift CV1 ヘッドセットにメガネ用のレンズを装着し近視矯正を可能にするアダプターの 3D モデルデータを見つけました。

このレンズアダプターは Oculus Rift CV1 にぴったりとはまるようにデザインされていて、レンズには、一般的な眼鏡用のレンズが利用できます。当初より公開されている、オリジナル版のアダプターでは、Zenni Optical の #450021 用に作られた、直径 40mm の円型の眼鏡用レンズを装着できます。

これをどこかでプリントしてもらうか、プリントしてもらうなら送料ケチるために複数オーダーしたほうがいいかなとか色々考えつつ、手を出せていなかったのですが……。もう半年以上前に見つけたこのレンズアダプターですが、最近 3D プリンターを購入したという知人がこのアダプターをプリントしてくれたので、ついに実物を手に入れることができました。


写真は見やすい白い樹脂でプリントしたものを掲載しましたが、実際に CV1 に取り付けたものは黒色のアダプターです。

レンズを入手するための方法は?

そして、次のチャレンジは、「眼鏡のレンズをどうするか」です。今回入手したアダプターは先のとおり Zenni Optical #450021 と互換性があります。このアダプターに対応するレンズを入手する方法として、まずは下記2パターンが考えられます。


  1. 同フレームのみ購入して、レンズは日本で作る
  2. 同フレームとあわせて、レンズも購入する

ずっと悩んでいたのですが、今回は結局、後者「レンズを購入したらフレームもついてくる」という形で入手することにしました。

はじめての通販眼鏡オーダー

次の問題は、いままで眼鏡購入は街のメガネ屋に依頼して作ってもらっていて、通販で眼鏡のレンズなんて買ったことがない、という点です。このため、過去に購入したコンタクトレンズや眼鏡のパラメータを参考にオーダーすることになります。

コンタクトレンズの度数でオーケー

先述のとおり、私は近視矯正用のコンタクトレンズを使用しているので、そのコンタクトレンズを見ることで自分が必要とする近視矯正のパラメータがわかります(というか何百回もコンタクトレンズを使っているので、近視の強さはもう憶えてしまっています)。手元のコンタクトレンズによる近視矯正のパラメータは下記のとおりでした。

  • 左目 -3.25
  • 右目 -2.75

私のコンタクトレンズは乱視矯正タイプではありません。コンタクトレンズは乱視矯正が入るとモノが分厚くなります。個人差がありますが、私の場合、装着感が悪くなり、外れやすくなります。コンタクトレンズを購入するにあたって色々相談したり試した結果、「乱視矯正をせず、近視矯正だけにする」ことにしました(ただし近視矯正を多少強めに入れています)。過去12年ほど、ずっと同じ度数でワンデータイプのコンタクトレンズを使っておりこのコンタクトレンズで遠くにいる仲間の姿、顔や、トラック、遠くの看板など、アウトドアで必要十分な視界が得られることがわかっており、CV1でも問題ありません。このコンタクトレンズと同じ度数の眼鏡レンズを CV1 に入れれば問題ないはずです。

IPDは、眼球と眼球の距離

IPDは左右の眼球の中心の距離を示すパラメータのようです。コンタクトレンズは眼球自体に装着するので IPD の値がわからないのですが、 Ocuus Rift CV1 のセッティングでは 62mm がもっともはっきりして見えるほか、定規で自分の眼球の距離を測ってみてもおよそ 65mm ぐらいでした。「指定できるIPDの値がジャストでない場合は狭い方の値を選べ」ということですし、 CV1 で 62mm という数値が出ていたので、今回は 62mm で作成することにしました。

眼鏡購入時の伝票やカルテからも、必要となる値はわかるはず

眼鏡を持っていても自分の左右の目の矯正パラメータを憶えていることはそうそう無いと思いますが、眼鏡を作ってもらったときの資料が残っていれば、そこに矯正のパラメータが書かれているので、確認することができます。もしくは、眼鏡を作った眼科やお店に問い合わせれば、カルテが残っているはずです。

私がオーダーしたレンズのパラメータは?

先述の近視矯正のみであれば、Zenni Optical の眼鏡オーダー時に下記のパラメータでオーダーすれば十分です。CYL、Axisは乱視矯正の場合のパラメータですので、近視矯正だけの場合はゼロで問題ないのだと思われます。



一般的に眼鏡のレンズは矯正がつよいほどレンズが分厚くなり、高価なレンズほど値段が安くなります。つまり安価なレンズで矯正を強くするとレンズが太くなります。今回、私は 1.57 Mid-Index Single Vision のレンズでオーダーしました。

Oculus Rift CV1への装着感、見え方など含めて、私の度数ではこの設定で特に問題はなさそうです。近視が私より大幅に強い人は、薄い購入レンズを選ぶか悩まれるかもしれません。

コーティングは下記のみにしました。どうせ VR 用ですし。
  • Anti‐Reflection Coating
  • Standard anti‐reflective coating

価格は?

レンズ(+フレーム)代金は14.90ドル、日本への送料が9.95ドルでした。クレジットカードへの最終的な請求金額は下記のとおり、3000円弱でした。



配達されてきた

オーダーしたレンズ(+フレーム)は香港で製造され、日本に向けて出荷されたようです。封筒に眼鏡ケースを入れて送られてきました。(写真は後でとったもので、レンズは取り外し済みです)



ちなみに常用している日本ブランドの眼鏡と比べると、ノーズパッドのは幅に大きな差があります。日本人は鼻が低いですもんねー。



出来上がった眼鏡の状態で見え方に問題がないかを確認しても、とくに問題はありませんでした。

重要! レンズを外す前に

レンズを外す前に、コーティングを痛めないようなメンディングテープや付箋をレンズにはり、上下がわかるようにしておくことをお勧めします。
  • 右目レンズか、左目レンズか
  • レンズのどの部分が上か(円形レンズなので方向がわからなくなる)
特に、乱視矯正レンズだと方向は絶対に大事なので、やはり方向がわからなくならないよう、特に注意してください。

実は、私の場合この眼鏡に対応できる精密ドライバーが手元になかったので、普段お世話になっている眼鏡ショップでレンズを外してもらいました(店舗によっては嫌がられるでしょうから、これが当たり前だとは思わないでください!)。この際、どちらが上であったか等を示す印をつけないまま外してもらった都合、購入時点でどの部分が上だったかは分からなくなっており、反省点です。(IPDがおかしいことになっているかも)

CV1への装着

まず、眼鏡のレンズ2枚を装着します。レンズアダプターに必要以上の力をかけないように注意しながらはめこみます。一度はめ込んでしまえば、アダプターからレンズがすぐにポロッと落ちることはないでしょう。少しゆるく感じるかもしれませんが、CV1に組み込めば、もっと安定します。

CV1の顔に当たるスポンジ部分は、その樹脂フレームと一緒に、Rift本体から分離できます。液晶側(スポンジがついていない方)からレンズアダプタの下のレール部分をはめこみます。

Thingverse に投稿されている写真より

そして、同パーツとレンズアダプタをOculus Rift CV1本体にはめ込めば取り付け完了です。

利用感

映像の見え方としてはバッチリです。

普段利用している眼鏡を外さないといけないのはまだまだ不便ではあるのですが、それでもコンタクトレンズなしで CV1 を装着すれば VR 内で表示された小さな文字まできちんと読めるので大変便利です。実はまだ Touch をオーダーしていないのですが、今後 Touch を入手するのが楽しみになりました。

まとめ

普段から視力矯正が必要な人が VR ヘッドセットをかぶるのはちょっと大変です。でも、 CV1 に今回紹介したレンズアダプター、そして安く作れるレンズを組み合わせることで、 VR ライフがより身近なものになります。

私のような、眼鏡を常用しており、結果として Oculus Rift CV1 から遠ざかってしまっているオーナーの方もいるかと思います。そんな方には本アダプターがとても役にたつかとと思います。