wiki:malibu/boot

Version 1 (modified by Tim Harvey, 15 months ago) ( diff )

initial page

Malibu Boot Firmware

The 'Boot Firmware' for Malibu is defined as the combination of the firmware stages through up to and including the bootloader. This can be broken down into the following stages:

  • Boot ROM (internal on CN913x SoC): fetch first level boot firmware from boot device (ie eMMC) into L2 cache
  • ATF (ARM Trusted Firmware)
  • Bootloader (U-Boot)

Gateworks provides pre-built Boot Firmware ready to flash onto boot devices as well as source for building and/or modifying the boot firmware yourself.

CN913x BOOT ROM

The BOOT ROM is firmware baked into the SoC and is in charge of loading code from the 'boot device' into L2 cache, verifying signatures (if using trusted boot) and executing it.

The BOOT ROM fetches code from an offset, verifies a header, and jumps to that code. If the header verification fails it will move on to the next offset. The offsets vary per boot device:

  • eMMC:
    • boot0/boot1 hardware partitions: LBA0 (0)
    • data hardware partition: LBA1 (512B), LBA34 (512B*34), LBA4096 (2M), LBA8192 (4M), LBA12288 (6M)
  • SD:
    • LBA1 (512B), LBA34 (512B*34), LBA4096 (2M), LBA8192 (4M), LBA12288 (6M)

Note that LBA refers to Logical Block Address which is a block device unit of 512 bytes.

The image header contains a 4-byte magic pattern to identify the boot image, 32bit checksums, a load address, an execution address, a 1byte uart config to configure the serial port for boot info, a baudrate for the serial port and some extension data.

The CN913x Boot flow is documented in chapter 28 of the ARMADA 80xx Family Functional Specification which can be obtained under NDA with Marvell.

Boot Firmware Image

The boot firmware image contains all of the components of the 'Boot Firmware':

  • ARM Trusted Firmware
  • Marvell DDR configuration software; this is a Binary ROM extension (BLE) for the ATF
  • U-Boot; this is a BL33 for the ATF

The boot firmware for Malibu is placed on the boot0 emmc hardware partition so that it is separated from the OS image.

Malibu Boot Firmware Image Map:

  • imx8mm:
start-end len item
0x00000000 - 0x003f0000 4032K ATF (including ddr config as BLE and U-Boot as BL33)
0x0003f000 - 0x00400000 64K U-Boot env (redundant 32KB env)

Compressed Disk Images

Gateworks releases compressed disk images that can be easily flashed using the U-Boot Bootloader or Linux (booted on a ramdisk based root filesystem). These disk images contain a partition table so they are tailored to the specific device size they are intended for. Additionally they are commonly configured for a small partition size to keep flash programming time at a minimum. This requires resizing the rootfs filesystem in order to take advantage of the remaining flash space.

Once you have a root filesystem directory/tarball and have a kernel Image you can create a compressed disk image that can be installed easily from the bootloader.

The creation of the compressed disk image is demonstrated in the Malibu BSP makefile

Once you have a compressed disk image you can install this using the methods described in malibu/firware-update. For example in the bootloader:

setenv dev 0 # emmc device; use mmc list to see all mmc devs
tftpboot ${loadaddr} image.img.gz && gzwrite mmc ${dev} ${loadaddr} ${filesize}

If you created a filesystem that did not stretch to the partition it was installed on (as we create a minimally sized filesystem image to fit within the eMMC device for faster programming) you will want to resize it after booting to Linux. This is a one time operation after flashing a compressed disk image and can be done using the 'growpart_once' script that we install on the Ubuntu Root filesystems found in the script here (search for growpart_once)

To install the kernel and root filesystem on a removable block storage device see linux/blockdev.

U-Boot Bootloader

Gateworks supports the U-Boot Bootloader for the Malibu product family.

The purpose of a bootloader is to load the Linux kernel and execute it passing it configuration parameters such as an optional kernel command-line, an optional initial ramdisk filesystem, and a device-tree.

