LoginSignup
6

posted at

updated at

KV260 が Linux をブートするまでのシーケンス

KV260 に載っている ZynqMP のブートシーケンスは次の手順で進みます。詳しいことは参考資料「ZynqMPのブートとパワーマネージメント」を参照してください。これは「ZynqMP 勉強会」@Vengineer さんが発表した資料で、ZynqMP のブートシーケンスが詳しく説明されています。

・ステージ0 (内部ROM)

ZynqMP のステージ0ブートローダーは内部ROMにあります。ステージ0ブートローダーは PMU(Platform Management Unit) が実行します。PMU はシステム全体のリソースのパワーアップ、リセットの制御および監視を担当します。PMU はこのため専用のプロセッサで、実態は MicroBlaze という Xilinx が開発したプロセッサのようです。ステージ0ブートローダーは、プライマリブートデバイスにある BOOT.BIN に含まれるステージ1ブートローダー(FSBL) を内部RAMをロードして Coretex-A53 を起動します。

・ステージ1~3 BOOT.BIN (プライマリブートデバイス)

KV260 のプライマリブートデバイスは SOM にある QSPI に接続されたフラッシュメモリです。このプライマリブートデバイスに BOOT.BIN があります。

より正確には KV260 のプライマリーデバイスには先頭アドレスに Image Selector があります。まずこの Image Selector が内部メモリにロードされて Coretex-A53 が実行します。Image Selector の目的は、同じプライマリーデバイスにある2つ(リカバリーを含めると3つ)の BOOT.BIN を選択することです。詳細は『KV260 が Linux をブートするまでのシーケンス (Image Selector編)』を参照してください。

Image Selector によって選択された BOOT.BIN には FSBL(First Stage Boot Loader)、PMUFW(Platform Management Unit FirmWare)、BL31(ARM Trusted Firmware Boot Loader Stage 3-1)、U-Boot が含まれています。

・ステージ1 (FSBL - First Stage Boot Loader)

ステージ1ブートローダー(FSBL) は内部RAMにロードされます。ステージ1ブートローダー(FSBL)は Coretex-A53 が実行します。ステージ1ブートローダー(FSBL) は次の処理を行います。

  • PS(Processing System) の初期設定
  • BOOT.BIN に含まれる Bitstream を PL(Programmable Logic) へコンフィギュレーション
    (ただし KV260 の QSPI にある BOOT.BIN には Bitstream は含まれていないため、このステップは無い模様)
  • BOOT.BIN に含まれるステージ2ブートローダー(BL31)を SDRAM にロード
  • BOOT.BIN に含まれるステージ3ブートローダー(U-Boot)を SDRAM にロード
  • BOOT.BIN に含まれるPMUFW(Platform Manager Unit Firmware)を PMU の RAM にロード
  • ステージ2ブートローダー(BL31)に制御を移す

・ステージ2 (BL31 - ARM Trusted Firmware Boot Loader Stage 3-1)

ステージ2ブートローダー(BL31) は SDRAM にロードされます。BL31 は ARM が提供している ATF(ARM Trusted Firmware) の EL3 Runtime Firmware です。ATF に関しては次の URL を参照してください。

ステージ2ブートローダー(BL31)は Coretex-A53 が実行します。ステージ2ブートローダー(BL31)は自分自身を初期化してステージ3ブートローダー(U-Boot)に制御を移した後でも RAM に常駐して各種サービスを提供します。

・ステージ3 (U-Boot)

ステージ3ブートローダー(U-Boot)はファイルシステムを使えたり、スクリプトや環境変数などが使えるので、その設定にしたがって、Linux のカーネルイメージ、Device Tree、場合によってはルートファイルシステムを SDRAMに ロードします。その後、Linuxカーネルイメージに制御を移します。

KV260 の QSPI にある U-Boot は正常に起動すると UART に次のようなメニューを表示します。このメニュー表示後5秒間なにも入力が無いと自動的に「Auto-Select - 1.CC boot 2.SOM boot」に移行します。

Fig.1 U-Boot Menu

Auto-Select はセカンダリブートデバイス(KV260の場合は SD-Card)にある boot.scr を呼び出します。

ステージ3ブートローダー(U-Boot)によるブートシーケンスは『KV260 が Linux をブートするまでのシーケンス (U-Boot編)』でもう少し詳細に説明しています。

・ステージ4 SD Card (セカンダリブートデバイス)

KV260 のセカンダリーブートデバイスは SD-Card です。

boot.scr

