Booting LAN966x

1. Introduction

The LAN966x family comprises the following SKUs:

  • LAN9662 - 2 port end-node TSN Gigabit Ethernet switch device.

  • LAN9668 - 8 port TSN Gigabit Ethernet switch device.

This document will focus on the LAN966x SoCs, but to fully explain the boot process and boot facilities it is also necessary to consider the flash memories available on the board. The upcoming sections will briefly describe the boot media supported by the LAN966x, and then describe which of these media is available on the various evaluation boards offered by Microchip.

This document uses many abbreviations, see the terms and abbreviations section for details.
This document is specific to the B0 revision of LAN966x. A A0 revision also exists, but is not considered here.

2. Overview

LAN966x offers secure boot, which is based on ARM Trusted Firmware (TF-A). The TF-A architecture heavily influence the boot-sequence, and to understand how LAN966x boots, a bit of TF-A understanding is also needed.

Following is an illustration of a typical lan966x boot sequence using UBoot and Linux:

Bootflow with UBoot

It is possible to skip UBoot, if this case the boot sequence will look like this:

Bootflow without UBoot

TF-A and LAN966x goes through the following boot steps:

  • TF-A/BL1 This is ROM code embedded inside the chip. LAN966x always start by boot TF-A/BL1 from ROM. TF-A/BL1 loads the next bootloader (BL2) from one of the support boot-medias. The strapping pins are used to configure which of the supported boot-media to use.

  • BL2 This is a second stage boot-loader also part of TF-A. This bootloader runs from an on-chip SRAM, it setup the trust-zones, configure DDR memory and other basic platform initialization. Once the platform is initialized, it will load BL32 and BL33 from the configured boot-media into DDR memory.

  • BL32 This is a called "EL3 Runtime Software", also part of TF-A. This stage does not influence the boot-flow directly, and will not be covered here.

  • BL33 In TF-A terminology, this is the unsecure firmware. It is not part of the TF-A project, but is signed and distributed together with TF-A. TF-A imports this as a BLOB. Typically this is either UBoot or a special version of the kernel which can run without UBoot.

The above list of update-able images (BL2, BL32 and BL33), plus relevant certificates and relevant support files are packed in a FIP (Firmware Image Packet), which is a storage format defined by TF-A. The FIP containing these images must be stored raw in the designed boot-media. In some cases it must be put at a specific address, while in other it is stored in a partition with a predefined name.

This document will not go into the details of TF-A, but just assume that the FIP is available and describe where and how it can be programmed. Two different FIPs will be used, one with UBoot as BL33, and another one with Linux-kernel as BL33.

3. Boot media configuration

The strapping pins are configuring the initial boot mode. The table below lists the supported modes:

Strapping Pins LAN966x B0

0000 (0x0)

eMMC + FC3 (for trace)

0001 (0x1)

QSPI0 + FC3 (for trace)

0010 (0x2)

SDCard + FC3 (for trace)

0011 (0x3)

eMMC

0100 (0x4)

QSPI0

0101 (0x5)

SDCard

0110 (0x6)

PCIe EndPoint

0111 (0x7)

Reserved

1000 (0x8)

UART Monitor at FC3 + QSPI0

1001 (0x9)

Reserved

1010 (0xa)

Reserved

1011 (0xb)

Reserved

1100 (0xc)

Reserved

1101 (0xd)

Reserved

1110 (0xe)

Reserved

1111 (0xf)

SPI Client

The strapping configuration is read by TF-A/BL1, which uses it to select select the boot-media, and thereby determinate where the FIP is loaded from. UBoot will also use the strapping pins to determinate which flash to load the environment configuration from.

3.1. UART Traces

When booting from flash the TF-A loaders can be configured to emit trace messages on the UART provided by FlexCom3. The following table show the strapping configurations with and without traces enables.

Trace enable Trace disable Flash type

0000

0011

eMMC

0001

0100

QSPI/NOR

0010

0101

SDCard

Boards which do not have a compatible HW configuration shall avoid this strap mode.

Be aware that traces to the UART impact boot time and should only be activated when debugging is needed or the startup time is not important.

3.2. Booting from eMMC/SDCard (0000, 0010, 0011 or 0101)

When booting from eMMC/SDCard, a valid GUID Partition Table (GPT) must be used. The TF-A/BL1 ROM will look for a partition called fip and fip.bak and use then accordingly. The table below provide an example of a partition table. The page size for the eMMC/SDCard device is 0x200/512 bytes.

Type Part-idx Part-name Offset/name Partition size

GPT (PartTable)

n/a

n/a

Page 0x0

0x40 (32kb)

TF-A FIP

1

fip

Page 0x40

0x40000 (128mb)

TF-A FIP

2

fip.bak

Page 0x40040

0x40000 (128mb)

UBoot (Env)

3

Env

Page 0x80040

0x1000 (2mb)

UBoot (Env)

4

Env.bak

Page 0x81040

0x1000 (2mb)

ext4 (rootfs)

5

Boot0

Page 0x82040

0x200000 (1gb)

ext4 (rootfs)

6

Boot1

Page 0x282040

0x200000 (1gb)

ext4 (data)

7

Data

Page 0x482040

until end

SDCard doesn’t support redundant environment.