The following items are supported in the Gateworks U-Boot for Malibu:

  • eth0 (RGMII)
  • USB Host mode (USB Mass Storage and USB Networking for various USB Ethernet adapters supported by U-Boot
  • eMMC / microSD

The following items are not currently supported in the Gateworks U-Boot for Malibu:

  • PCIe support
  • USB device mode support (for USB OTG)

Distro Config

The Malibu Bootloader uses U-Boot's 'Distro Config' which is a well defined U-Boot env intended to make it easier for distro maintainers to develop compatible bootscripts. This primarily entails a set of 'boot scripts' and variables that control them.

Ultimately this U-Boot environment is looking for a U-Boot boot script on a 'bootable' partition (partitions with the 'boot' flag enabled). It searches in this order with these rules:

  • boot_targets - list of target device type/nums to search: defaults to mmc1 mmc0 usb0 usb1 pxe dhcp
  • devplist - dynamically created list of all partitions flagged as 'bootable'
  • boot_prefixes - list of directories within a partition searched for bootscripts
  • boot_scripts - list of boot script names searched for

Boot Scripts

When writing bootscripts compatible with Distro Config you can assume the following env variables:

  • devtype - the device type the script was loaded from (mmc|usb|sata)
  • devnum - the device number the script was loaded from (ie 0 for mmc0, 1 for mmc1, etc)
  • distro_bootpart - the partition number the script was loaded from (ie 0, 1, etc)
  • fdtcontroladdr - the address the device-tree is at (Note that the Malibu bootloader contains a static version of the board device-tree)
  • kernel_addr_r - address where kernel can be loaded
  • bootargs - default bootargs to pass to the kernel - you probably want to add to this and not overwrite it
  • console - the serial console device to pass to the kernel

Additionally you should note the following:

  • use load/ls/save commands which support FAT/ext filesystem types automatically instead of the fs specific commands
  • if using a root filesystem that is not supported by the bootloader (ie F2FS or BTRFS) you can place your bootscript and kernel image in the FAT12 filesystem on partition 1 of the boot device. This filesystem is part of the 16MB 'Boot Firmware' image. If doing so you will need to compress the kernel and package it into a FIT image in order to fit it in the available space.

The Distro-Config environment supports legacy uImage scripts (it does not support FIT images with scripts). You can create these with the mkimage tool from U-Boot as such:

mkimage -A arm64 -T script -C none -d boot.txt boot.scr

The bootscript can be updated at runtime on the Linux target. For example:

mkimage -A arm64 -T script -C none -d boot.txt /boot/boot.scr

Boot Device Order (boot_targets)

While the Malibu product family can only boot from its primary boot device (typically eMMC), once you are booted to the bootloader you can choose from a wider variety of devices to boot the OS from.

This OS boot device order is specified by the Distro Config environment. Specifically it is controlled by the boot_targets env variable which typically defaults to mmc1 mmc0 usb0 usb1 pxe dhcp.

For example, to limit OS booting to only USB:

setenv boot_targets usb0 usb1
saveenv

Flattened Image Tree (FIT) images

The U-Boot bootloader supports Flattened Image Tree (FIT) images which expand greatly on the legacy U-Boot image (uImage) format by allowing multiple binary blobs within an image. These blobs can be kernel images, ramdisk images, device-tree blobs, and bootloader scripts. Each image can also be optionally compressed (meaning U-Boot will decompress it) and check-sumed with a variety of hash mechanisms (meaning U-Boot will verify the image before using it).

Quick summary of FIT Images:

  • introduced to resolve limitations with original single-image formats and follow-on multi-image format supported by UBoot bootm (boot memory)
  • uses power of the Device-Tree-Compiler (DTC)
  • FIT .itb files can be created with mkimage by passing in a .its file which in device-tree notation describes the images
  • U-Boot supports FIT with several commands:
    • source <addr>:<name> # source a script by name from FIT image in memory
    • iminfo <fitaddress> # print all the info contained in a FIT image in memory and verify (just not boot it)
    • imextract <fitaddress> <item> <addr> # extract item (ie kernel@1) to addr
    • bootm <fitaddress>[#conf] - $fdtcontroladdr # boot default or 'conf' configuration (ie #config@1)
    • bootm start <fitaddress>[#conf] - $fdtcontroladdr # boot from memory a specific configuration (or default configuration) from FIT image

Example:

  • kernel.its with a single compressed kernel for ARM64
    /dts-v1/;
    / {
            description = "Simple image with single Linux kernel";
            #address-cells = <1>;
            images {
                    kernel@1 {
                            description = "Linux kernel";
                            data = /incbin/("./Image.gz");
                            type = "kernel";
                            arch = "arm64";
                            os = "linux";
                            compression = "gzip";
                            load = <0x40200000>;
                            entry = <0x40200000>;
                            hash@1 {
                                    algo = "sha256";
                            };
                    };
            };
    
            configurations {
                    default = "conf@1";
                    conf@1 {
                            description = "Boot Linux kernel";
                            kernel = "kernel@1";
                    };
            };
    };
    
  • create image:
    cp arch/arm64/boot/Image .
    gzip Image
    mkimage -f kernel.its /tftpboot/kernel.itb
    
  • boot the default configuration from U-Boot:
    tftpboot $loadaddr kernel.itb && bootm $loadaddr - $fdtcontroladdr
    

References:

U-boot env tools

A detailed description of u-boot-tools usage can be found here.

In order to configure u-boot-tools to work correctly for Malibu you will need a fw_env.config file the appropriate values.

To create this file:

cat << EOF > /etc/fw_env.config
# Device               offset          Env. size
/dev/mmcblk0boot0      0x3f0000        0x8000
/dev/mmcblk0boot0      0x3f8000        0x8000
EOF
Note: See TracWiki for help on using the wiki.