U-Boot はセカンダリーブートデバイス(KV260の場合は SD-Card)にある boot.scr を呼び出します。

boot.scr は u-boot 専用のスクリプトファイルです。これは一見バイナリファイルに見えますが、実は Petalinux などが生成した boot.scr の場合は特にエンコードされていないので、cat で中を見ることができます。なお、boot.scr の内容はディストリビューションによって異なります。ここでは「UltraZed/Ultra96/Ultra96-V2/KV260 向け Debian GNU/Linux (v2021.1版) ブートイメージの提供」 で紹介した KV260 用 boot.scr について説明します。

fpga@debian-fpga:/mnt/boot$ file boot.scr
boot.scr: u-boot legacy uImage, Boot script, Linux/ARM, Script File (Not compressed), 2530 bytes, Tue Apr  5 23:00:00 2011, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0x5C38692B, Data CRC: 0x85779C72
fpga@debian-fpga:~$ cat /mnt/boot/boot.scr
'V\8i+M・       窈rBoot script  レ# This is a boot script for U-Boot
# Generate boot.scr:
# mkimage -c none -A arm -T script -d boot.cmd.default boot.scr
#
################


for boot_target in ${boot_targets};
do
        echo "Trying to load boot images from ${boot_target}"
        if test "${boot_target}" = "jtag" ; then
                booti 0x00200000 0x04000000 0x00100000
        fi
        if test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; then
                if test -e ${devtype} ${devnum}:${distro_bootpart} /uEnv.txt; then
                        fatload ${devtype} ${devnum}:${distro_bootpart} 0x00200000 uEnv.txt;
                        echo "Importing environment(uEnv.txt) from ${boot_target}..."
                        env import -t 0x00200000 $filesize
                        if test -n $uenvcmd; then
                                echo "Running uenvcmd ...";
                                run uenvcmd;
                        fi
                fi
                if test -e ${devtype} ${devnum}:${distro_bootpart} /image.ub; then
                        fatload ${devtype} ${devnum}:${distro_bootpart} 0x10000000 image.ub;
                        bootm 0x10000000;
                fi
                if test -e ${devtype} ${devnum}:${distro_bootpart} /Image; then
                        fatload ${devtype} ${devnum}:${distro_bootpart} 0x00200000 Image;;
                fi
                if test -e ${devtype} ${devnum}:${distro_bootpart} /system.dtb; then
                        fatload ${devtype} ${devnum}:${distro_bootpart} 0x00100000 system.dtb;
                fi
                if test -e ${devtype} ${devnum}:${distro_bootpart} /ramdisk.cpio.gz.u-boot && test "${skip_tinyramdisk}" != "yes"; then
                        fatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 ramdisk.cpio.gz.u-boot;
                        booti 0x00200000 0x04000000 0x00100000
                fi
                if test -e ${devtype} ${devnum}:${distro_bootpart} /rootfs.cpio.gz.u-boot && test "${skip_ramdisk}" != "yes"; then
                        fatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 rootfs.cpio.gz.u-boot;
                        booti 0x00200000 0x04000000 0x00100000
                fi
                booti 0x00200000 - 0x00100000
        fi
        if test "${boot_target}" = "xspi0" || test "${boot_target}" = "qspi" || test "${boot_target}" = "qspi0"; then
                sf probe 0 0 0;
                sf read 0x10000000 0xF40000 0x6400000
                bootm 0x10000000;
                echo "Booting using Fit image failed"

                sf read 0x00200000 0xF00000 0x1D00000
                sf read 0x04000000 0x4000000 0x4000000
                booti 0x00200000 0x04000000 0x00100000;
                echo "Booting using Separate images failed"
        fi
        if test "${boot_target}" = "nand" || test "${boot_target}" = "nand0"; then
                nand info;
                nand read 0x10000000 0x4180000 0x6400000
                bootm 0x10000000;
                echo "Booting using Fit image failed"

                nand read 0x00200000 0x4100000 0x3200000
                nand read 0x04000000 0x7800000 0x3200000
                booti 0x00200000 0x04000000 0x00100000;
                echo "Booting using Separate images failed"
        fi
done

uEnv.txt

前節で紹介した boot.scr は、セカンダリーブートデバイスが SD-Card だった場合、まずブートパーティションに uEnv.txt があるかどうかチェックします。uEnv.txt は環境変数を設定するためのファイルです。もし uEnv.txt があった場合は、その内容を読み込んで環境変数を設定します。

uEnv.txt に環境変数 uenvmd が定義されていた場合はそれを実行します。

