はじめに
YoctoProjectでinitramfs入門でinitramfsの使用方法を調査した。今回は実機環境でinitramfsを使用してみる。
ターゲットはラズベリーパイ4。使用するブランチはkirkstone。
環境構築
作業環境
$ mkdir -p ~/yocto/rpi-kirkstone $ cd ~/yocto/rpi-kirkstone
pokyの取得
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
環境変数の設定
$ source poky/oe-init-build-env
meta-raspberrypiの取得
$ bitbake-layers layerindex-fetch meta-raspberrypi
local.confを編集
meta-raspberrypiでinitramfsをバンドルしたカーネルを作成するための設定はmeta-raspberrypi/docs/extra-build-config.md
に下記のように記載されている。
## Image with Initramfs To build an initramfs image: * Set this 3 kernel variables (in kernel's do_configure:prepend in linux-raspberrypi.inc after the line kernel_configure_variable LOCALVERSION "\"\"" ) - kernel_configure_variable BLK_DEV_INITRD y - kernel_configure_variable INITRAMFS_SOURCE "" - kernel_configure_variable RD_GZIP y * Set the yocto variables (e.g. in local.conf) - `INITRAMFS_IMAGE = "<name for your initramfs image>"` - `INITRAMFS_IMAGE_BUNDLE = "1"` - `BOOT_SPACE = "1073741"` - `INITRAMFS_MAXSIZE = "315400"` - `IMAGE_FSTYPES_pn-${INITRAMFS_IMAGE} = "${INITRAMFS_FSTYPES}"`
これを参考にlocal.confに設定を追加する。kernel_configure_variableについては追加の作業は不要のようだ。
conf/local.conf
に下記の部分を追加
MACHINE = "raspberrypi4-64" DL_DIR = "${TOPDIR}/../downloads" # enable uart ENABLE_UART = "1" # systemd DISTRO_FEATURES:append = " systemd" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" # Bundle initramfs INITRAMFS_IMAGE = "core-image-minimal-initramfs" INITRAMFS_IMAGE_BUNDLE = "1" BOOT_SPACE = "1073741" INITRAMFS_MAXSIZE = "315400" IMAGE_FSTYPES_pn-${INITRAMFS_IMAGE} = "${INITRAMFS_FSTYPES}" # fallbackto shell in the initramfs INITRAMFS_SCRIPTS = "\ initramfs-framework-base \ initramfs-module-debug \ " CMDLINE_DEBUG = "debug shell"
INITRAMFS_IMAGEは前回と同様にcore-image-minimal-initramfs
を使用する。
INITRAMFS_SCRIPTS
でモジュールを設定。CMDLINE_DEBUG
でカーネルのブートパラメータを追加している。
使用するカーネルイメージの変更
例によってこのままでは、initramfsをバンドルしたカーネルイメージが作成されるようになるだけで、 wicによって作成されるイメージにはそれは適用されない。
meta-raspberrypiのカーネル
bitbakeで生成されるカーネルイメージは下記のようになっている。
$ pushd ./tmp/deploy/images/raspberrypi4-64/ $ ls -lha Image* lrwxrwxrwx 2 mickey mickey 80 1月 6 02:08 Image -> Image-1-5.15.34+git0+e1b976ee4f_0086da6acd-r0-raspberrypi4-64-20230105170742.bin -rw-r--r-- 2 mickey mickey 24M 1月 6 02:08 Image-1-5.15.34+git0+e1b976ee4f_0086da6acd-r0-raspberrypi4-64-20230105170742.bin -rw-r--r-- 2 mickey mickey 36M 1月 6 02:08 Image-initramfs-1-5.15.34+git0+e1b976ee4f_0086da6acd-r0-raspberrypi4-64-20230105170742.bin lrwxrwxrwx 2 mickey mickey 90 1月 6 02:08 Image-initramfs-raspberrypi4-64.bin -> Image-initramfs-1-5.15.34+git0+e1b976ee4f_0086da6acd-r0-raspberrypi4-64-20230105170742.bin lrwxrwxrwx 2 mickey mickey 80 1月 6 02:08 Image-raspberrypi4-64.bin -> Image-1-5.15.34+git0+e1b976ee4f_0086da6acd-r0-raspberrypi4-64-20230105170742.bin
一方で、wicイメージのブートパーティションに書き込まれているカーネルは下記のようになっている。
$ ls -lha | grep kernel -rw-r--r-- 1 mickey mickey 36M 4月 6 2011 kernel8.img
つまり、カーネルイメージはkernel8.img
という名前にリネームしてコピーされるということになる。
meta-raspberrypi/wic/sdimage-raspberrypi.wks
を見るとブートパーティションはbootimg-partition
のソースプラグインを使用していることがわかる。
part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4096 --size 20
このプラグインはIMAGE_BOOT_FILES
変数によって、インストールするファイルを制御している。
meta-raspberrypiのこの変数の定義はmeta-raspberrypi/conf/machine/include/rpi-base.inc
で下記のようになっている。
IMAGE_BOOT_FILES ?= "${BOOTFILES_DIR_NAME}/* \ ${@make_dtb_boot_files(d)} \ ${@bb.utils.contains('RPI_USE_U_BOOT', '1', \ '${KERNEL_IMAGETYPE} u-boot.bin;${SDIMG_KERNELIMAGE} boot.scr', \ '${KERNEL_IMAGETYPE};${SDIMG_KERNELIMAGE}', d)} \ "
実際には下記のように展開される。
$ bitbake -e core-image-minimal | grep '^IMAGE_BOOT_FILES=' IMAGE_BOOT_FILES="bootfiles/* bcm2711-rpi-4-b.dtb bcm2711-rpi-400.dtb bcm2711-rpi-cm4.dtb overlay_map.dtb;overlays/overlay_map.dtb at86rf233.dtbo;overlays/at86rf233.dtbo disable-bt.dtbo;overlays/disable-bt.dtbo dwc2.dtbo;overlays/dwc2.dtbo gpio-ir.dtbo;overlays/gpio-ir.dtbo gpio-ir-tx.dtbo;overlays/gpio-ir-tx.dtbo gpio-key.dtbo;overlays/gpio-key.dtbo gpio-poweroff.dtbo;overlays/gpio-poweroff.dtbo gpio-shutdown.dtbo;overlays/gpio-shutdown.dtbo hifiberry-amp.dtbo;overlays/hifiberry-amp.dtbo hifiberry-dac.dtbo;overlays/hifiberry-dac.dtbo hifiberry-dacplus.dtbo;overlays/hifiberry-dacplus.dtbo hifiberry-digi.dtbo;overlays/hifiberry-digi.dtbo justboom-both.dtbo;overlays/justboom-both.dtbo justboom-dac.dtbo;overlays/justboom-dac.dtbo justboom-digi.dtbo;overlays/justboom-digi.dtbo i2c-gpio.dtbo;overlays/i2c-gpio.dtbo i2c-rtc.dtbo;overlays/i2c-rtc.dtbo imx219.dtbo;overlays/imx219.dtbo imx477.dtbo;overlays/imx477.dtbo iqaudio-dac.dtbo;overlays/iqaudio-dac.dtbo iqaudio-dacplus.dtbo;overlays/iqaudio-dacplus.dtbo mcp2515-can0.dtbo;overlays/mcp2515-can0.dtbo mcp2515-can1.dtbo;overlays/mcp2515-can1.dtbo mcp3008.dtbo;overlays/mcp3008.dtbo miniuart-bt.dtbo;overlays/miniuart-bt.dtbo pitft22.dtbo;overlays/pitft22.dtbo pitft28-capacitive.dtbo;overlays/pitft28-capacitive.dtbo pitft28-resistive.dtbo;overlays/pitft28-resistive.dtbo pitft35-resistive.dtbo;overlays/pitft35-resistive.dtbo pps-gpio.dtbo;overlays/pps-gpio.dtbo rpi-ft5406.dtbo;overlays/rpi-ft5406.dtbo rpi-poe.dtbo;overlays/rpi-poe.dtbo vc4-fkms-v3d.dtbo;overlays/vc4-fkms-v3d.dtbo vc4-fkms-v3d-pi4.dtbo;overlays/vc4-fkms-v3d-pi4.dtbo vc4-kms-v3d.dtbo;overlays/vc4-kms-v3d.dtbo vc4-kms-v3d-pi4.dtbo;overlays/vc4-kms-v3d-pi4.dtbo vc4-kms-dsi-7inch.dtbo;overlays/vc4-kms-dsi-7inch.dtbo w1-gpio.dtbo;overlays/w1-gpio.dtbo w1-gpio-pullup.dtbo;overlays/w1-gpio-pullup.dtbo wm8960-soundcard.dtbo;overlays/wm8960-soundcard.dtbo Image;kernel8.img
Image;kernel8.img
の行が、カーネルイメージのリネームの部分となることがわかる。つまり下記の部分を修正することで、wicイメージに適用されるカーネルイメージを変更することができる。
${@bb.utils.contains('RPI_USE_U_BOOT', '1', \ '${KERNEL_IMAGETYPE} u-boot.bin;${SDIMG_KERNELIMAGE} boot.scr', \ '${KERNEL_IMAGETYPE};${SDIMG_KERNELIMAGE}', d)} \
RPI_USE_U_BOOT
変数によってカーネルをu-bootに差し替えるための分岐があるが、今回はu-bootを使用しないので、この部分は無視できる。
この変数はDEPLOY_DIR内のファイル名;wicイメージ内のファイル名
という記法になっている。
ここでは、DEPLOY_DIRはbuild/tmp/deploy/images/raspberrypi4-64
を指すので、この中にあるinitramfsバンドルのカーネルイメージを指すようにすれば良い。
これらを踏まえるとlocal.conf
でIMAGE_BOOT_FILES
を下記のように設定すれば良いことになる。
IMAGE_BOOT_FILES = "${BOOTFILES_DIR_NAME}/* \ ${@make_dtb_boot_files(d)} \ ${KERNEL_IMAGETYPE}-${INITRAMFS_LINK_NAME}.bin;${SDIMG_KERNELIMAGE} \ "
${KERNEL_IMAGETYPE}-${INITRAMFS_LINK_NAME}.bin
を展開するとImage-initramfs-raspberrypi4-64.bin
になるので、
これがkernel8.img
としてwicイメージに入るようになる。
動作確認
local.confまとめ
最終的にlocal.confのinitramfs関連の設定は下記のようになる。
INITRAMFS_IMAGE = "core-image-minimal-initramfs" INITRAMFS_IMAGE_BUNDLE = "1" BOOT_SPACE = "1073741" INITRAMFS_MAXSIZE = "315400" IMAGE_FSTYPES_pn-${INITRAMFS_IMAGE} = "${INITRAMFS_FSTYPES}" INITRAMFS_SCRIPTS = "\ initramfs-framework-base \ initramfs-module-debug \ " CMDLINE_DEBUG = "debug shell" IMAGE_BOOT_FILES = "${BOOTFILES_DIR_NAME}/* \ ${@make_dtb_boot_files(d)} \ ${KERNEL_IMAGETYPE}-${INITRAMFS_LINK_NAME}.bin;${SDIMG_KERNELIMAGE} \ "
ビルドおよび動作確認
下記でビルドする。
$ bitbake core-image-base
出来上がったwicイメージをSDカードに書き込む。
$ pushd ./tmp/deploy/images/raspberrypi4-64 $ sudo bmaptool copy ./core-image-base-raspberrypi4-64.wic.bz2 /dev/sdX
/dev/sdX
は適宜読み替え。
下記のようにログイン前にshが実行されればinitramfsが動作している。
DEBUG: Loading module debug DEBUG: Running debug_run DEBUG: Calling module hook (post): debug_hook_handler Starting shell after debug... sh: can't access tty; job control turned off / #
まとめ
meta-raspberrypiを使用して、ラズベリーパイ4の実機でもinitramfsを使用できることを確認した。 カーネルイメージにinitramfsをバンドルしてしまえば、config.txtなどに追加の設定を行う必要もなく、 initramfsを使用できることがわかった。