Changes between Version 23 and Version 24 of provisioning


Ignore:
Timestamp:
10/24/2023 11:49:25 PM (13 months ago)
Author:
Ryan Erbstoesser
Comment:

refactor with new info from Tim and try to add venice option at the top with a and b options

Legend:

Unmodified
Added
Removed
Modified
  • provisioning

    v23 v24  
    77
    88You could stitch all these various images together into a 'disk image' or 'device image' and flash it as a single object however doing so on a particularly large flash device, say an 8GiB eMMC can take a long time depending on how much data you need to write.
     9
     10== Overall Venice Recommendations
     11This wiki page has a great amount of information.
     12
     13Provisioning refers to flashing 100s or 1000s of boards with the same software when placing a large order with Gateworks. Gateworks typically does not want a 900MB .bin JTAG file because this will take forever to flash. Gateworks prefers a compressed image that shortens the time to flash the eMMC.
     14
     15
     16There are two recommended options from Gateworks:
     17 * Option A:
     18  * Pull off / rip an image of a single known configured system ('gold image') and then flash to 100s of more boards
     19   * Can require consideration of unique information such as serial-number from /proc/device-tree/serial-number, a mac address, or a unique ID from a crypto device when duplicated across 100s of boards
     20 * Option B:
     21  * Create an image programatically by building Ubuntu with changes embedded into the build and then flash to 100s of more boards
     22
     23
     24=== Option A Details
     25  * Pull off an image of a single known configured system ('gold image') and then flash to 100s of more boards
     26   * Can require consideration of unique information such as serial-number from /proc/device-tree/serial-number, a mac address, or a unique ID from a crypto device when duplicated across 100s of boards
     27
     281. Boot target to a Linux rescue image
     292. Use the rescue image to create a tarball of your partitions, for example eMMC partition 1 (mmcblk2p1 on venice)
     30{{{
     31# copy partition table (or just re-create it manually during the install)
     32dd if=/dev/mmcblk2 of=/tmp/partition-table bs=1M count=1
     33# create a tarball of the partition
     34mount /dev/mmcblk2p1 /mnt
     35tar --numeric-owner -cJf /tmp/mmcblk2p1.tar.xz -C /mnt .
     36}}}
     37
     38You will either need to store this on a mounted removable storage device partition or store to ramdisk (as above) and transfer them via network. If the compressed data exceeds the size of the ramdisk you will need to go straight to removable storage.
     39
     40The reason you do not want to simple compress the entire eMMC device (/dev/mmcblk2 on Venice) or partition (/dev/mmcblk2p1 for example) is because this will end up a) compressing unused data which will very likely not compress well because it is un-allocated and likely random data b) also ends up writing all unused data which takes a lot of time during the installation process
     41
     42To install your 'gold image' on a target:
     431. Boot to a Linux rescue image (below)
     442. Run a script that creates your partition table and partition contents from the partition tarballs, for example eMMC partition 1 (mmcblk2p1 on venice)
     45{{{
     46# install the saved partition table
     47dd if=/tmp/partition-table of=/dev/mmcblk2
     48# or create partition table, ie start at 1MiB (2048 512byte blocks) and end at the extent of the device
     49printf "2048,,L,,\n" | sudo sfdisk -uS /dev/mmcblk2
     50# create an ext4 fs on partition 1
     51mkfs.ext4 -q -F -L rootfs /dev/mmcblk2p1
     52# mount it
     53mount /dev/mmcblk2p1 /mnt
     54# extract the tarball to it
     55tar -C /mnt -xf /tmp/mmcblk2p1.tar.xz --keep-directory-symlink
     56# unmount it
     57umount /dev/mmcblk2p1
     58}}}
     59
     60Repeat the above for all partitions and follow-up with any additional per-device modifications you would like to make (ie doing something that depends on the devices serial-number from /proc/device-tree/serial-number, a mac address, or a unique ID from a crypto device.
     61
     62=== Option B Details
     63Create an image programatically by building Ubuntu with changes embedded into the build and then flash to 100s of more boards.
     64
     65If you want a more 'programmatic' way of creating your image that doesn't involve ripping the contents of a 'gold image' that may have been created through a complex variety of manual steps (Some engineers always prefer programmatic approaches):
     661. Create Ubuntu image with packages pre-installed and system pre-configured, see instructions here: [wiki:ubuntu#CreatingUbunturootfsusingqemuandchroot Building Ubuntu Image]
     671. Boot target to a Linux rescue image (below)
     681. Run a script that creates your partition table and partition contents from scratch (using the steps from the previous option)
     69
     70=== Linux Rescue Image
     71A Linux Rescue Image is a self-contained Linux OS that does not rely on an on-board rootfs. This can be a kernel and device-tree with a separate rootfs that is on removable storage, or it can be a kernel with the rootfs built-in (which is how we like to do it at Gateworks just to have one less file/filesystem to worry about).
     72
     73It is very easy to create a Linux Rescue image using buildroot to build the root filesystem as well as the kernel. You can include in buildroot all the tools you find necessary for the operations you need to perform. We post pre-built images on http://dev.gateworks.com/buildroot/venice/minimal and document how to build them at http://trac.gateworks.com/wiki/buildroot#VeniceIMX8M
     74
     75Provided you are using a kernel Image with a built-in rootfs (such as the prebuilt Images we post on http://dev.gateworks.com/buildroot/venice/minimal/) you can boot this via the following in U-Boot:
     76{{{
     77# via TFTP
     78u-boot=> setenv bootargs; tftpboot $kernel_addr_r Image && tftpboot $fdt_addr_r imx8mm-venice-gw72xx-0x.dtb && booti $kernel_addr_r - $fdt_addr_r
     79# via USB Mass Storage device (usb device 0 partition 1)
     80u-boot=> setenv bootargs; usb start && load usb 0:1 $kernel_addr_r Image && load usb 0:1 $fdt_addr_r imx8mm-venice-gw72xx-0x.dtb && booti $kernel_addr_r - $fdt_addr_r
     81# via microSD (mmc device 1 partition 1)
     82u-boot=> setenv bootargs; load mmc 1:1 $kernel_addr_r Image && load mmc 1:1 $fdt_addr_r imx8mm-venice-gw72xx-0x.dtb && booti $kernel_addr_r - $fdt_addr_r
     83}}}
     84
    985
    1086== FLASH programming methods and performance
     
    26102Summary of Pros and Cons of FLASH programming methods:
    27103- JTAG:
    28  - Pro: no dependence on booting firmware already on the boot device (FLASH can be corrupt/blank)
    29  - Con: slow transfer rate
     104 - Pro: No dependence on booting firmware already on the boot device (FLASH can be corrupt/blank)
     105 - Con: Slow transfer rate
    30106- U-Boot:
    31107 - Pro: minimal dependence on boot firmware
     
    78154
    79155
     156
    80157== Hybrid approaches
    81158There are hybrid approaches you may consider as well. You could choose to create a JTAG'able image that contained custom firmware that automatically boots into a provisioning system that uses Linux for example. This JTAG'able image could be small enough to flash quickly over JTAG and you could even elect to have Gateworks pre-program your image on your boards if you have a Gateworks special or custom build. In this situation for example your image could pull a script from the network to complete your provisioning so that the image programmed on your boards can stay consistent but provide you flexibility in modifying the instructions for provisioning later on. This is the most flexible approach.
    82159
    83 Another example of a hyrid approach is to use U-Boot to provision images based on a script of U-Boot commands such that you can program various portions of your disk image at a time. For example if you had a scenario where you have multiple filesystems spread across a large eMMC device you could fetch and program the boot-firmware, partition table, and each filesystem independently keeping the data actually written to your FLASH device as small as possible. While this approach could be done in U-Boot alone, there are likely still multiple advantages to booting a Linux ramdisk image to provide greater flexibility and/or familiarity with tools.
     160Another example of a hybrid approach is to use U-Boot to provision images based on a script of U-Boot commands such that you can program various portions of your disk image at a time. For example if you had a scenario where you have multiple filesystems spread across a large eMMC device you could fetch and program the boot-firmware, partition table, and each filesystem independently keeping the data actually written to your FLASH device as small as possible. While this approach could be done in U-Boot alone, there are likely still multiple advantages to booting a Linux ramdisk image to provide greater flexibility and/or familiarity with tools.
    84161
    85162
     
    93170A very easy way to build a minimal ramdisk Linux based OS is to use buildroot. All you need is basic kernel support for the target board and a minimal set of tools:
    94171- minimal root filesystem (only tools you need for your provisioning needs)
    95 - minimal kernel config (only drivers/features you need for your
    96 provisioning needs)
     172- minimal kernel config (only drivers/features you need for your provisioning needs)
    97173- ramdisk (build artifact will be a 'Image' which is a kernel + ramdisk)
    98174- script that performs the provisioning
     
    134210   - Note we set the rootfs partition bit 2 attribute to mark the partition as BIOS bootable in case you are using the U-Boot generic distro config to look for bootscripts on bootable partitions
    135211   - Note the 'end sector' for the rootfs partition above is 0 meaning it will size to the end of the device
    136   3. create and populate the rootfs partition
     212  3. Create and populate the rootfs partition
    137213{{{#!bash
    138214# fetch tar archives from network
     
    152228umount /mnt
    153229}}}
    154   4. create a bootscript if desired (note this requires understanding of how U-Boot generic distro bootconfig works; you could alternately simply put whatever you need directly into U-boot env below)
     230  4. Create a bootscript if desired (note this requires understanding of how U-Boot generic distro bootconfig works; you could alternately simply put whatever you need directly into U-boot env below)
    155231{{{#!bash
    156232cat <<\EOF > /tmp/bootscript
     
    168244umount /mnt
    169245}}}
    170   5. customize U-Boot env if desired (note this requires understanding where the U-Boot env is located on FLASH)
     246  5. Customize U-Boot env if desired (note this requires understanding where the U-Boot env is located on FLASH)
    171247{{{#!bash
    172248# customize U-Boot env
     
    186262
    187263
    188  * provision a Newport board eMMC with a single ext4 root filesystem from a rootfs and kernel tarball:
     264 * Provision a Newport board eMMC with a single ext4 root filesystem from a rootfs and kernel tarball:
    189265  1. Load and boot kernel+ramdisk buildroot image from TFTP server
    190266{{{#!bash
     
    213289   - Note we set the rootfs partition's bit 2 attribute to mark the partition as BIOS bootable in case you are using the U-Boot generic distro config to look for bootscripts on bootable partitions
    214290   - Note the 'end sector' for the rootfs partition above is 0 meaning it will size to the end of the device
    215   3. create and populate the rootfs partition
     291  3. Create and populate the rootfs partition
    216292{{{#!bash
    217293# fetch tar archives from network
     
    228304umount /mnt
    229305}}}
    230   4. create a bootscript if desired (note this requires understanding of how U-Boot generic distro bootconfig works; you could alternately simply put whatever you need directly into U-boot env below)
     306  4. Create a bootscript if desired (note this requires understanding of how U-Boot generic distro bootconfig works; you could alternately simply put whatever you need directly into U-boot env below)
    231307{{{#!bash
    232308cat <<\EOF > /tmp/bootscript
     
    248324umount /mnt
    249325}}}
    250   5. customize U-Boot env if desired (note this requires understanding where the U-Boot env is located on FLASH)
     326  5. Customize U-Boot env if desired (note this requires understanding where the U-Boot env is located on FLASH)
    251327{{{#!bash
    252328# customize U-Boot env