ここでは QEMUを立ち上げて devicetree を取り出して、再度 QEMU に与えてみます。QEMU はオプションに合わせて devicetree を動的に作るので、最初に固定構成で試してみます。取り出したソースを書き換えることで、機能を試してみることもできます。
devicetree を取り出す
まずは QEMU で kernel を普通に起動します。kernel と rootfs はそれぞれ準備して置きます。
./qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 4096 -nographic \ -kernel linux/arch/arm64/boot/Image.gz \ -initrd buildroot.cpio.uboot \ -append "ip=10.0.2.15:10.0.2.2:10.0.2.2:255.255.255.0"
QEMU は与えられたオプションを元に devicetree を動的に生成するので、構成を決めてオプションとして与えておきます。ここでは、Cortex-A57 4core + 4GB DRAM とします。
devicetree のバイナリファイル (blob) は /sys/firmware/fdt にあります。これを取り出して host に保存します。
# mount -t nfs -o nolock <hostip>:/home/<user> /mnt # cp /sys/firmware/fdt /mnt/ # umount /mnt
ソースに変換
このバイナリファイル (blob) を QEMU の入力にできそうですが、参照がうまくいかないようなので、host PC に持ってきたバイナリファイルをソースファイルに変換します。
$ dtc fdt > qemu.dts
devicetree ソースに変換できました。このままでは可読性が低いので、気になる場合は phandle はラベルに置き換えるのがよいでしょう(ここは手動で)。例えば、以下のような割込みコントローラ定義がある場合、
/ { interrupt-parent = <0x8005>; ... intc@8000000 { phandle = <0x8005>;
次のように置き換えます (頑張れば自動でできそうですが)。
/ { interrupt-parent = <&intc>; ... intc: intc@8000000 {
再度、devicetree ソースをバイナリファイルに変換します。
$ dtc qemu.dts > qemu.dtb
QEMU に入力します。ただし devicetree が構成を決めるわけではないので、オプションは同じように指定する必要があります。"-append" については devicetree のものが使われるため省略可能です。
./qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 4096 -nographic \
-kernel linux/arch/arm64/boot/Image.gz \
-initrd buildroot.cpio.uboot \
-dtb qemu.dtb
何の役に立つのか?
単に取り出したものを入力するだけでは何も変わらないのですが、例えば PHRAM のようにデバイスに依らない機能はこの devicetree で領域を予約することで動作を確認することができます。
また、QEMU のオプションを変えることで devicetree の中身が変わるので、devicetree の意味を理解することにも使えそうです。
コメント