wiki:provisioning

Provisioning boards

We refer to the act of duplicating a firmware image across multiple boards as Provisioning.

The easiest way to provision boards or removable storage devices is to build the particular BSP you are interested in, and use its tools to create a JTAG image suitable for programming with the Gateworks JTAG dongle (for NAND flash boards) or to create removable storage devices (for NAND-less boards). See linux/ubi.

  • For Ventana click here for instructions on building custom a U-boot environment.

If however you wish to customize a board's configuration in some way that you have not configured into the build system you will want to boot a board, make your customizations, then pull those customizations off and use them to provision further boards. This is what is presented in detail on this page.

SPI / NOR FLASH based boards (Laguna)

Products that use NOR and/or SPI flash have the ability to be uploaded to a host PC via the Gateworks GW16042 JTAG dongle and jtag_usb application.

For these products simply configuring a board the way you want it at runtime then uploading the flash to a file provides you with a firmware image that can then be programmed onto other boards.

Please read more about JTAG upload here: JTAG Instructions

Ventana NAND flash based boards

Products that use NAND flash present an issue in that they can contain bad blocks. As a result the raw flash devices can differ in size making it difficult to implement a JTAG flash upload/download scenario.

There are several ways of provisioning NAND bootable boards:

  • using JTAG (this is what Gateworks uses on our production line)
  • using U-Boot (more complex, much faster than JTAG, but does not allow provisioning the SPL)
  • using Linux (even more complex, much faster than JTAG, but allows provisioning the SPL)
  • a combination of the above

Regardless of the method used for provisioning there are several artifacts that you need in order to provision NAND:

  • SPL (secondary program loader)
  • u-boot.img (bootloader)
  • env (bootloader env)
  • ubi (unsorted block image containing ubifs filesystem)

Pulling Software off of an Existing Board

SPL and Bootloader

