はじめに
MACHINE="qemuarm64"などでイメージを作成すると、実機を用意しなくてもYoctoProjectを試せるので便利。 ただ、複数のパーティションを使用したり、ストレージを追加したい場合にぱっとやり方がわからない。 手順を調査したのでメモ。
今回は、ディスクイメージファイルを作成しqemuにデバイスを追加する方法とwicを使用してパーティションを追加する方法を記す。
環境構築
ソース取得
$ git clone git://git.yoctoproject.org/poky.git -b kirkstone
環境変数設定
source poky/oe-init-build-env
local.conf
下記の内容をconf/local.conf
に追加
MACHINE = "qemuarm64"
ビルド
$ bitbake core-image-minimal
qemuの起動
下記のコマンドでqemuを起動できる。
nographic
を指定することで、端末の中で起動することができる。VMの出力はシリアルコンソールとして扱われる。
qemu上の文字列などをコピペしたいときなどは便利。
$ runqemu nographic
実際にqemuを起動するにはデバイス構成や、使用するカーネルなど様々な設定をコマンドラインで渡す必要がある。
bitbakeでqemuのイメージを作成するとbuild/tmp/deploy/images/qemuarm64/core-image-minimal-qemuarm64.qemuboot.conf
というファイルが一緒に生成される。
runqemuで特にオプションが指定されない場合は、このファイルにかかれている情報がqemuに渡されるようになっている。
qemuboot.confの中身
core-image-minimal-qemuarm64.qemuboot.confの内容を見てみる。
[config_bsp] deploy_dir_image = . image_link_name = core-image-minimal-qemuarm64 image_name = core-image-minimal-qemuarm64-20230811074446 kernel_imagetype = Image machine = qemuarm64 qb_cmdline_ip_slirp = ip=dhcp qb_cmdline_ip_tap = ip=192.168.7.@CLIENT@::192.168.7.@GATEWAY@:255.255.255.0::eth0:off:8.8.8.8 qb_cpu = -cpu cortex-a57 qb_cpu_kvm = -cpu host -machine gic-version=3 qb_default_fstype = ext4 qb_default_kernel = ${@bb.utils.contains("INITRAMFS_IMAGE_BUNDLE", "1", "Image-${INITRAMFS_LINK_NAME}.bin", "Image", d)} qb_drive_type = /dev/sd qb_graphics = -device virtio-gpu-pci qb_machine = -machine virt qb_mem = -m 256 qb_network_device = -device virtio-net-pci,netdev=net0,mac=@MAC@ qb_opt_append = -device qemu-xhci -device usb-tablet -device usb-kbd -echr 0x14 qb_rng = -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 qb_rootfs_extra_opt = qb_rootfs_opt = -drive id=disk0,file=@ROOTFS@,if=none,format=raw -device virtio-blk-pci,drive=disk0 qb_serial_opt = -device virtio-serial-pci -chardev null,id=virtcon -device virtconsole,chardev=virtcon qb_smp = -smp 4 qb_system_name = qemu-system-aarch64 qb_tap_opt = -netdev tap,id=net0,ifname=@TAP@,script=no,downscript=no qb_tcpserial_opt = -device virtio-serial-pci -chardev socket,id=virtcon,port=@PORT@,host=127.0.0.1 -device virtconsole,chardev=virtcon serial_consoles = 115200;ttyAMA0 115200;hvc0 staging_bindir_native = ../../../work/x86_64-linux/qemu-helper-native/1.0-r1/recipe-sysroot-native/usr/bin staging_dir_host = ../../../work/qemuarm64-poky-linux/core-image-minimal/1.0-r0/recipe-sysroot staging_dir_native = ../../../work/qemuarm64-poky-linux/core-image-minimal/1.0-r0/recipe-sysroot-native tune_arch = aarch64 uninative_loader = ../../../sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2
メインとなるストレージを指定しているのは以下の部分
qb_rootfs_opt = -drive id=disk0,file=@ROOTFS@,if=none,format=raw -device virtio-blk-pci,drive=disk0
ディスクドライブの指定方法はこれを参考にすれば良さそう。
ストレージの追加を試みる
ディスクイメージファイルの作成
下記のコマンドを実行し、${DEPLOY_DIR_IMAGE}の変数が指す場所にディスクイメージとなるファイルを作成する。
$ pushd ./tmp/deploy/images/qemuarm64/ $ fallocate -l 1G disk.img
qemuboot.confの直接編集
core-image-base-qemuarm64.qemuboot.conf
の内容を修正しディスクを追加する。
ディスク指定は汎用的なオプション追加のためのqb_opt_append
で行う。
qb_opt_append = -drive id=disk1,file=@DEPLOY_DIR_IMAGE@/disk.img,if=none,format=raw -device virtio-blk-pci,drive=disk1
runqemuではqb_opt_append
を処理する際に「@DEPLOY_DIR_IMAGE@」を見つけると、 bitbakeで参照される${DEPLOY_DIR_IMAGE}が指すディレクトリのパスに置き換えるようになっている。
qemuを起動し、/dev/vdbが認識されていればストレージの追加は成功となる。
$ runqemu nographic root@qemuarm64:~# ls /dev/vd* /dev/vda /dev/vdb
ただし、ストレージデバイスが追加されただけなので、ファイルシステムの作成(mkfs)やマウントなどは手動で行う必要がある。
また、この方法では次回bitbake実行時にこの内容は破棄されてしまう。
local.confでの設定
ディスクイメージファイルを作成した状態でlocal.conf
に下記の内容を記載する。
QB_OPT_APPEND:append = " -drive id=disk1,file=@DEPLOY_DIR_IMAGE@/disk.img,if=none,format=raw -device virtio-blk-pci,drive=disk1"
これでbitbakeをするたびに追加したストレージが認識しなくなることは避けられる。
qemuでwicを使用する
ストレージを追加する方法では、以下のことを自分で行う必要がある。
- ファイルシステムの作成(mkfs)
- マウント(mountコマンドの実行や/etc/fstabの修正)
これは意外と面倒な作業となる。
ディスクイメージを追加することにこだわらずにパーティションを追加するだけであればwicを使用する方法もある。 この場合、qemu上で/dev/vdbは存在しないが、/dev/vdaがパーティション分割された状態で認識されるようになる。
作業用レイヤの作成
下記のコマンドで作業用レイヤを作成する。
$ bitbake-layers create-layer ./meta-wic-work $ bitbake-layers add-layer ./meta-wic-work
wksファイルの作成
下記のコマンドでwksの格納場所を作成する。
$ mkdir ./meta-wic-work/wic
meta-wic-work/wic/qemu-wic.wks
を下記の内容で作成する。
part / --source rootfs --ondisk vda --fstype=ext4 --label platform --align 1024 part /opt --fstype=ext4 --ondisk vda --label opt --fixed-size=1G
bbclassファイルの作成
qemuがqemu-wic.wksを参照し、wicイメージを出力するための設定と、ルートFS上に/opt
ディレクトリを作成する、qemu-wic.bbclassを作成する。
下記のコマンドでbbclassの格納場所を作成する。
$ mkdir ./meta-wic-work/classes
meta-wic-work/classes/qemu-wic.bbclass
を下記の内容で作成する。
ROOTFS_POSTPROCESS_COMMAND += "create_opt_dir;" QB_FSINFO = "wic:no-kernel-in-fs" QB_KERNEL_ROOT = "/dev/vda1" QB_DEFAULT_FSTYPE = "wic" WKS_FILE = "qemu-wic.wks" IMAGE_FSTYPES += "wic" create_opt_dir() { mkdir ${IMAGE_ROOTFS}/opt }
local.confの修正
local.confに下記の内容を追加する。
INHERIT += "qemu-wic"
また、QB_OPT_APPEND:appendの行は不要なので削除する。
イメージのビルド及び動作確認
下記コマンドでイメージをビルドしなおす。
$ bitbake core-image-minimal -c cleansstate $ bitbake core-image-minimal
動作確認
$ runqemu nographic
qemu上で下記を実行し/dev/vda2
が/opt
としてマウントされていることを確認する。
root@qemuarm64:~# mount /dev/root on / type ext4 (rw,relatime) devtmpfs on /dev type devtmpfs (rw,relatime,size=116500k,nr_inodes=29125,mode=755) proc on /proc type proc (rw,relatime) sysfs on /sys type sysfs (rw,relatime) debugfs on /sys/kernel/debug type debugfs (rw,relatime) tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755) tmpfs on /var/volatile type tmpfs (rw,relatime) /dev/vda2 on /opt type ext4 (rw,relatime) devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=000)
ついでにqemu上の/etc/fstab
の内容も確認する。
root@qemuarm64:~# cat /etc/fstab # stock fstab - you probably want to override this with a machine specific one /dev/root / auto defaults 1 1 proc /proc proc defaults 0 0 devpts /dev/pts devpts mode=0620,ptmxmode=0666,gid=5 0 0 tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0 tmpfs /var/volatile tmpfs defaults 0 0 # uncomment this if your device has a SD/MMC/Transflash slot #/dev/mmcblk0p1 /media/card auto defaults,sync,noauto 0 0 /dev/vda2 /opt ext4 defaults 0 0
まとめ
今回は、下記の2つの方法でqemuのストレージを拡張する方法を調べた。
どうしてもディスクデバイスを増やしたい理由がなければwicを使用してパーティションを追加する方法が手軽。 さりげにbbclassの作成方法にも軽く触れておいたので参考になれば。