みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoProject u-bootのブートスクリプトを使う

はじめに

u-bootではシステム起動時に決まった順番で処理を自動実行させるために boot.scrやuEnv.txtなどのブートスクリプトを使用することができる。

extlinux.confではカーネルやデバイスツリー、initramfsなどを任意のものに差し替えることはできるが、 それ以外のことはできない。

u-boot自体はデバイスの初期化やネットワーク設定、メモリの読み書きなど様々なことが実行できるようになっている。 通常それらを行う場合はu-bootのコンソールを使用し、コマンドを入力していく。 ブートスクリプトはファイルに予めコマンド列を記述しておくことでそれらの処理を自動的に実行させることができる。

extlinux.confと比較すると、より細かい作業を自動化することができる。

uEnv.txt vs boot.scr

uEnv.txtとboot.scrは基本的に同じ目的で存在している。

uEnv.txtはコマンド列を記述したテキストファイルをそのまま配置すればよく手軽である反面、 すでにdeprecatedとなっており、新規での使用は推奨されない。また、新し目のu-bootではすでに使用不可になっている。

推奨されるのはboot.scrだが、こちらは素となるテキストファイルをmkimageによって変換する必要がある。

# ./tools/mkimage -c none -A arm -T script -d autoboot.cmd boot.scr

YoctoProjectのboot.scr

meta-raspberrypiのアプローチ

先述の通り、boot.scrを作成するにはmkimageによる変換が必要であるため、meta-raspberrypiではrpi-u-boot-scr.bbというレシピが存在しており、その中で次のような処理を行っている。

do_compile() {
    sed -e 's/@@KERNEL_IMAGETYPE@@/${KERNEL_IMAGETYPE}/' \
        -e 's/@@KERNEL_BOOTCMD@@/${KERNEL_BOOTCMD}/' \
        "${WORKDIR}/boot.cmd.in" > "${WORKDIR}/boot.cmd"
    mkimage -A ${UBOOT_ARCH} -T script -C none -n "Boot script" -d "${WORKDIR}/boot.cmd" boot.scr
}

boot.scrを使うだけで、この様なレシピを毎回作成するのは結構面倒な作業と感じてしまう。 実は最近のYoctoProjectのバージョンでは、boot.scrに関する機能が強化され、u-bootにbbappendを作成するだけでboot.scrを作成できるようになっている。

boot.scrの作成手順

作業用レイヤの作成

作業用にmeta-workを作成する。

$ bitbake-layers create-layer -p 20 meta-work
$ bitbake-layers add-layer ./meta-work

boot.cmdの作成

u-bootで自動化したいコマンド列を記述したファイルをboot.cmdという名前で作成する。

setenv bootargs "root=/dev/mmcblk0p2 rootwait rw debug console=${console},${baudrate}";
fatload mmc 0:1 ${loadaddr} zImage;
fatload mmc 0:1 ${fdtaddr} am335x-boneblack.dtb;
bootz ${loadaddr} - ${fdtaddr}

あまり意味はないが、例としてBeagleBone Blackで、カーネル、デバイスツリーを読み込みLinuxを起動する処理を記述している。

bbappendの作成

レシピはrecipetoolを使用して作成できる。

$ recipetool appendsrcfile -W ./meta-work virtual/bootloader ./boot.cmd
$ recipetool setvar -r ./meta-work/recipes-bsp/u-boot/u-boot_2022.01.bbappend UBOOT_ENV boot
$ recipetool setvar -r ./meta-work/recipes-bsp/u-boot/u-boot_2022.01.bbappend UBOOT_ENV_SUFFIX scr

実際に作成されたファイルは次のようになっている。スカスカなので公開する場合などは筆者はエディタで整形したりする。

SRC_URI += "file://boot.cmd"

FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"

UBOOT_ENV = "boot"

UBOOT_ENV_SUFFIX = "scr"

これでbitbakeを実行するとtmp/deploy/images/beaglebone-yocto/boot.scrが作成される。 fileコマンドで確認するとブートスクリプトが作成されていることがわかる。

$ flie -L tmp/deploy/images/beaglebone-yocto/boot.scr
tmp/deploy/images/beaglebone-yocto/boot.scr: u-boot legacy uImage, , Linux/ARM, Script File (Not compressed), 212 bytes, Mon Jan 10 18:46:34 2022, Load Address: 00000000, Entry Point: 00000000, Header CRC: 0X25DA2A0B, Data CRC: 0X95AF300C

wicイメージに含めるためにlocal.confに下記を追加する。

IMAGE_BOOT_FILES:append = " \
    boot.scr \
"

beaglebone-yoctoの実機で試す場合

beaglebone-yoctoで試す場合は、extlinux.confの生成を回避するために--sourceparams="loader=u-boot"を削除したwksを使用する必要がある。

具体的な手順は下記。

$ mkdir meta-work/wic
$ cat << 'EOF' > meta-work/wic/beaglebone-yocto-wo-extlinux.wks
part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4 --fixed-size 32 --use-uuid
part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root --align 4 --use-uuid
bootloader --append="console=ttyS0,115200"
EOF
$ echo 'WKS_FILE = "beaglebone-yocto-wo-extlinux.wks"' >> conf/local.conf

詳細は前回を参照。

関連する変数

これらの処理はuboot-config.bbclasssu-boot.incで行われる。

実際には下記の変数が関連しているが、UBOOT_ENV_SUFFIXUBOOT_ENVのみ設定すればよい。

# Additional environment variables or a script can be installed alongside
# u-boot to be used automatically on boot.  This file, typically 'uEnv.txt'
# or 'boot.scr', should be packaged along with u-boot as well as placed in the
# deploy directory.  Machine configurations needing one of these files should
# include it in the SRC_URI and set the UBOOT_ENV parameter.
UBOOT_ENV_SUFFIX ?= "txt"
UBOOT_ENV ?= ""
UBOOT_ENV_SRC_SUFFIX ?= "cmd"
UBOOT_ENV_SRC ?= "${UBOOT_ENV}.${UBOOT_ENV_SRC_SUFFIX}"
UBOOT_ENV_BINARY ?= "${UBOOT_ENV}.${UBOOT_ENV_SUFFIX}"
UBOOT_ENV_IMAGE ?= "${UBOOT_ENV}-${MACHINE}-${PV}-${PR}.${UBOOT_ENV_SUFFIX}"
UBOOT_ENV_SYMLINK ?= "${UBOOT_ENV}-${MACHINE}.${UBOOT_ENV_SUFFIX}"

UBOOT_ENV_SUFFIXがscrに設定された場合、mkimageが実行されるようになっている。

    if [ -n "${UBOOT_ENV}" ] && [ "${UBOOT_ENV_SUFFIX}" = "scr" ]
    then
        ${UBOOT_MKIMAGE} -C none -A ${UBOOT_ARCH} -T script -d ${WORKDIR}/${UBOOT_ENV_SRC} ${WORKDIR}/${UBOOT_ENV_BINARY}
    fi

まとめ

  • u-bootでブートスクリプトを使用すると便利
  • uEnv.txtはdeprecated
  • boot.scrはmkimageで作成する必要があるが、YoctoProjectでは比較的簡単に導入できる