The SPL and u-boot.img are built artifacts (which can be downloaded from ​http://dev.gateworks.com/ventana/images).

Bootloader Environment

The env can be blank, which will use built-in defaults, or can be customized and extracted from the flash.

To create and extract a bootloader env:

  1. Create the env on a board:
    # blank per-board vars (which are set from eeprom by default, yet overridable via env)
    setenv fdt_file
    setenv ethaddr
    setenv eth1addr
    # perform any other desired changes
    # save
    saveenv
    
  2. Extract the env from the board and save to removable storage:
    • from Linux
      dd if=/dev/mtd1 of=env bs=1M
      
    • from U-Boot:
      # read the env (environment) partition into temporary memory, note the size reported below as 0x100000
      
      Ventana > nand read ${loadaddr} env
      
      NAND read: device 0 offset 0x1000000, size 0x100000
       1048576 bytes read: OK
      Ventana > 
      
      # store it to file on micro-SD with an ext4 fs (size re-used from above)
      mmc dev 0 && ext4write mmc 0:1 ${loadaddr} /env 0x100000
      
      # or store it to file on USB mass storage with an ext4 fs
      usb start && usb dev 0 && ext4write usb 0:1 ${loadaddr} /env 0x100000
      
    • Note that you may find it easier to build yourself a custom bootloader with defaults that match your needs rather than deal with extracting and imaging an env flash partition
    • Note that your ext4 filesystem must not have checksums enabled (metadata_csum, a feature added to newer e2fsprogs) as U-Boot does not support this in ext4write.

Root Filesystem

The ubi root filesystem is originally built by the the build system of the specific BSP your using, however if you end up imaging this onto a board, and customizing it, you may be able to pull it back off as long as your flash size is far less than your memory:

  • From Linux assuming /tmp is a tmpfs (ram based) and that you are booted into the filesystem you are copying and you have more ram available than the size of /dev/mtd2 (such as a 256MB flash on a 512MB system)
    dd if=/dev/mtd2 of=/tmp/ubi bs=4M
    
  • From U-Boot
    # read the rootfs (filesystem) partition into temporary memory, note the size reported below as 0xef00000
    
    Ventana > nand read ${loadaddr} rootfs
    
    NAND read: device 0 offset 0x1100000, size 0xef00000
     250609664 bytes read: OK
    
    
    # store it to file on micro-SD with an ext4 fs (size re-used from above)
    Ventana > mmc dev 0 && ext4write mmc 0:1 ${loadaddr} /rootfs 0xef00000
    switch to partitions #0, OK
    mmc0 is current device
    File System is consistent
    update journal finished
    250609664 bytes written in 57489 ms (4.2 MiB/s)
    Ventana > 
    
    # or store it to file on USB mass storage with an ext4 fs
    usb start && usb dev 0 && ext4write usb 0:1 ${loadaddr} /rootfs 0xef00000
    
    • Note that your ext4 filesystem must not have checksums enabled (metadata_csum, a feature added to newer e2fsprogs) as U-Boot does not support this in ext4write.

Flashing Boards with Pulled Software

Once you have all the artifacts you can re-assemble them into a JTAG image suitable for the Gateworks JTAG adapter and software. The following usage of mkimage_jtag will create a jtagable image matching the partitioning described by 'mtdparts=nand:16m(uboot),1m(env),-(rootfs)'

mkimage_jtag -e SPL@0 u-boot.img@14M env@16M ubi@17M > image.bin

Or, for a faster two-step method of imaging using U-Boot with serial and ethernet (to a tftp server with the ubi):

  1. create a JTAG image of the SPL + bootloader + env:
    mkimage_jtag SPL u-boot.img env > image.bin
    
  2. once the above is flashed with the Gateworks JTAG adapter and software you can flash the ubi (much more quickly than via JTAG) within U-Boot
  3. break out into the bootloader, transfer the ubi image from a tftp server into SDRAM, and flash it:
    setenv ipaddr 192.168.1.1 # local ip
    setenv serverip 192.168.1.146 # server ip
    tftp ${loadaddr} image.ubi # tftp ubi image
    nand erase.part rootfs # erase the nand partition named rootfs from the mdtparts variable
    nand write ${loadaddr} rootfs ${filesize} # write the downloaded ubi to rootfs
    

Notes:

  • you can always elect to build your own bootloader with a custom config rather than pulling the env data off a board

micro-SD provisioning

Directly Cloning SD Cards

See linux/blockdev

U-Boot MicroSD Provisioning

The main difference between provisioning removable storage devices such as micro-SD compared to non-removable storage devices (such as NAND flash) is that the removable devices can be potentially booted on a board with a different model, CPU, or memory configuration. This causes us to treat the U-Boot environment differently when we extract it from a configured board.

If you do not want a blank env (which uses built-in defaults) you must provision one board, boot it to the bootloader, customize your env, then extract that env to use when provisioning additional boards.

The Ventana bootloader stores its microSD env on raw block sectors from offset 709K and is 256K in size.

The env can be blank, which will use built-in defaults, or can be customized and extracted.

To create and extract a bootloader env: (only if this is being used, otherwise skip this step)

  1. Create the env on a board:
    # blank per-board vars (which are set from eeprom by default, yet overridable via env)
    setenv fdt_file
    setenv ethaddr
    setenv eth1addr
    # perform any other desired changes
    # save
    saveenv
    
  2. extract the env from a board that boots to micro-SD:
    • from Linux:
      # copy 256KB from offset 709KB to 'env' file
      dd if=/dev/sdc of=env bs=1K skip=709 count=256 oflag=sync
      
    • from U-Boot:
      mmc read ${loadaddr} 0x58a 0x200 # read 512x 512byte blocks (256K) from block 0x1418
      # store it to file on micro-SD with an ext4 fs
      ext4write mmc 0:1 ${loadaddr} /mmc.env 0x40000
      # store it to file on USB mass storage with an ext4 fs
      usb start && usb dev 0 && ext4write usb 0:1 ${loadaddr} /mmc.env 0x40000
      
    • Note that your ext4 filesystem must not have checksums enabled (metadata_csum, a feature added to newer e2fsprogs) as U-Boot does not support this in ext4write.

To place an extracted env onto a micro-SD:

  • from Linux:
    # copy 256KB from file env to offset 709KB:
    dd if=env of=/dev/sdc bs=1K seek=709 count=256 oflag=sync
    

Provisioning root file system from live Newport board

It's always best to create your rootfs from scratch using the Newport BSP when this option is available. If you're prevented from doing so it is possible to provision the root file system from some Newport boards without too much difficulty. Newport SBC's are capable of booting from both eMMC and MMC. The boot device can be selected by the GSC performing a 5x press on the power button. In the following section we will create a bootable microSD card, load it as the primary boot device, image partition 2 of the eMMC using "dd", then create a compressed disk image from this data.

Requirements

  • A Newport board with MMC card slot and push button (GSC must be configured to accept push button input—this is default)
  • A MMC with capacity enough to accommodate full size of eMMC (8GB) along with BSP for performing recovery. Recommended would be a minimum 16GB or 32GB card.
  • A desktop computer with Linux natively installed. This workstation must have a drive capable of accepting an MMC and have packages for DD and Mount.

On your workstation

Download a Gateworks pre-built image. All of our images include the tools necessary to perform this operation, though Ubuntu will likely be the easiest to work with.

wget -N http://dev.gateworks.com/newport/images/focal-newport.img.gz

Insert a micro SD card into your workstation and identify the device name it's been assigned. This can be done using a variety of methods, for example the "dmesg" output. In this example the MMC is "/dev/sdb"

Image the MMC.

zcat focal-newport.img.gz | sudo dd of=/dev/sdb bs=4M

Remove the SD card from your workstation.

On your Newport SBC

Insert the SD card into the SD card reader, then apply power to the SBC (or otherwise turn it on). 5x press the power button, you will see the status LED turn off and back on. The BDK will display microSD as MMC0.

Example output:

	Gateworks Newport SPL (12.7.0-96865d0 Tue Jul 7 21:19:32 UTC 2020)

	GSC     : v55 0xe7e2 RST:BOOT_WDT2 Thermal Protection Enabled
	Temp    : Board:34C/86C CPU:42C/100C
	Model   : GW6400-B1
	MFGDate : 09-23-2019
	Serial  : 802864
	RTC     : 8
	SoC     : CN8020-800BG676-SCP-P12-G 1024KB 800/550MHz 0xa2 Pass 1.2 
	MMC0    : microSD
	MMC1    : eMMC

Proceed with booting to Linux user-space. Once there if you would like to view the rootfs you're about to image it's located at /dev/mmcblk1p2. Doing so is optional.

mount /dev/mmcblk1p2 /mnt

ls /mnt #this will display the eMMC's rootfs

umount /mnt

Image the partition to a file.

dd if=/dev/mmcblk1p2 of=myrootfs.img

"sync" the filesystem and power board off

sync
#remove power

Remove MMC from the SBC.

Create an image

Navigate to the "/tmp" directory on your workstation. In actuality this can be any directory that you have read and write permissions, "/tmp" should only be used if you don't care what happens to these files later.

cd /tmp

Insert the MMC into the SD card reader on your workstation, as before note the the name the device is assigned. Because we created our image in within the rootfs we will need to mount the second partition, for example "/dev/sdb2":

sudo mount /dev/sdb2 /mnt/

ls /mnt/

Copy the image you created of mmcblk1p2 into "/tmp"

cp /mnt/myrootfs.img .

Executing the command "file" on this file will return that it is ext4 filesystem data and the volume name is "rootfs".

Example:

	user@workstation:/tmp$ file myrootfs.img 
	myrootfs.img: Linux rev 1.0 ext4 filesystem data, UUID=951f19a1-cc54-4a07-9b7f-41a54ea8acb4, volume name "rootfs" (needs journal recovery) (extents) (64bit) (large files) (huge files)

Add boot firmware and create a gzipped image.

  • Download boot firmware
    wget http://dev.gateworks.com/newport/boot_firmware/firmware-newport.img
    
  • name it however you please
    cp firmware-newport.img myimg-newport.img
    
  • Create a disk image containing the root filesystem and boot firmware. The boot firmware is 16M so we will "dd" the rootfs using this offset.
    dd if=myrootfs.img of=myimg-newport.img bs=16M seek=1
    
  • gzip the image so it can be installed using standard methods on other Newport boards.
    gzip -k -f myimg-newport.img 
    

Be mindful that the image size can't exceed the total DRAM of the board you plan to install it on if you're using the bootloader command "tftpboot". The "update_all", and "update_rootfs" scripts both use this command

ls -lh myimg-newport.img.gz #size must be less than total DRAM of board

Flash this image to a Newport SBC:

In the bootloader:

GW6400-B1> setenv ipaddr 192.168.1.52
GW6400-B1> setenv serverip 192.168.1.56
GW6400-B1> setenv image myimg-newport.img.gz
GW6400-B1> setenv dev 0
GW6400-B1> run update_all 
Last modified 4 months ago Last modified on 07/14/2020 08:52:32 PM