例えば次のような uEnv.txt があった場合、SD-Card にある image-5.10.0-xlnx-v2021.1-zynqmp-fpga を Linux Kernel Image として、また devicetree-5.10.0-xlnx-v2021.1-zynqmp-fpga-kv260-revB.dtb を Device Tree Blob として、/dev/mmcblk1p2 をルートファイルシステムとして Linux をブートします。

uEnv.txt
########################################################################
# Linux Kernel Files
#  * linux_kernel_image : Linux Kernel Image File Name
#  * linux_fdt_image    : Linux Device Tree Blob File Name
########################################################################
linux_kernel_image=image-5.10.0-xlnx-v2021.1-zynqmp-fpga
linux_fdt_image=devicetree-5.10.0-xlnx-v2021.1-zynqmp-fpga-kv260-revB.dtb

########################################################################
# Linux Boot Argments
#  * linux_boot_args_console : ex) console=tty1
#                                  console=ttyPS1,115200
#  * linux_boot_args_rootfs  : ex) root=/dev/mmcblk1p2 rw rootwait
#  * linux_boot_args_systemd : ex) systemd.unit=graphical.target
#                                  systemd.unit=multi-user.target
#  * linux_boot_args_cpuidle : ex) cpuidle.off=1
#  * linux_boot_args_cma     : ex) cma=256M
#  * linux_boot_args_uio     : ex) uio=uio_pdrv_genirq.of_id=generic-uio
#  * linux_boot_args_other   :
########################################################################
linux_boot_args_console=console=ttyPS1,115200
linux_boot_args_rootfs=root=/dev/mmcblk1p2 rw rootwait
linux_boot_args_systemd=systemd.unit=multi-user.target
linux_boot_args_cpuidle=cpuidle.off=1
linux_boot_args_cma=1000M
linux_boot_args_uio=uio_pdrv_genirq.of_id=generic-uio
linux_boot_args_other=

########################################################################
# uenvcmd : During sdboot, if uenvcmd is set, uenvcmd will be executed.
########################################################################
linux_img_load_cmd=fatload ${devtype} ${devnum}:${distro_bootpart} 0x00200000 ${linux_kernel_image}
linux_fdt_load_cmd=fatload ${devtype} ${devnum}:${distro_bootpart} 0x00100000 ${linux_fdt_image}
linux_load_cmd=env run linux_img_load_cmd && env run linux_fdt_load_cmd
linux_boot_cmd=booti 0x00200000 - 0x00100000
linux_args_cmd=if env exists linux_boot_args; then; setenv bootargs ${linux_boot_args}; else; setenv bootargs ${linux_boot_args_console} ${linux_boot_args_rootfs} ${linux_boot_args_systemd} ${linux_boot_args_cpuidle} ${linux_boot_args_cma} ${linux_boot_args_uio} ${linux_boot_args_other}; fi
uenvcmd=env run linux_args_cmd && env run linux_load_cmd && env run linux_boot_cmd

image.ub

uEnv.txt に uenvcmd が定義されていなかった場合、boot.scr は ブートパーティションに image.ub があるかチェックします。image.ub は Linux Kernel や Device Tree Blob をまとめた u-boot のブートイメージです。もし image.ub があれば、それをロードして実行します。

Image

image.ub が無かった場合、boot.scr はブートパーティションに Image があるかチェックします。Image は Linux Kernel のイメージです。Image があれば、それをロードします。

system.dtb

image.ub が無かった場合、boot.scr はブートパーティションに system.dtb があるかチェックします。system.dtb は Linux Kernel をブートする際のデバイスツリーです。system.dtb があれば、それをロードします。

ramdisk.cpio.gz.u-boot or rootfs.cpio.gz.u-boot

image.ub が無かった場合、boot.scr はブートパーティションに ramdisk.cpio.gz.u-boot または rootfs.cpio.gz.u-boot があるかチェックします。ramdisk.cpio.gz.u-boot および rootfs.cpio.gz.u-boot は Linux のルートファイルシステムです。ramdisk.cpio.gz.u-boot または rootfs.cpio.gz.u-boot があればそれをロードします。そして 前節、前前節でロードした Image と system.dtb をブートします。

ramdisk.cpio.gz.u-boot および rootfs.cpio.gz.u-boot が無かった場合は、bootargs で設定された root パラメーターにしたがってルートファイルシステムを設定します。例えばこの記事で紹介した uEnv.txt だと root=/dev/mmcblk1p2 rw rootwait なので SD-Card の第二パーティションをルートファイルシステムとしてマウントします。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6