The bold parts are the items which is hard-coded in either TF-A/BL1 or in UBoot. If it relates to UBoot then it can be changed, but requires changes to UBoot as well. Everything else is just an example which can be changed according to customer needs.

3.3. Booting from NOR (0001 or 0100)

The following table contains the offsets used by TF-A and UBoot when booting from QSPI/NOR:

Type Offset/name Max size

TF-A FIP

0x0

0x00180000 (1536kb)

UBoot (Env)

0x180000

0x00040000 (256kb)

UBoot (Env-bak)

0x1C0000

0x00040000 (256kb)

3.4. PCIe End Point (0110)

This mode is used to initialize the SoC as a PCIe end-point. This mode can pull certain configuration options from OTP. Using this mode does not require any flash or DDR memory to be mounted at the board.

After the PCIe end-point is configured the internal CPU will go to sleep.

3.5. UART Monitor (1000)

This mode will boot into a UART monitor using FlexCom3. This can be used to program the OTP and to load firmware into flash. This mode can be used without any valid content in the flash, and is therefore useful for de-brick or even production scenarios.

The UART Monitor implement a machine interface and should not be used interactively with a terminal. Instead use the HTML5 client provided as part of the TF-A project.

For any other use-case, the UART console terminal needs to be configured to 115200/8/N/1

3.6. SPI Client (pin mode 1111)

In this strapping mode, the CPU is not booting at all. This means the (TF-A is not running. A SPI client will be initialized instead. This SPI interface allows a host CPU to read/write register in the switch-core.

4. Beyond TF-A

So far we have concentrated on configuring the HW and boot media. Once put in place, TF-A/BL2, BL2 and BL32 will boot, and eventually reach TF-A/BL33. TF-A/BL33 is the boot-step after TF-A, and can be UBoot, Linux kernel or some other OS. The following chapters covers this in more details.

4.1. TF-A/UBoot/Linux

In this mode the UBoot binary is embedded in into the FIP as TF-A/BL33. TF-A will do the platform initialization, load images (and authenticate them), DDR initialization etc. Once done, it will boot UBoot, which then control the next steps in boot flow.

UBoot will take care of loading the ITB and the rootfs and boot up into the Linux.

This is the so called normal-boot mode.

4.2. TF-A/Linux

In this mode a Linux kernel binary is embedded in into the FIP as TF-A/BL33. TF-A will do the platform initialization, load images (and authenticate them), DDR initialization etc. Once done, it will boot the Linux kernel directly.

This is the so called fast-boot mode.

5. Images and artifacts

The referenced images and archives can all found on public servers. Therefore, the following description will provide all needed information.

5.1. TFA images

The TFA (FIPs) images can be found under following link:
https://github.com/microchip-ung/arm-trusted-firmware/releases

5.2. Buildroot artifacts

The build artifacts (UBoot, kernel, rootfs etc.) can be found on following public server:
http://mscc-ent-open-source.s3-website-eu-west-1.amazonaws.com/?prefix=public_root/bsp

Download the proper architecture and build version. For example:
mscc-brsdk-arm-yyyy.version.tar.gz

After extracting the *.tar.gz file, all rootfs and ITB related files can be found inside following folder:
mscc-brsdk-arm-yyyy.version/arm-cortex_a8-linux-gnu/standalone/release

5.3. Artifacts

The following subchapter gives a rough overview of the common used terms in the context of the available images and build artifacts.

5.3.1. TFA images

The upcoming table is describing the most important files extracted from the TFA artifacts archive:

File name File type BL33 data Flash Description

fwu-lan966x_b0-release.html

HTML5

n/a

n/a

Firmware update tool for MS Edge or Chrome

lan966x_b0-release.fip

FIP file

UBoot

NOR

Cleartext FIP, directly for NOR

lan966x_b0-release.fip.gz

FIP file

UBoot

NOR*

Compressed FIP (from above)

lan966x_b0-release-fwu_fip.bin

FWU FIP

n/a

n/a

FWU FIP for boot monitor bootstrap

lan966x_b0-release-linux.fip.gz

FIP file

Linux

MMC*

Compressed Linux FIP

lan966x_b0-release-mmc.gpt.gz

GPT image

UBoot

MMC*

Compressed GPT image for MMC/UBoot

lan966x_b0-release-mmc-linux.gpt.gz

GPT image

Linux

MMC*

Compressed GPT image for MMC/Linux

(*) The compressed images must be uncompressed before flashing to NOR/MMC. This is done on the fly by the FWU HTML tool.

5.3.2. Buildroot artifacts

Following table is describing the available ITB and filesystem related binaries inside the buildroot artifacts archive:

File name Description

brsdk_standalone_arm.ext4.gz

ext4 rootfs with ITB, located in the root directory.

brsdk_standalone_arm.itb

ITB only, used in the *.gz file.

fit.itb

ITB with Kernel and squashfs filesystem. Suitable for network boot.

rootfs.ext2

ext2 rootfs standalone

rootfs.ext4

ext4 rootfs standalone

rootfs.squashfs

squashfs filesystem standalone

rootfs.tar

rootfs/tar standalone

5.3.3. Kernel

The ITB files from the build artifacts archive including always the latest available kernel files.

5.3.4. DTS

The device tree sources are a set of text files in the Linux kernel source tree. They describe the hardware properties for a specific platform.

5.3.5. DTB

For processing the DTS, a Device Tree Compiler is used. Mainly, the compiler takes as input a device-tree in a given format and outputs a device-tree in another format.

Since the DTS represents the device-tree data in a human readable format, it is the preferred input format.
The output result of the DTC results is a .dtb file.

5.3.6. rootfs

Various types of root filesystem builds are provided inside the build artifact archive.

5.3.7. rootfs/tar

The rootfs/tar is accumulating a large collection of files into a single archive file, while preserving filesystem informations such as user/group permissions, dates, files, inodes and directory structures.

There is no tarball compression method used.

A tarball build of the rootfs/tar can be found inside the build artifacts archive. Please have a look for a binary which is named to rootfs.tar.

5.3.8. squashfs

The squashfs filesystem is a zlib compressed read-only filesystem (e.g. files, inodes and directories) for Linux. SquashFS gives more flexibility and performance speed than a tarball archive.

The rootfs.squashfs based build can be found inside the build artifacts archive.

5.3.9. ext4

The ext4 filesystem is also supported by the LAN966x system. There are different flavours of the ext4 builds inside the build artifacts archive available.

5.4. FIT

The Flattened Image Tree is a format for combining different binary elements such as the kernel, initramfs and DTB into a single .itb file.

Bootloaders like e.g. UBoot can read and process the FIT metadata to boot an embedded Linux system.

5.4.1. ITB full

This type of the FIT is containing the kernel files, device tree(s) and a root filesystem. Beside the FIP file, only one further single binary needs to be maintained and flashed to the target system. The drawback is the longer bootup time, caused by the the bigger image size.

The according binary, which includes a 'squashfs' root filesystem, can be found in the build artifacts archive named by 'fit.itb'.

5.5. ext4

Beside of the rootfs/tar and the squashfs, there is also the usage of an ext4 root filesystem possible. The following section should give a rough overview about some ext4 based use-cases.

5.5.1. ext4 with embedded ITB bare on FS

This variant of the ext4 build is containing the ext4 filesystem and additionally an ITB located inside root directory of the ext4 filesystem. For example, UBoot is capable to load filesystem and execute the ITB found in the root directory.

This build variant is available inside the build artifacts archive. It is named to 'brsdk_standalone_arm.ext4.gz'.

5.6. FIP

The FIP binary, so called 'fip.bin', is containing all parts of the TF-A firmware build. Basically, following components can be found there:

  • BL2

  • BL32 or BL33

  • certificates

  • support files

The different FIP builds can be found inside the build artifacts archive.

5.7. GPT image

The GPT image is used for configuring basically the flash device structure. This means writing the GPT, creating all needed partitions and do some further setup work.

The boot partition named to 'fip' will contain afterwards a 'fip.bin' file for the first system startup.

5.8. eMMC/SDCard default partition schema

The following table is showing the default partition scheme for the MMC flash devices. This means this table is valid for the eMMC and the SDCard device.

offset (pages)    size (pages)       Name/desc
==============    ===============    =====================
0x0               0x40     (32kb)    GPT (partition table)
0x40              0x40000  (128mb)   fip
0x40040           0x40000  (128mb)   fip.bak
0x80040           0x1000   (2mb)     Env
0x81040           0x1000   (2mb)     Env.bak
0x82040           0x200000 (1gb)     Boot0
0x282040          0x200000 (1gb)     Boot1
0x482040          0x300000 (1.5gb)   Data

When eMMC or SDCard is selected as boot media, the TF-A expects in the first 32kb of the flash pages a GPT.

The ROM code will look for a partition called fip. It will now try to boot from this partition. If the booting from the fip partition fails, it will try to load the firmware image from the fip.bak recovery partition.

If the boot attempt from the recovery partition is failing, no fallback approach is offered here.

6. Boot configurations

Possible boot methods will be described in the upcoming sections.

6.1. Network-boot

Before using the network boot feature, it needs to be ensured that the UBoot bootlader is made available inside the BL33.

After startup and entering UBoot console, the network stack on the target needs to be configured. This can be done by using static network settings or using a dynamic ip address provisioning like DHCP.

On the host system a TFTP server needs to be established. Host and target needs to be located in the same subnet. Afterwards the files can be transmitted over network to the target system memory.

For the network boot scenario a 'fit.itb' file needs to be provisioned by the TFTP server. After configuration of the UBoot, the file can be uploaded to the platform and will be executed directly from the target memory.

6.2. NOR

When QSPI/NOR is selected as boot media, the TF-A expect that the NOR flash is used in raw mode. This means in comparison to the eMMC/SDCard approach, there is no filesystem applied here.

The NOR flash device can usually programmed with a standard SPI flash programmer. Before attaching the programmer, check the usage of the proper pin header and use the correct SPI pins on the eval board. But here, there is also another further way for updating the NOR flash device possible. This will be described in the upcoming chapters.

Take care to write the 'fip.bin' file to a NOR memory address of 0x0 (zero).+ Because of the NOR size limitation on the LAN966x eval boards, only the 'fip.bin' file can be stored.

For a full booting Linux system, the missing ITB and the rootfs needs to be stored on an additionally flash device. Afterwards the bootloader needs to be configured properly for recognizing the FS and the ITB.

6.3. eMMC

For the eMMC boot operation mode, the 'fip.bin' file needs to be located mandatory on a partition section named to 'fip' or 'fip.bak'.

In this example, the UBoot needs to be part of the 'fip.bin'. This is required for uploading and writing the ITB and FS data via DHCP/TFTP to the correct eMMC partition sections.

Afterwards the environment variables of UBoot needs to be setup properly for a full boot.

6.4. Linux@BL33

This is the so called fast-boot mode. TF-A is loading in the BL33 stage directly the rootfs and ITB file. After the kernel is up and running, the FS will be mounted.

In this mode, there is no further bootstage (like UBoot) involved here. This will decrease the bootup time in comparison to the previously described scenarios.

7. Use-cases

7.1. Debrick or blank flash

In case of a blank eMMC or NOR device, following the instructions in Restore SecureBoot Images

7.2. UBoot

According the flashed FIP or GPT file, UBoot is available during system boot and can be used for customizing e.g. the ITB and rootfs related components. Furthermore, it can be used for updating existing GPT images or FIP files on the flash device.

The flash images will use either UBoot or Linux as (final) boot firmware. The string of '-linux-' in the FIP or GPT filename identifies the availability of the Linux or UBoot feature.

Sometimes it makes also to use the command of 'help', which provides a huge collection of all available commands and features. For example, the command of 'env print' can be used for dumping all available and initialized variables on the system.

7.2.1. Working with MMC subsystem

For setting up the UBoot mode, following steps needs to be applied:

  • Set the strapping mode to 0x0 (eMMC + FC3). See Boot media configuration.

  • Attach the board via usb cable to the host workstation

  • Configure a serial console application like e.g. putty (settings 115200/8/N/1)

  • Attach console application to /dev/ttyACM0

  • Reset the board and interrupt the UBoot autoboot before timeout.

  • On UBoot console, the command 'mmc info' will return the emmc device properties.

m => mmc info
Device: sdhci-host@e0830000
Manufacturer ID: 9d
OEM: 101
Name: IS008
Bus Speed: 30000000
Mode : MMC High Speed (52MHz)
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 7.3 GiB
Bus Width: 4-bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 7.3 GiB WRREL
Boot Capacity: 4 MiB ENH
RPMB Capacity: 4 MiB ENH

The UBoot command of 'mmc help' will provide an overview of all available mmc sub system related commands.

m => mmc help
mmc - MMC sub system

Usage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
mmc hwpartition [args...] - does hardware partitioning
  arguments (sizes in 512-byte blocks):
    [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes
    [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition
    [check|set|complete] - mode, complete set partitioning completed
  WARNING: Partitioning is a write-once setting once it is set to complete.
  Power cycling is required to initialize partitions after set to complete.
mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode
 - Set the BOOT_BUS_WIDTH field of the specified device
mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>
 - Change sizes of boot and RPMB partitions of specified device
mmc partconf dev [boot_ack boot_partition partition_access]
 - Show or change the bits of the PARTITION_CONFIG field of the specified device
mmc rst-function dev value
 - Change the RST_n_FUNCTION field of the specified device
   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.
mmc setdsr <value> - set DSR register value

For example, the MMC command of 'mmc write' will primarily used for storing the data content on the flash device.

7.2.2. Working with NOR subsystem

For setting up the UBoot mode, following steps needs to be applied:

  • Set the strapping mode to 0x1 (QSPI + FC3). See Boot media configuration.

  • Attach the board via usb cable to the host workstation

  • Configure a serial console application like e.g. putty (settings 115200/8/N/1)

  • Attach putty to /dev/ttyACM0

  • Reset the board and interrupt the UBoot autoboot before timeout

  • On the UBoot console, the command 'sf probe' will return the spi flash device properties

m => sf probe
SF: Detected sst26vf016b with page size 256 Bytes, erase size 4 KiB, total 2 MiB

The UBoot command of 'sf help' will provide an overview of all available spi flash related sub system commands.

m => sf help
sf - SPI flash sub-system

Usage:
sf probe [[bus:]cs] [hz] [mode] - init flash device on given SPI bus
                                  and chip select
sf read addr offset|partition len       - read `len' bytes starting at
                                          `offset' or from start of mtd
                                          `partition'to memory at `addr'
sf write addr offset|partition len      - write `len' bytes from memory
                                          at `addr' to flash at `offset'
                                          or to start of mtd `partition'
sf erase offset|partition [+]len        - erase `len' bytes from `offset'
                                          or from start of mtd `partition'
                                         `+len' round up `len' to block size
sf update addr offset|partition len     - erase and write `len' bytes from memory
                                          at `addr' to flash at `offset'
                                          or to start of mtd `partition'
sf protect lock/unlock sector len       - protect/unprotect 'len' bytes starting
                                          at address 'sector'

The SPI flash command of 'sf write' or 'sf update' will primarily used for storing FIP data content on the SPI flash device.

7.2.3. Loading files from network

UBoot can also configured for using the network stack for file transmission. A common practice is to enable the DHCP server on the host and using the UBoot 'dhcp' command. After recognizing a valid IP address, a file transmission using TFTP wil be established.

In case of using a static IP setup on the target, the following example can be applied via UBoot console. Adjust the values to the individual network environment.

The command of 'tftpboot' can be used then afterwards on the UBoot console.

env set 'ipaddr 192.168.0.10'
env set 'netmask 255.255.255.0'
env set 'serverip 192.168.0.1'
saveenv

m => help tftp
tftpboot - boot image via network using TFTP protocol

Usage:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]

In case of a available DHCP server in the network, the UBoot command of 'dhcp' can be used. It will setup the network configuration and establish afterwards the TFTP based file transmission.

m => help dhcp
dhcp - boot image via network using DHCP/TFTP protocol

Usage:
dhcp [loadAddress] [[hostIPaddr:]bootfilename]
The DHCP server, TFTP server and the target needs to be reside in the same network.

Hereby, a test binary called 'fip.bin' will be now transmitted from the TFTP server via network to the target device memory. The used address of 0x64000000 is chosen randomly and points to an unused DDR memory section.

m => dhcp 0x64000000 fip.bin
port0 Waiting for PHY auto negotiation to complete........ done
Using port0 device
TFTP from server 192.168.0.1; our IP address is 192.168.0.20
Filename 'fip.bin'.
Load address: 0x64000000
Loading: ######################################
         106.4 KiB/s
done
Bytes transferred = 553376 (871a0 hex)

Now, the 'fip.bin' data is copied the target memory and can be e.g. written into an eMMC partition or in NOR flash device.

7.2.4. Boot image

This chapter shows some update examples.

In the first step, we have to check the UBoot environment variables inside the UBoot console. Therefore enter UBooot console by following routine:

  1. Reset the board and wait for the UBoot autoboot stage

  2. Press any key to stop autoboot timer in order to get a U-Boot console prompt.

Make sure that following environment variables are available as shown.

m => env print

fdt_high=0xffffffff
initrd_high=0xffffffff
baudrate=115200
bootdelay=3
bootcmd=run mmc_boot
loadaddr=0x64000000
mmc_unzip_loadaddr=0x80000000
mmc_bak=6
mmc_boot=run mmc_tryboot; run mmc_swap; run mmc_tryboot
mmc_cur=5
mmc_dev=mmc 0
mmc_format=gpt guid ${mmc_dev} mmc_guid; gpt write ${mmc_dev} ${mmc_part}; env save
mmc_part=uuid_disk=${mmc_guid}; name=fip,start=32K,size=128MiB,type=system; name=fip.bak,size=128MiB,type=system; name=Env,size=2MiB,type=data; name=Env.bak,size=2MiB,type=data; name=Boot0,size=1GiB,type=linux; name=Boot1,size=1GiB,type=linux; name=Data,size=-,type=linux;
mmc_swap=env set _mmc_tmp ${mmc_bak}; env set mmc_bak ${mmc_cur}; env set mmc_cur ${_mmc_tmp}; env set _mmc_tmp; env save
mmc_tryboot=run mmc_load; if test $? = 0; then setenv mtdroot root_next=/dev/mmcblk0p${mmc_cur}; run ramboot; fi;
mmc_load=ext4load ${mmc_dev}:${mmc_cur} ${loadaddr} Image.itb
ramboot=bootm start ${loadaddr}#${pcb}; bootm loados ${loadaddr}#${pcb}; bootm ramdisk ${loadaddr}#${pcb}; run set_rootargs; run setup; bootm fdt ${loadaddr}#${pcb}; bootm prep ${loadaddr}#${pcb}; bootm go ${loadaddr}#${pcb}
setup=setenv bootargs console=${console} ${mtdparts} ${rootargs} ${mtdroot} fis_act=${active} ${bootargs_extra}
rootargs_mmc=setenv rootargs root=/dev/mmcblk0p${mmc_cur} ro rootwait
rootargs_ram=setenv rootargs root=/dev/ram0 ro rootwait
set_rootargs=if test $initrd_start = 0; then run rootargs_mmc; else; run rootargs_ram; fi;
div_512=setexpr _tmp_ ${filesize} + 0x1ff; setexpr filesize_512 ${_tmp_} / 0x200; env set _tmp_
fip_fw=lan966x_b0.fip
fip_fw_dl=dhcp ${loadaddr} ${fip_fw}
nor_boot=sf probe; env set active linux; run nor_tryboot; env set active linux.bk; run nor_tryboot
nor_dlup=dhcp ${nor_image}; run nor_update
nor_fip_upd=sf probe; sf update ${loadaddr} 0 ${filesize}
nor_fip_dlup=run fip_fw_dl; run nor_fip_upd
nor_image=brsdk_standalone_arm.itb
nor_only=env set mtdparts mtdparts=${nor_parts};env set bootcmd run nor_boot;env save
nor_parts=spi0:1536k(fip),256k(Env),256k(Env.bk),25m(linux),25m(linux.bk),12m(rootfs_data)
nor_tryboot=sf read ${loadaddr} 200000 1900000; run ramboot
nor_update=sf probe; sf update ${fileaddr} 200000 ${filesize}
mmc_fip0_upd=run div_512; mmc write ${loadaddr} ${mmc_offset_fip0} ${filesize_512}
mmc_fip0_dlup=run fip_fw_dl; run mmc_fip0_upd
mmc_fip1_upd=run div_512; mmc write ${loadaddr} ${mmc_offset_fip1} ${filesize_512}
mmc_fip1_dlup=run fip_fw_dl; run mmc_fip1_upd
mmc_fip01_dlup=run fip_fw_dl; run mmc_fip0_upd; run mmc_fip1_upd
mmc_fw=brsdk_standalone_arm.ext4.gz
mmc_dl=dhcp ${loadaddr} ${mmc_fw}; unzip ${loadaddr} ${mmc_unzip_loadaddr}
mmc_boot0_upd=run div_512; mmc write ${mmc_unzip_loadaddr} ${mmc_offset_boot0} ${filesize_512}
mmc_boot0_dlup=run mmc_dl; run mmc_boot0_upd
mmc_boot1_upd=run div_512; mmc write ${mmc_unzip_loadaddr} ${mmc_offset_boot1} ${filesize_512}
mmc_boot1_dlup=run mmc_dl; run mmc_boot1_upd
mmc_boot01_dlup=run mmc_dl; run mmc_boot0_upd; run mmc_boot1_upd
mmc_offset_fip0=0x40
mmc_offset_fip1=0x40040
mmc_offset_boot0=0x82040
mmc_offset_boot1=0x282040
mmc_offset_data=0x482040
console=ttyS0,115200n8
mtdparts=mtdparts=spi0:1536k(fip),256k(Env),256k(Env.bak)
bootargs_extra=uio_pdrv_genirq.of_id=generic-uio loglevel=1

Use the env set command if something is wrong or missing and remember to use the env save command when you are done. There might be other environment variables defined, but you can safely ignore them.

Some explanation for the predefined environment variables and for what they are used for:

  • fdt_high - The value 0xffffffff prevents an extra copy of the flattened device tree.

  • initrd_high - The value 0xffffffff prevents an extra copy of the ramdisk.

  • baudrate - U-Boot console baudrate.

  • bootdelay - Number of seconds to wait for user input before running bootcmd.

  • bootcmd - Command to run automatically at boot. Default is set to run mmc_boot.

  • loadaddr - Temporary address to use when loading images via TFTP or from eMMC.

  • mmc_unzip_loadaddr - Temporarily used address for uncompressing images

  • mmc_bak - The backup partition index for boot1

  • mmc_boot - Try first to load 'brsdk_standalone_arm.ext4.gz' from active partition. If failing then backup partition will be tried

  • mmc_cur - The default partition index for boot0

  • mmc_dev - eMMC device to use in read/write commands.

  • mmc_format - Format eMMC device according defined partition layout

  • mmc_part - Partition layout definitions to use in 'mmc_format'.

  • mmc_swap - Change active partition from 'Boot0' to 'Boot1' and vice versa

  • mmc_tryboot - Seeking for available boot images

  • mmc_load - Try to load an ITB image from the active partition

  • ramboot - Try to load an run an ITB image from memory

  • setup - Configuring bootargs environment variable

  • rootargs_mmc - Configuration for rootfs in eMMC

  • rootargs_ram- Configuration for rootfs in ram

  • set_rootargs - Set correct configuration for root file system

  • div_512 - Calculates the number of required flash pages (512 bytes)

  • fip_fw - Defines the name of the FIP file used for eMMC and NOR update

  • fip_fw_dl - Configuring and starting the DHCP request for file download

  • nor_fip_upd - Writes the FIP data to the NOR flash device

  • nor_fip_dlup - Download and write the FIP data to NOR flash device

  • mmc_fip0_upd - Writes FIP data to the eMMC device in partition 'fip'

  • mmc_fip_dlup - Download and write the FIP data to eMMC device

  • mmc_fip1_upd - Writes FIP data to the eMMC device in partition 'fip.bak'

  • mmc_fip1_dlup - Download and write the FIP data to eMMC device

  • mmc_fip01_dlup - Download FIP and write data to partition 'fip0' and 'fip1'

  • mmc_fw - Defines the name of the ext4.gz file for eMMC update

  • mmc_dl - Download ext4.gz file and uncompress data into target memory

  • mmc_boot0_upd - Writes the uncompressed data to the eMMC device in partition 'boot0'

  • mmc_boot0_dlup - Download, uncompress and write the image data to eMMC device

  • mmc_boot1_upd - Writes the uncompressed data to the eMMC device in partition 'boot1'

  • mmc_boot1_dlup - Download, uncompress and write the image data to eMMC device

  • mmc_boot01_dlup - Download, uncompress and write data to partition 'boot0' and 'boot1'

  • mmc_offset_fip0 - GPT address offset of the 'fip' partition

  • mmc_offset_fip1 - GPT address offset of the 'fip.bak' partition

  • mmc_offset_boot0 - GPT address offset of the 'boot0' partition

  • mmc_offset_boot1 - GPT address offset of the 'boot1' partition

  • mmc_offset_data - GPT address offset of the 'data' partition

  • console - Configuration settings for the console terminal

  • mtdparts - NOR flash partition configuration

  • bootargs_extra - Additional UBoot arguments

The following examples assumes that the build artifacts of brsdk_standalone_arm.ext4.gz and/or lan966x_b0.fip are available on the TFTP server.

7.2.4.1. from eMMC

For a successful eMMC boot, a special partition layout needs to be make available on the flash device. This can be achieved by following two approaches:

Use the already defined UBoot console command of 'mmc_format':

m => run mmc_format
success!
Writing GPT: success!
Saving Environment to MMC... Writing to redundant MMC(0)... OK

or

Write a GPT image directly to the blank eMMC device, like described in the eMMC GPT section.

For checking the partition layout, use the UBoot command of 'mmc part'.This is the expected partition layout here:

m => mmc part

Partition Map for MMC device 0  --   Partition Type: EFI

Part    Start LBA       End LBA         Name
        Attributes
        Type GUID
        Partition GUID
  1     0x00000040      0x0004003f      "fip"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   00042021-0408-4601-9dcc-a8c51255994f
  2     0x00040040      0x0008003f      "fip.bak"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   8ef917d1-2c6f-4bd0-a5b2-331a19f91cb2
  3     0x00080040      0x0008103f      "Env"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   77877125-add0-4374-9e60-02cb591c9737
  4     0x00081040      0x0008203f      "Env.bak"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   b4b84b8a-04e3-48ae-8536-aff5c9c495b1
  5     0x00082040      0x0028203f      "Boot0"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   35219908-c613-4b08-9322-3391ff571e19
  6     0x00282040      0x0048203f      "Boot1"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   8e123a33-e3d3-4db9-92f4-d3ebd9b3224f
  7     0x00482040      0x00e8ffde      "Data"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   02a90af2-5d1c-4a29-9177-97a513e3cae4

Verify that Start LBA in each partition equals the partition addresses in the corresponding environment variable mmc_p<n>. Please see also chapter eMMC/SDCard default partition schema.

The following scenario will now upload an brsdk_standalone_arm.ext4.gz file, which is containing an ext4 rootfs and including an ITB in the root directory.

Following steps needs to be applied therefore:

Run the mmc_boot0_dlup command to load the brsdk_standalone_arm.ext4.gz file via DHCP to the target memory. Afterwards, the file will be uncompressed and written into the eMMC partition 'Boot0'.

m => run mmc_boot0_dlup
port0 Waiting for PHY auto negotiation to complete........ done
Using port0 device
TFTP from server 192.168.0.1; our IP address is 192.168.0.10
Filename 'brsdk_standalone_arm.ext4.gz'.
Load address: 0x64000000
Loading: #################################################################
         ###### ...........
         #################################################################
         #########################
         6.2 MiB/s
done
Bytes transferred = 106115072 (6533000 hex)

MMC write: dev # 0, block # 8192, count 208960 ... 208960 blocks written: OK

If UBoot run in its default configuration, it will do now all needed actions, and make the rootfs and ITB available in the expected eMMC partition.

7.2.4.2. from network

Running the fip_fw_dl command will upload the lan966x_b0.fip file using the DHCP/TFTP connection.

m => fip_fw_dl
port0 Waiting for PHY auto negotiation to complete........ done
Using port0 device
TFTP from server 192.168.0.1; our IP address is 192.168.0.10
Filename 'lan966x_b0.fip'.
Load address: 0x64000000
Loading: #################################################################
         ###### ...........
         #################################################################
         #########################################
         2.9 MiB/s
done
Bytes transferred = 22538412 (157e8ac hex)

Afterwards the command of ramboot will execute the image inside the memory. For example:

## Loading kernel from FIT Image at 64000000 ...

Using Device Tree in place at 67d00000, end 67d07977

Starting kernel ...

For configuring the device permanently to the network boot mode, set the environment variable of bootcmd as shown below:

m => setenv bootcmd 'run fip_fw_dl; run ramboot'
m => saveenv
m => reset

After reset, UBoot will run the sequence of bootcmd on every target startup.

7.2.4.3. from NOR

No matter if you have a eMMC equipped evaluation board you can also select to store the boot image in SPI NOR flash only and use this image as the boot media.

This will not be as fast as booting from eMMC but can be used as a fallback solution in case the first option is not available for some other reason.

To set the u-boot env to boot from nor it is required to run this command:

m => run nor_only

This will partitioned the NOR like this:

m => mtd list
List of MTD devices:
* nor0
  - device: spi-flash@0
  - parent: qspi@e0834000
  - driver: jedec_spi_nor
  - path: /ahb/apb/qspi@e0834000/spi-flash@0
  - type: NOR flash
  - block size: 0x1000 bytes
  - min I/O: 0x1 bytes
  - 0x000000000000-0x000000200000 : "nor0"
          - 0x000000000000-0x000000180000 : "fip"
          - 0x000000180000-0x0000001c0000 : "Env"
          - 0x0000001c0000-0x000000200000 : "Env.bk"
          - 0x000000200000-0x000001a00000 : "linux"
          - 0x000001a00000-0x000003400000 : "linux.bk"
          - 0x000003400000-0x000004000000 : "rootfs_data"

As you can see there are two 25MB linux partitions (a main and a backup) that can be used to store a FIT image.

To add an image in the NOR flash it is required to download the image and write it in the NOR using the command:

m => run nor_dlup

You can boot the system with the run nor_boot command.

7.2.5. Program image

The UBoot console can also be used for programming a new image. This can be the case for some update reasons. But therefore, a running system with UBoot needs to be available on the target.

7.2.5.1. to eMMC

In the first step, we have to boot into UBoot console like following description:

  1. Reset the board and wait for the UBoot autoboot stage

  2. Press any key to stop autoboot timer in order to get a U-Boot console prompt.

Now we will upload a GPT image like e.g. lan966x_b0-release-mmc.gpt to the target memory.

m => dhcp 0x64000000 lan966x_b0-release-mmc.gpt
port0 Waiting for PHY auto negotiation to complete........ done
Using port0 device
TFTP from server 192.168.0.1; our IP address is 192.168.0.10
Filename 'lan966x_b0-release-mmc.gpt'.
Load address: 0x64000000
Loading: #################################################################
         #################################################################
         ###### ...........
         #################################################################
         #######
         6.1 MiB/s
done
Bytes transferred = 104890368 (6408000 hex)

Now the image data is uploaded to the target memory and can be written to the flash device.

Lets focus on the next two upcoming commands. The first command converts the uploaded filesize to the required number of flash pages (512 byte). The second command is writing the image data to the eMMC flash device.

Important is here, to set the write offset address of 0x0 (zero) for the flash.

m => run div_512
m => mmc write ${loadaddr} 0x0 ${filesize_512}

MMC write: dev # 0, block # 0, count 208960 ... 208960 blocks written: OK

7.3. Update image from Linux

A running Linux system on the target can also be used for image update purpose. Therefore a network connection from the target to the host system needs to be established first. Afterwards a working TFTP server needs to make available in the same network.

Using the fdisk command will dump the available partitions on the eMMC. This is useful for checking the proper partition index identifier.

The device /dev/mmcblk0p<n> corresponds to partition <n>.

# fdisk -l
Found valid GPT with protective MBR; using GPT

Disk /dev/mmcblk0: 15269888 sectors, 3360M
Logical sector size: 512
Disk identifier (GUID): 671e9526-c34a-4bc9-9670-bfebb6dba410
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 15269854

Number  Start (sector)    End (sector)  Size Name
     1              64          262207  128M fip
     2          262208          524351  128M fip.bak
     3          524352          528447 2048K Env
     4          528448          532543 2048K Env.bak
     5          532544         2629695 1024M Boot0
     6         2629696         4726847 1024M Boot1
     7         4726848        15269854 5147M Data

7.3.1. Update FIP

One way to upload the e.g. lan966x_b0-release.fip file, is to use a TFTP client inside the running Linux.

Therefore attach the putty console to the target and upload the FIP file using the 'dhcp' or 'tftp' command in an e.g. /temp folder on the target.

Afterwards the file can be written by using the dd command into the proper device partition.

In this example, we will write the data into the partition named to fip which can be mapped to /dev/mmcblk0p1.

dd if=/temp/lan966x_b0-release.fip of=/dev/mmcblk0p1

After rebooting of the target, the updated file will be executed now.

7.3.2. Update ext4-img

The same approach as described before, can be applied also for updating the brsdk_standalone_arm.ext4.gz binary.

Upload the file using e.g. TFTP to a /temp folder or to a destination folder of your preference. In this folder, it needs to be unzipped first.

Afterwards write the file by using the dd command to the proper device partition.

In this example, we will write the data into the partition named to Boot0 which can be mapped to /dev/mmcblk0p5.

dd if=/temp/ext4-itb-bare.ext4 of=/dev/mmcblk0p5

After rebooting of the target, the updated file will be executed now.

8. TERMS and ABBREVIATIONS

BL1             Boot Loader 1: In secure immutable ROM (Trusted ROM Firmware)
BL2             Boot Loader 2: In secure on-chip RAM, temporary (Trusted Boot
                Firmware)
BL31            Boot Loader 31: Resident secure services (ARM v8)
BL32            Boot Loader 32: Resident secure services (ARM v7)
BL33            Boot Loader 33: Typically U-Boot.
BSSK            Binding Secret Symmetric Key
CLI             Command line interface
DDR             Double Data Rate, memory type
DHCP            Dynamic Host Configuration Protocol
DTB             Device Tree Blob
DTC             Device Tree Compiler
DTS             Device Tree Source files
eMMC            Embedded MultiMediaCard
FCx             Flex Com Interface #x
FIP             Firmware Image Package
FIT             Flattened Image Tree
FS              Filesystem
FW              Firmware
GPT             GUID Partition Table
JTAG            Joint Test Action Group, interface for testing and debugging
KERNEL          The Linux kernel
LBA             Logical Block Address
OTP             One-Time-Programmable Memory
PCIe            Peripheral Component Interconnect Express
PSCI            Power State Coordination Interface
ROOTFS          ROOT File System, used in Linux context
ROT             Root of Trust
ROT-PK          Root of Trust Public Key
ROT-PK-SHA      Root of Trust Public Key SHA (SHA of the public key of the ROT)
ROT-PRIVATE     Root of Trust Private Key
SDCard          Secure Digital Card
SJTAG           Secure JTAG
SoC             System on Chip
SPI             Serial Peripheral Interface
SRAM            Secure Ram
SSK             Secret Symmetric Key
TBBR            Trusted Board Boot Requirements
TF-A            Trusted Firmware for ARMv7 and ARMv8
TFTP            Trivial File Transfer Protocol
UART            Universal Asynchronous Receiver-Transmitter