diff --git a/README.md b/README.md index 4348cf0..9992091 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ For usage with Raspberry Pi boards additional layer is required: * branch: master * revision: HEAD +For usage with tegra boards, see usage instructions below + Usage ----- @@ -61,6 +63,58 @@ Above will enable U-boot which Raspberry Pi does not default to, and instead boots straight to Linux. U-boot is required to do the "swapping" of partitions in the "dual-copy" layout. +Usage for Nvidia Jetson (Tegra) Platforms +------ + +The simplest way to use on tegra is to add to a forked copy of +[tegra-demo-distro](https://github.com/OE4T/tegra-demo-distro) which +also contains relevant images and submodules used to build tegra images. +However, this is not strictly required. The only dependency required +is the [meta-tegra](https://github.com/OE4T/meta-tegra) layer. + +Use these instructions to add to tegra-demo-distro on whatever +branch you'd like to target (kirkstone and later are supported). + +``` +cd repos +git submodule add https://github.com/sbabic/meta-swupdate-boards.git +git submodule add https://github.com/sbabic/meta-swupdate +cd ../layers +ln -s ../repos meta-swupdate-boards +ln -s ../repos meta-swupdate +``` + +Then use the `setup-env` script to start a bitbake shell, and add +these layers to your build +``` +bitbake-layers add-layer ../layers/meta-swupdate +bitbake-layers add-layer ../layers/meta-swupdate-boards +``` + +In your local.conf (or distro/machine configuration) add +these lines: +``` +IMAGE_INSTALL:append = " swupdate" +USE_REDUNDANT_FLASH_LAYOUT = "1" +SWUPDATE_CORE_IMAGE_NAME = "demo-image-base" +IMAGE_FSTYPES:append = " tar.gz" +``` +substituting any image in the "SWUPDATE_CORE_IMAGE_NAME" variable. + +Finally, build the update image using: +``` +bitbake update-image-tegra +``` + +After deploying the resulting .swu file to target, run the +update with: +``` +swupdate -i +``` +Then reboot to apply the update. The root partition should change +and the `nvbootctrl dump-slots-info` output should show boot +from the alternate boot slot with `Capsule update status:1`. + Maintainer ---------- diff --git a/conf/layer.conf b/conf/layer.conf index 9d0f6f3..b371e7f 100644 --- a/conf/layer.conf +++ b/conf/layer.conf @@ -11,7 +11,7 @@ BBFILE_PRIORITY_swupdate-boards = "7" LAYERDEPENDS_swupdate-boards = "swupdate" -LAYERSERIES_COMPAT_swupdate-boards = "kirkstone" +LAYERSERIES_COMPAT_swupdate-boards = "kirkstone nanbield" BBFILES_DYNAMIC += " \ atmel:${LAYERDIR}/dynamic-layers/atmel/*/*/*.bb \ @@ -19,4 +19,9 @@ BBFILES_DYNAMIC += " \ \ raspberrypi:${LAYERDIR}/dynamic-layers/raspberrypi/*/*/*.bb \ raspberrypi:${LAYERDIR}/dynamic-layers/raspberrypi/*/*/*.bbappend \ + \ + tegra:${LAYERDIR}/dynamic-layers/meta-tegra/*/*/*.bb \ + tegra:${LAYERDIR}/dynamic-layers/meta-tegra/*/*/*.bbappend \ + tegra:${LAYERDIR}/dynamic-layers/meta-tegra/*/*/*/*.bb \ + tegra:${LAYERDIR}/dynamic-layers/meta-tegra/*/*/*/*.bbappend \ " diff --git a/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra.bb b/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra.bb new file mode 100644 index 0000000..f517c3f --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra.bb @@ -0,0 +1,36 @@ +SUMMARY = "Tegra swupdate update image" +DESCRIPTION = "A swupdate image for demonstrating tegra updates" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "\ + file://sw-description \ + file://bootloader-update.lua \ +" + +inherit swupdate image_types_tegra + +DEPLOY_KERNEL_IMAGE ?= "${@os.path.basename(tegra_kernel_image(d))}" + +ROOTFS_DEVICE_PATH ?= "/dev/disk/by-partlabel" + +# Force image name to include version +SWUPDATE_CORE_IMAGE_NAME ?= "core-image-base" +ROOTFS_FILENAME ?= "${SWUPDATE_CORE_IMAGE_NAME}-${MACHINE}.rootfs.tar.gz" + +# Handle differences in redundant partition naming on t194 platforms +KERNEL_A_PARTNAME = "A_kernel" +KERNEL_A_PARTNAME:tegra194 = "kernel" +KERNEL_A_DTB_PARTNAME = "A_kernel-dtb" +KERNEL_A_DTB_PARTNAME:tegra194 = "kernel-dtb" +KERNEL_B_PARTNAME = "B_kernel" +KERNEL_B_PARTNAME:tegra194 = "kernel_b" +KERNEL_B_DTB_PARTNAME = "B_kernel-dtb" +KERNEL_B_DTB_PARTNAME:tegra194 = "kernel-dtb_b" + +# images to build before building swupdate image +IMAGE_DEPENDS = "${SWUPDATE_CORE_IMAGE_NAME} tegra-uefi-capsules" + +# images and files that will be included in the .swu image +SWUPDATE_IMAGES = "${ROOTFS_FILENAME} tegra-bl.cap ${DEPLOY_KERNEL_IMAGE} ${DTBFILE}" diff --git a/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra/bootloader-update.lua b/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra/bootloader-update.lua new file mode 100644 index 0000000..9412791 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra/bootloader-update.lua @@ -0,0 +1,5 @@ +function postinst() + local success = os.execute("/usr/bin/oe4t-set-uefi-OSIndications") + local result = "oe4t-set-uefi-OSIndications completed with success: " .. tostring(success) + return success, result +end diff --git a/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra/sw-description b/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra/sw-description new file mode 100644 index 0000000..397852d --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-extended/images/update-image-tegra/sw-description @@ -0,0 +1,104 @@ +software = +{ + version = "@@DISTRO_VERSION@@"; + + @@MACHINE@@ = { + hardware-compatibility: [ "1.0" ] + system = { + slot_a : { + partitions: ( + { + type = "diskformat"; + device = "@@ROOTFS_DEVICE_PATH@@/APP_b"; + properties: { + fstype = "ext4"; + force = "true"; + } + } + ); + images: ( + { + filename = "@@ROOTFS_FILENAME@@"; + type = "archive"; + device = "@@ROOTFS_DEVICE_PATH@@/APP_b"; + filesystem = "ext4"; + path = "/"; + installed-directly = true; + preserve-attributes = true; + sha256 = "$swupdate_get_sha256(@@ROOTFS_FILENAME@@)"; + }, + { + filename = "@@DEPLOY_KERNEL_IMAGE@@"; + device = "@@ROOTFS_DEVICE_PATH@@/@@KERNEL_B_PARTNAME@@"; + }, + { + filename = "@@DTBFILE@@"; + device = "@@ROOTFS_DEVICE_PATH@@/@@KERNEL_B_DTB_PARTNAME@@"; + } + + ); + files: ( + { + filename = "tegra-bl.cap"; + path = "/opt/nvidia/esp/EFI/UpdateCapsule/TEGRA_BL.Cap"; + properties = {create-destination = "true";} + } + ); + scripts: ( + { + filename = "bootloader-update.lua"; + type = "lua" + sha256 = "$swupdate_get_sha256(bootloader-update.lua)"; + } + ); + + }; + slot_b : { + partitions: ( + { + type = "diskformat"; + device = "@@ROOTFS_DEVICE_PATH@@/APP"; + properties: { + fstype = "ext4"; + force = "true"; + } + } + ); + images: ( + { + filename = "@@ROOTFS_FILENAME@@"; + type = "archive"; + device = "@@ROOTFS_DEVICE_PATH@@/APP"; + filesystem = "ext4"; + path = "/"; + installed-directly = true; + preserve-attributes = true; + sha256 = "$swupdate_get_sha256(@@ROOTFS_FILENAME@@)"; + }, + { + filename = "@@DEPLOY_KERNEL_IMAGE@@"; + device = "@@ROOTFS_DEVICE_PATH@@/@@KERNEL_A_PARTNAME@@"; + }, + { + filename = "@@DTBFILE@@"; + device = "@@ROOTFS_DEVICE_PATH@@/@@KERNEL_A_DTB_PARTNAME@@"; + } + ); + files: ( + { + filename = "tegra-bl.cap"; + path = "/opt/nvidia/esp/EFI/UpdateCapsule/TEGRA_BL.Cap"; + properties = {create-destination = "true";} + } + ); + scripts: ( + { + filename = "bootloader-update.lua"; + type = "lua" + sha256 = "$swupdate_get_sha256(bootloader-update.lua)"; + } + ); + }; + }; + } +} diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate-genconfig.sh b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate-genconfig.sh new file mode 100644 index 0000000..cbb4f91 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate-genconfig.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +get_current_slot() { + curslot=$(nvbootctrl get-current-slot) + if [ $curslot -eq 1 ]; then + echo "b" + else + echo "a" + fi +} + +. /etc/os-release + +if [ -e /run/mfgdata/serial-number ]; then + SERIALNUMBER=$(cat /run/mfgdata/serial-number) +elif [ -e /sys/module/fuse_burn/parameters/tegra_chip_uid ]; then + SERIALNUMBER=$(cat /sys/module/fuse_burn/parameters/tegra_chip_uid) +else + SERIALNUMBER="unknown" +fi + +BOOTSLOT=$(get_current_slot) + +rm -f /run/swupdate/swupdate.cfg + +extrased= +if [ ! -e /usr/share/swupdate/swupdate.pem ]; then + extrased="-e /public-key-file/d" +fi +sed -e"s,@SWVERSION@,$VERSION_ID," \ + -e"s,@SERIALNUMBER@,$SERIALNUMBER," \ + -e"s,@BOOTSLOT@,$BOOTSLOT," \ + $extrased \ + /usr/share/swupdate/swupdate.cfg.in > /run/swupdate/swupdate.cfg diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate-mods.conf b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate-mods.conf new file mode 100644 index 0000000..e2d491d --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate-mods.conf @@ -0,0 +1,2 @@ +[Service] +ExecStartPre=/usr/libexec/swupdate/swupdate-genconfig diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate.cfg.in b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate.cfg.in new file mode 100644 index 0000000..81bb603 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config/swupdate.cfg.in @@ -0,0 +1,13 @@ +globals: +{ + verbose = false; + loglevel = 3; + select = "system,slot_@BOOTSLOT@"; +}; + +identify : ( + { name = "swversion"; value = "@SWVERSION@" }, + { name = "serialnumber"; value = "@SERIALNUMBER@" }, + { name = "model"; value = "@MODEL@" } +); + diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config_1.0.bb b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config_1.0.bb new file mode 100644 index 0000000..a29abe6 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate-machine-config_1.0.bb @@ -0,0 +1,47 @@ +DESCRIPTION = "Machine-specific configuration for swupdate" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +SRC_URI = "\ + file://swupdate.cfg.in \ + file://swupdate-genconfig.sh \ + file://swupdate-mods.conf \ +" + +SRC_URI:append:secureboot = " \ + file://swupdate.pem \ +" + +SWUPDATE_BOARDNAME ??= "${MACHINE}" +SWUPDATE_HWREVISION ??= "1.0" + +S = "${WORKDIR}" +B = "${WORKDIR}/build" + +do_compile() { + rm -f ${B}/hwrevision + echo "${SWUPDATE_BOARDNAME} ${SWUPDATE_HWREVISION}" > ${B}/hwrevision + sed -e's,@MODEL@,${SWUPDATE_BOARDNAME},g' \ + ${S}/swupdate.cfg.in > ${B}/swupdate.cfg.in +} + +do_install() { + install -d ${D}${sysconfdir} + install -m 0644 ${B}/hwrevision ${D}${sysconfdir}/ + ln -s /run/swupdate/swupdate.cfg ${D}${sysconfdir}/swupdate.cfg + install -d ${D}${datadir}/swupdate + install -m 0644 ${B}/swupdate.cfg.in ${D}${datadir}/swupdate/ + install -d ${D}${libexecdir}/swupdate + install -m 0755 ${S}/swupdate-genconfig.sh ${D}${libexecdir}/swupdate/swupdate-genconfig + install -d ${D}${sysconfdir}/systemd/system/swupdate.service.d + install -m 0644 ${S}/swupdate-mods.conf ${D}${sysconfdir}/systemd/system/swupdate.service.d/ +} + +do_install:append:secureboot() { + install -m 0644 ${S}/swupdate.pem ${D}${datadir}/swupdate/ +} + +FILES:${PN} += "${datadir}/swupdate" +PACKAGE_ARCH = "${MACHINE_ARCH}" +EXTRADEPS = "tegra-redundant-boot" +RDEPENDS:${PN} += "${EXTRADEPS}" diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/archive.cfg b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/archive.cfg new file mode 100644 index 0000000..f8cd2fe --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/archive.cfg @@ -0,0 +1,2 @@ +CONFIG_ARCHIVE=y +CONFIG_LOCALE=y diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/disable-uboot.cfg b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/disable-uboot.cfg new file mode 100644 index 0000000..92a2af8 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/disable-uboot.cfg @@ -0,0 +1,4 @@ +# CONFIG_UBOOT is not set +# CONFIG_UBOOT_FWENV is not set +# CONFIG_UBOOT_DEFAULTENV is not set +CONFIG_BOOTLOADER_NONE=y diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/hash.cfg b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/hash.cfg new file mode 100644 index 0000000..a12299a --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/hash.cfg @@ -0,0 +1,2 @@ +CONFIG_HASH_VERIFY=y +CONFIG_DISABLE_CPIO_CRC=y diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/part-format.cfg b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/part-format.cfg new file mode 100644 index 0000000..3f43f22 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/part-format.cfg @@ -0,0 +1,4 @@ +CONFIG_DISKPART_HANDLER=y +CONFIG_DISKFORMAT_HANDLER=y +# CONFIG_FAT_FILESYSTEM is not set +CONFIG_EXT_FILESYSTEM=y diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/systemd.cfg b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/systemd.cfg new file mode 100644 index 0000000..596aae0 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate/systemd.cfg @@ -0,0 +1,3 @@ +CONFIG_SYSTEMD=y +CONFIG_SOCKET_CTRL_PATH="/run/swupdate/control.sock" +CONFIG_SOCKET_PROGRESS_PATH="/run/swupdate/progress.sock" diff --git a/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate_%.bbappend b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate_%.bbappend new file mode 100644 index 0000000..8f4a4b5 --- /dev/null +++ b/dynamic-layers/meta-tegra/recipes-support/swupdate/swupdate_%.bbappend @@ -0,0 +1,18 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" + +SRC_URI += "\ + file://systemd.cfg \ + file://hash.cfg \ + file://part-format.cfg \ + file://archive.cfg \ + file://disable-uboot.cfg \ +" + +DEPENDS += "e2fsprogs" + +do_install:append() { + rm -rf ${D}${sysconfdir}/swupdate.cfg +} + +RDEPENDS:${PN} += "swupdate-machine-config" +FILES_${PN}:remove = "${sysconfdir}/swupdate.cfg" diff --git a/recipes-extended/images/update-image.bb b/recipes-extended/images/update-image.bb index 1636ba6..4dc65da 100644 --- a/recipes-extended/images/update-image.bb +++ b/recipes-extended/images/update-image.bb @@ -6,10 +6,13 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda inherit swupdate SRC_URI = "\ - file://emmcsetup.lua \ file://sw-description \ " +SRC_URI:append:beaglebone_yocto = " \ + file://emmcsetup.lua \ +" + # images to build before building swupdate image IMAGE_DEPENDS = "core-image-full-cmdline" diff --git a/recipes-extended/images/update-image/rpi/emmcsetup.lua b/recipes-extended/images/update-image/rpi/emmcsetup.lua deleted file mode 100644 index e69de29..0000000 diff --git a/recipes-extended/images/update-image/sama5d27-som1-ek-sd/emmcsetup.lua b/recipes-extended/images/update-image/sama5d27-som1-ek-sd/emmcsetup.lua deleted file mode 100644 index 58a7832..0000000 --- a/recipes-extended/images/update-image/sama5d27-som1-ek-sd/emmcsetup.lua +++ /dev/null @@ -1,12 +0,0 @@ -function preinst() - local out = "Post installed script called" - - return true, out - -end - -function postinst() - local out = "Post installed script called" - - return true, out -end diff --git a/recipes-extended/images/update-image/wandboard/emmcsetup.lua b/recipes-extended/images/update-image/wandboard/emmcsetup.lua deleted file mode 100644 index 58a7832..0000000 --- a/recipes-extended/images/update-image/wandboard/emmcsetup.lua +++ /dev/null @@ -1,12 +0,0 @@ -function preinst() - local out = "Post installed script called" - - return true, out - -end - -function postinst() - local out = "Post installed script called" - - return true, out -end