wiki:newport/firmware-update

Newport Firmware Update

The various components of the 'firmware' on a Newport board which you may want to update from time to time are (lowest level components listed first):

  • GSC firmware
  • BDK components (boot.bin bootstub, board device-tree, init.bin app)
  • Linux device-tree
  • ATF
  • U-Boot bootloader
  • Linux kernel
  • root filesystem

Some of the above components are contained within the embedded FAT12 filesystem and others are placed at offsets within the boot device specified by the Newport 'boot firmware' flash map. Typically you do not want to update the entire boot firmware with a simple dd if=firmware-newport.bin of=/dev/mmcblk0 as this would have the undesired affect of overwriting your U-Boot env and the contents of the embedded FAT12 filesystem that you may not want to alter.

For components which are not contained in the embedded FAT12 fs such as the bootstub, the ATF, and the U-Boot FIP you can update them individually in Linux using dd or in U-Boot using mmc write taking care to place them at the right offset. Note that the BDK provided by Gateworks (modified from the Cavium SDK to support Newport) does not contain any support for redundancy or fallbacks although such features could be implemented in the BDK if you choose. The same can be said for the ARM Trusted Firmware provided by Gateworks (from the Cavium SDK) which loads/verifies/executes the bootloader. The only component that technically can not have a fallback is the bootstub unless you are using trusted boot with flash jump enabled and consider the non-trusted bootstub a backup.

To determine the versions of the various components of the firmware you can use the details stored in the 'version' file on the embedded FAT12 filesystem. These details are created by the Newport BSP Makefile (newport/Makefile) if you need to modify or add to them. The GSC firmware version details can be obtained via the Linux driver sysfs fw_ver and fw_crc properties in '/sys/bus/i2c/devices/0-0020/'.

Updating GSC firmware

The GSC firmware is updated via the gsc_update application running under Linux as described at on the gsc wiki. While it takes only a few seconds to update there is no recovery for a failed update. Gateworks has ensured that this update is robust but can not survive a power-cut or kernel crash in the middle of the update. Updates to the GSC firmware are expected to be rare.

Updating BDK components

The BDK is the 'secondary program loader' that the CN80xx BOOT ROM loads/validates/executes. It consists of several components or stages:

  • bootstub: The first 192KB at the fixed FLASH offset of 0x20000 (non-trusted) and 0x50000 (trusted) is the contents of the 'boot.bin' bootstub (bdk/apps/boot/boot.bin). The bootstub is responsible for very early init including identifying the board, loading the board.dtb from the FAT12 filesystem and loading/verify/executing the 'init app' (bdk/apps/init/init.bin). Updating the bootstub can be done in Linux using dd or in U-Boot using mmc write but you will also need to update the CVM_CLIB flash headers at 0x10000. For example:
    • extract extract the CVM_CLIB headers, the non-trusted bootstub and the trusted bootstub from firmware-newport.img:
      dd if=firmware-newport.img of=bootstub.bin bs=64K skip=1 count=7 # extract 0x10000 to 0x80000
      
    • write it in Linux:
      dd if=bootstub.bin of=/dev/mmcblk0 bs=64K seek=1 count=7 # program 0x10000 to 0x80000
      
    • If you need to update one bootstub without the other you will need to modify the CVM_CLIB headers using the details specified in the CN80XX HRM and performed by the newport/make-bootfs.py script.
  • board.dtb: The 'board.dtb' file (ie gw6300.dtb*, gw6304.dtb*, etc) is loaded/verified by the bootstub and contains very low level board-specific CN80XX configuration details that are outside of the scope of the Linux kernel device-tree bindings such as QLM configuration and DRAM configuration. Updating the board.dtb can be done by mounting the FAT12 filesystem in Linux (/dev/mmcblk0p1) and replacing the file.
  • init.bin: The 'init app' (bdk/apps/init) is responsible for the majority of the low-level board configuration such as configuring the CN80XX DDR controller, QLM's, BGX's, phy's, and various board-specific GPIO's. When complete it will load/validate the Linux device tree from the FAT12 filesystem, then load/validate/execute the ATF from its fixed offset in FLASH at 0xe00000 (14MiB). Updating the init app can be done by mounting the FAT12 filesystem in Linux (/dev/mmcblk0p1) and replacing the init.bin file.

Updating Linux device-tree

The board specific Linux device-tree (ie gw*-linux.dtb*) is loaded by the BDK 'init app' from the embedded FAT12 fs therefor can be updated by mounting the filesystem in Linux (/dev/mmcblk0p1) and replacing the file.

Updating ARM Trusted Firmware (ATF)

The ARM Trusted Firmware exists from '0x0e00000 - 0x0f00000' (1Mib at 14MiB offset) specified by the 'boot firmware' flash map. It will load/verify/execute U-Boot from its FIP image. The ATF can be updated individually from Linux using dd or U-Boot using mmc write but there is a header around it so you must obtain it from the firmware-newport.img.

For example:

  • extract ATF from firmware-newport.img:
    dd if=firmware-newport.img of=atf.bin bs=1M skip=14 count=1 # extract 1MiB@14MiB)
    
  • write it in Linux:
    dd if=atf.bin of=/dev/mmcblk0 bs=1M seek=14 count=1 # program 1MiB@14MiB
    

Updating U-Boot bootloader

The U-Boot bootloader is wrapped in a ATF FIP package placed at '0x0f00000 - 0x0ff00000' (960KiB at 15MiB offset) and is loaded/verified/executed by the ATF. You can update this taking the 'fip.img' created by the Newport BSP Makefile uboot target and using Linux dd or U-Boot mmc-write.

For example:

  • write fip.img in Linux:
    dd if=fip.bin of=/dev/mmcblk0 bs=1M seek=15 # program at 15MiB offset
    

Updating Linux kernel

The Linux kernel exists in the embedded FAT12 filesystem and is loaded by the bootloader boot scripts. It can be updated by mounting /dev/mmcblk0p1 in Linux and replacing the file. How and from where the kernel is loaded can be changed to your liking in the U-Boot env however the Gateworks U-Boot env uses a bootscript which is scanned for by the U-Boot scripts (look over the U-Boot env to follow the 'distro config' bootscript setup). The Ubuntu bootscript in the Newport BSP (newport/ubuntu.scr) uses a compressed kernel in a FIT image (kernel.itb). If wanted your bootscripts can be altered to provide a redundant/alternate kernel based on some U-Boot env var flags and counters that could be modified in Linux with the fw_setenv/fw_printenv tools from the U-Boot package. These are packaged in the u-boot-tools Ubuntu package and you can see example usages in the Newport BSP newport/Makefile.

Updating root filesystem

Updates on the root filesystem are very use specific. You can use a package manager, or use multiple rootfs partitions on the FLASH selected by U-Boot when setting up the bootargs passed to the kernel. A common way to to this would be to use U-Boot variables as flags and counters that are altered within Linux via the fw_setenv/fw_printenv tools from the U-Boot u-boot-tools package. You can see example usages in the Newport BSP newport/Makefile.

Last modified 3 weeks ago Last modified on 04/27/2018 09:11:51 AM