Changes between Version 47 and Version 48 of buildroot


Ignore:
Timestamp:
12/01/2021 11:22:30 PM (8 months ago)
Author:
Cale Collins
Comment:

added venice SWupdate section

Legend:

Unmodified
Added
Removed
Modified
  • buildroot

    v47 v48  
    924924Note that if you require support for SWUpdate to complete an install that isn't already there (for example you want to add the capability to update GSC firmware via the gsc_update utility) you will either need to a) add a static linked version of that tool to your image or b) do a 2-stage update where you add the required tools first, then use them in a future update
    925925
     926=== For Venice
     927
     928In this example Buildroot branch 2021.08.x was used.
     929
     930Here are the relevant files to add to your buildroot directory:
     931 * '''configs/venice_swupdate_defconfig''': Buildroot defconfig (represents the minimal 'changes' made to buildroot default config):
     932{{{#!bash
     933cat << EOF > configs/venice_swupdate_defconfig
     934BR2_aarch64=y
     935BR2_KERNEL_HEADERS_5_10=y
     936BR2_ROOTFS_OVERLAY="overlay"
     937BR2_LINUX_KERNEL=y
     938BR2_LINUX_KERNEL_CUSTOM_GIT=y
     939BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/Gateworks/linux-venice.git"
     940BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="v5.10.18-venice"
     941BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
     942BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="venice_minimal_kernel_defconfig"
     943BR2_LINUX_KERNEL_INSTALL_TARGET=y
     944BR2_PACKAGE_UBOOT_TOOLS=y
     945BR2_PACKAGE_OPENSSL=y
     946BR2_PACKAGE_LIBCONFIG=y
     947BR2_PACKAGE_JSON_C=y
     948BR2_PACKAGE_LIBCURL=y
     949BR2_PACKAGE_SWUPDATE=y
     950BR2_PACKAGE_SWUPDATE_CONFIG="swupdate.config"
     951BR2_TARGET_ROOTFS_EXT2=y
     952BR2_TARGET_ROOTFS_EXT2_4=y
     953BR2_TARGET_ROOTFS_EXT2_GZIP=y
     954EOF
     955}}}
     956  - Note that SWupdate reuqires ZLIB if we are going to use gzip compression
     957
     958 * '''Download or create a defconfig:'''
     959{{{#!bash
     960wget http://dev.gateworks.com/buildroot/venice/minimal/venice_minimal_kernel_defconfig
     961}}}
     962 * '''overlay/etc/fw_env.config''': config file for u-boot env tools fw_setenv
     963{{{#!bash
     964mkdir overlay
     965mkdir overlay/etc
     966cat << EOF > overlay/etc/fw_env.config
     967# Device               offset          Env. size
     968/dev/mmcblk2           0xff0000        0x8000
     969/dev/mmcblk2           0xff8000        0x8000
     970EOF
     971}}}
     972  - Note that this file is whitespace sensitive
     973 * '''Create swupdate.config config file to build swupdate executable which drives the update process.'''
     974{{{#!bash
     975cat << EOF > swupdate.config
     976# We do not need MTD or LUA support
     977# CONFIG_MTD is not set
     978# CONFIG_LUA is not set
     979CONFIG_SIGNED_IMAGES=y
     980CONFIG_ENCRYPTED_IMAGES=y
     981# Suricatta provides support for fetching updates via a Hawkbit server if desired
     982CONFIG_SURICATTA=y
     983CONFIG_SURICATTA_SSL=y
     984CONFIG_SURICATTA_STATE_CHOICE_BOOTLOADER=y
     985# We need the raw handler to image to an MMC partition
     986CONFIG_RAW=y
     987# We need the shellscript handler for our update.sh shellscript
     988CONFIG_SHELLSCRIPTHANDLER=y
     989# We need the bootloader handler to alter the u-boot environment
     990CONFIG_BOOTLOADERHANDLER=y
     991EOF
     992}}}
     993  * Note: The "BR2_PACKAGE_SWUPDATE_CONFIG=" Buildroot config argument could potenially point to an existing file, edit this peramater using menuconfig to point to the file you're creating here.
     994 * '''sw-description''': part of the actual firmware OTA which describes the process and file manifest of the update image. See [https://sbabic.github.io/swupdate/sw-description.html# here] for syntax
     995{{{#!bash
     996cat << EOF > sw-description
     997software =
     998{
     999        version = "0.1.0";
     1000        description = "Firmware update for XXXXX Project";
     1001
     1002        /* images installed to the system */
     1003        images: (
     1004                {
     1005                        filename = "venice_swupdate.ext2.gz";
     1006                        device = "/dev/update";
     1007                        type = "raw";
     1008                        sha256 = "b443d32b1f2036d731a423f1c9fd6c05731eb107b48b84bc42be95c0c7b31f03";
     1009                        compressed = true;
     1010                }
     1011        );
     1012
     1013        scripts: (
     1014                {
     1015                        filename = "update.sh";
     1016                        type = "shellscript";
     1017                        sha256 = "80463da620c42e02f51b360a33a34d0f180992cbd398c0ea6db0a5d838fa3739";
     1018                }
     1019        );
     1020}
     1021EOF
     1022}}}
     1023  * Note: You will need to generate your own sha256, use the "sha256sum" command to do this.  Check that your filename is accurate.
     1024
     1025- '''update.sh''': This is the script that SWUpdate runs which we use as both a preinst and psotinst script (via cmdline). We determine the current root device and, flip it, and symlink /dev/update to the device to update to. We don't have to do the image install as we've configured SWUpdate to do that for us in sw-descrption images.
     1026{{{#!bash
     1027#!/bin/sh
     1028cat << EOF > sw-descrption
     1029if [ $# -lt 1 ]; then
     1030        exit 0;
     1031fi
     1032
     1033function get_current_root_device
     1034{
     1035        for i in `cat /proc/cmdline`; do
     1036                if [ ${i:0:5} = "root=" ]; then
     1037                        CURRENT_ROOT="${i:5}"
     1038                fi
     1039        done
     1040}
     1041
     1042# ping-pong between /dev/mmcblk2p1 and /dev/mmcblk2p2
     1043# (adapt for your partitioning scheme and/or root device type)
     1044function get_update_part
     1045{
     1046        CURRENT_PART="${CURRENT_ROOT:-/dev/mmcblk2p1}"
     1047        if [ $CURRENT_PART = "/dev/mmcblk2p1" ]; then
     1048                UPDATE_PART="2";
     1049        else
     1050                UPDATE_PART="1";
     1051        fi
     1052}
     1053
     1054function get_update_device
     1055{
     1056        UPDATE_ROOT=${CURRENT_ROOT%?}${UPDATE_PART}
     1057}
     1058
     1059
     1060if [ $1 == "preinst" ]; then
     1061        # get the current root device
     1062        get_current_root_device
     1063
     1064        # get the device to be updated
     1065        get_update_part
     1066        get_update_device
     1067
     1068        # create a symlink for the update process
     1069        ln -sf $UPDATE_ROOT /dev/update
     1070fi
     1071
     1072if [ $1 == "postinst" ]; then
     1073        # get the current root device
     1074        get_current_root_device
     1075
     1076        # get the device to be updated
     1077        get_update_part
     1078        get_update_device
     1079
     1080        # toggle rootpart
     1081        # we do it twice to write to both primary/secondary env
     1082        fw_setenv mmcbootpart $UPDATE_PART
     1083        fw_setenv mmcbootpart $UPDATE_PART
     1084fi
     1085EOF
     1086}}}
     1087
     1088* '''With these files created proceed with the build:'''
     1089{{{#!bash
     1090# build buildroot rootfs
     1091make venice_swupdate_defconfig
     1092make
     1093# create a private/public key combo for signature verifcation
     1094openssl genrsa -out swupdate-priv.pem # private
     1095openssl rsa -in swupdate-priv.pem -out swupdate-public.pem -outform PEM -pubout # public
     1096# sign the sw-description
     1097openssl dgst -sha256 -sign swupdate-priv.pem sw-description > sw-description.sig
     1098# build swupdate image
     1099cp output/images/rootfs.ext2.gz ./venice_swupdate.ext2.gz
     1100for i in sw-description sw-description.sig update.sh venice_swupdate.ext2.gz; do
     1101        echo $i; done | cpio -ov -H crc > my-software.swu
     1102}}}
     1103 * Note that you can skip the inclusion of sw-description.sig and the pub/priv key if you don't care about signatures and have not define CONFIG_SIGNED_IMAGES in your swupdate.config
     1104* '''create an MBR partition table that defines LinuxA and LinuxB partitions we will ping-pong between.'''
     1105{{{#!bash
     1106# 1: 32768:4194304 (2GiB) LinuxA
     1107# 2: 4227072:4194304 (2GiB) LinuxB
     1108# 3: 8421376:4194304(2GiB) userdata
     1109wget -q https://raw.githubusercontent.com/Gateworks/bsp-newport/sdk-10.1.1.0-newport/ptgen
     1110/bin/bash ptgen \
     1111-p 0x83:32768:4194304 \
     1112-p 0x83:4227072:4194304 \
     1113-p 0x83:8421376:4194304 \
     1114> output/images/mbr.bin
     1115}}}
     1116 * Note: How did we arive at these values?  "0x83" is the Linux partition type, "32768" is 16MB (the boot firmware offset) in 512 byte blocks, "4194304" is 2GiB in 512 byte blocks, this will be the length of the partition, "4227072" is the offset plus the length of the partition, this is where the next partion will start. 
     1117 * Bonus fact, here's a way to calculate these values on the command line:
     1118{{{#!bash
     1119echo $((16*1024*1024)) # 16MB in bytes
     1120echo $((16*1024*1024/512)) # to 512 byte blocks.
     1121printf "0x%x\n" $((16*1024*1024)) # to hex
     1122}}}
     1123* '''Boot the board, break out in the bootlader, then update the partition table:'''
     1124{{{#!bash
     1125tftpboot ${loadaddr} mbr.bin && mmc dev 2 && mmc write ${loadaddr} 0 1 # mbr is at 0 and 1 sector long
     1126}}}
     1127* '''While in U-Boot install the Buildroot rootfs to the first Linux partition offset (LinuxA)'''
     1128{{{#!bash
     1129tftpboot ${loadaddr} venice_swupdate.ext2.gz && gzwrite mmc 0 ${loadaddr} ${filesize} 0x100000 0x2000000 # rootfsA is at 0x2000000 (32MiB) and we use a 1MiB buffer
     1130}}}
     1131* '''In U-Boot set the env to use the ''mmcbootpart'' variable that our update.sh will need in order to toggle the partition after a successful update. Custom bootargs will also be applied in this step.'''
     1132{{{#!bash
     1133setenv mmcbootpart 2
     1134
     1135setenv bootcmd 'setenv bootargs console=${console} root=/dev/mmcblk2p${mmcbootpart} rootwait rw; setenv fsload load mmc 2:${mmcbootpart}; setenv dir /boot; run loadfdt && $fsload ${kernel_addr_r} boot/Image && booti ${kernel_addr_r} - ${fdt_addr_r}'                                                             
     1136
     1137saveenv
     1138}}}
     1139  - Note the single quotes around the bootargs value as we do not want U-Boot to expand the args until runtime
     1140
     1141* '''After you boot to buildroot you can fetch and install the SWUpdate image with:'''
     1142{{{#!bash
     1143# bring up networking
     1144udhcpc -i eth0
     1145# fetch image
     1146cd /tmp
     1147wget http://myserver/my-software.swu
     1148wget http://myserver/swupdate-public.pem
     1149swupdate -i my-software.swu -k swupdate-public.pem
     1150}}}
     1151 * Note that you can skip the -k param have not enabled signed images via CONFIG_SIGNED_IMAGES in your swupdate.config
     1152
     1153'''If you would like these files pre-compiled, download them [http://dev.gateworks.com/fae/swupdate-files.tar.gz Here].'''
     1154
     1155
    9261156== Other Buildroot Wiki Pages
    9271157See also: