Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This pages provides information related to using the industry standard "distro boot" boot flow for U-boot as it's been implemented by Xilinx. 

Table of Contents

Table of Contents
excludeTable of Contents

Introduction

While x86-based platforms have a de facto standardization of how boot operates from BIOS/UEFI during initial power-on until hand-off to a robust operating system like Linux or Microsoft Windows, this is largely incidental and has much to do with the limited number of x86-based vendors in the market. By contrast, the number of Arm-based SoC platforms numbers in the dozens and virtually every SoC has some form of unique boot process.

...

For example, a simple TFTP-based boot is illustrated below.

theme
Code Block
Midnight
bootcmd=echo Booting from network ...; usb start; setenv ethact asx0; if dhcp && tftp $loadaddr $bootfile && tftp $f

...

Distro boot extends this functionality by redirecting the call to bootcmd to a call to the distro_bootcmd variable. 

Code Block
themeMidnight
bootcmd=run distro_bootcmd

...

How the distro_bootcmd variable is defined and used differs by vendor but it typically contains a sequence of commands that scans a pre-defined list of potential boot targets in search of boot collateral as shown below.

Midnight
Code Block
theme
boot_targets=mmc0 jtag mmc0 mmc1 qspi0 nand0 usb0 usb1 scsi0 pxe dhcp
distro_bootcmd=scsi_need_init=; for target in ${boot_targets}; do run bootcmd_${target}; done


The command loops through the contents of the boot_targets list and scans the media in order looking for additional boot collateral. The boot_targets list is defined in the platform definition in the U-Boot source tree.
Depending on the specifics of the target platform, the distro boot infrastructure can either use the boot_targets list to explicitly find specific boot collateral (eg, hard-coded loading once a valid boot target is located) or it can be used to locate some kind of decoupled configuration information.

...

Specifically, the distro boot infrastructure will first scan for a file named extlinux.conf at the pre-defined locations (ex: /extlinux/extlinux.conf or /boot/extlinux/extlinux.conf) in the default U-Boot environment. The basic syntax of the extlinux.conf file is as show below.

Midnight
Code Block
theme
LABEL Linux
   KERNEL Image
   FDT system.dtb
   INITRD rootfs.cpio.gz.u-boot

...

In the absence of a valid extlinux.conf file, U-Boot will scan the boot_targets list looking for a file named boot.scr.uimg or boot.scr (in that order) and run any commands located in the script file. An example of the script file syntax is seen below.  If your environment requires a different sequence of commands or behavior, you can edit the boot.scr file to suit your needs.

Midnight
Code Block
theme
for boot_target in ${boot_targets};
do
        if test "${boot_target}" = "jtag" ; then
. . .
<COMMANDS>
. . .
        fi
        if test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; then
. . .
<COMMANDS>
. . .
        fi
        if test "${boot_target}" = "xspi0"; then
. . .
<COMMANDS>
. . .
        fi
done

...

The recommended method for packaging the boot.scr image is to use the U-Boot FIT format with a script similar to:

Midnight
Code Block
theme
/dts-v1/;

/ {
    description = "Boot script";
    images {
         default = "script";
         script {
             description = "Boot script";
             data = /incbin/("./boot.scr");
             type = "script";
             compression = "none";
             hash {
                 algo = "sha1";
             };
        };
    };
};

...

Packaging a FIT image is similar to the legacy method in that it uses mkimage but the syntax is much simpler:

theme
Code Block
Midnight
mkimage -f boot.fit boot.scr.uimg

If your design does not require the additional features provided in the FIT description method seen above, the image can be packaged simply with the mkimage command directly:

theme
Code Block
Midnight
mkimage -C none -A arm -T script -d boot.scr boot.scr.uimg

...

If you need to edit an existing packaged boot.scr file (or boot.scr.uimg), you can extract the plain ASCII text format using the following command line:

Code Block
themeMidnight
tail -c+73 < boot.scr.uimg > out

...

Starting with the 2020.1 release, Xilinx has switched to using the distro boot infrastructure by default for all SoC platform.  The default mechanism in the Xilinx-provided software stack utilizes the boot.scr framework.  Support is still present for using extlinux.conf files and they will be used if present.  The platform files which define the boot_targets list and the Xilinx-specific default U-Boot environment are:

SoC Platform

Path in U-Boot Source Tree

Zynq-7000

include/configs/zynq-common.h

Zynq UltraScale+ MPSoC

include/configs/xilinx_zynqmp.h

Versal

include/configs/xilinx_versal.h

On Xilinx platforms, the boot_targets list always prepends the current primary boot mode as configured on the MODE pins. Thus, it is expected to see a given target more than once in the boot_targets variable. For example, on a Zynq UltraScale+ MPSoC device booting from SD card, the boot_targets list appears as:

theme
Code Block
Midnight
boot_targets=mmc0 jtag mmc0 mmc1 qspi0 nand0 usb0 usb1 scsi0 pxe dhcp

...

For example, when booting from MMC devices (SD card or eMMC), the following script is run from the boot.scr file by default in the Xilinx-provided U-Boot environment.  This can be modified based on your needs. 

Midnight
Code Block
theme
if test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; then
   if test -e ${devtype} ${devnum}:${distro_bootpart} /image.ub; then
      fatload ${devtype} ${devnum}:${distro_bootpart} 0x10000000 image.ub;
      bootm 0x10000000;
      exit;
   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} /rootfs.cpio.gz.u-boot; then
      fatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 rootfs.cpio.gz.u-boot;
      booti 0x00200000 0x04000000 0x00100000
      exit;
   fi

   booti 0x00200000 - 0x00100000
   exit;
fi 

For additional details on the usage of the bootm and booti commands, see the U-Boot page.

Of note in this scheme is that the files must be found in the root of the filesystem and follow the naming scheme:

Component

File Name

Load Address

U-Boot combined image file (image.ub)

image.ub

0x10000000

Linux kernel image file (if image.ub is not found)

Image

0x00200000

Linux device tree file (if image.ub is not found)

system.dtb

0x00100000

Linux root filesystem image (if image.ub is not found)

rootfs.cpio.gz.u-boot

0x04000000

Booting from QSPI

When the boot mode detected is QSPI, the following script is run from the boot.scr file by default in the Xilinx-provided U-Boot environment.  This can be modified based on your needs. 

Midnight
Code Block
theme
if test "${boot_target}" = "xspi0" || test "${boot_target}" = "qspi" || test "${boot_target}" = "qspi0"; then
   sf probe 0 0 0;
   if test "image.ub" = "image.ub"; then
      sf read 0x10000000 0xF00000 0x6400000;
      bootm 0x10000000;
      exit;
   fi

   if test "image.ub" = "Image"; then
      sf read 0x00200000 0xF00000 0x1D00000;
      sf read 0x04000000 0x4000000 0x4000000
      booti 0x00200000 0x04000000 0x00100000
      exit;
   fi

   exit;
fi


When booting from a QSPI device, care must be taken to maintain a very specific scheme for where files are located both in the nonvolatile flash device as well as where they are loaded into DDR prior to hand-off to the robust operating system.

Component

Flash Address

Load Address

U-Boot combined image file (image.ub)

0xF00000

0x10000000

Linux kernel image file (if image.ub is not found)

0xF00000

0x00200000

Linux device tree file (if image.ub is not found)

Pre-loaded by BOOT.BIN

0x00100000

Linux root filesystem image (if image.ub is not found)

0x4000000

0x04000000

Note: The table above presents default values as found in the pre-built collateral.  The PetaLinux tools will automatically adjust the flash and load addresses as appropriate to fit the relative sizes of each payload partition.

...

In summary, the order of precedence for searching for boot components is as follows

  1. extlinux.conf file (located in /extlinux/ or /boot/extlinux/)

  2. boot.scr file + image.ub file

  3. boot.scr file + individual files (Image, system.dtb, etc.)

References

https://gitlab.denx.de/u-boot/u-boot/blob/master/doc/README.distro
https://www.denx.de/wiki/view/DULG/UBootEnvVariables
https://wiki.syslinux.org/wiki/index.php?title=Config
http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/

...