Current section
Files
Jump to
Current section
Files
nerves_system_onlogic_cl210
fwup.conf
fwup.conf
# Firmware configuration file for onlogic_cl210
require-fwup-version="1.4.0" # For the GPT support
#
# Firmware metadata
#
# All of these can be overriden using environment variables of the same name.
#
# Run 'fwup -m' to query values in a .fw file.
# Use 'fw_printenv' to query values on the target.
#
# These are used by Nerves libraries to introspect.
define(NERVES_FW_PRODUCT, "Nerves Firmware")
define(NERVES_FW_DESCRIPTION, "")
define(NERVES_FW_VERSION, "${NERVES_SDK_VERSION}")
define(NERVES_FW_PLATFORM, "onlogic_cl210")
define(NERVES_FW_ARCHITECTURE, "x86_64")
define(NERVES_FW_AUTHOR, "Very")
# /dev/rootdisk* paths are provided by erlinit to refer to the disk and partitions
# on whatever drive provides the rootfs.
define(NERVES_FW_DEVPATH, "/dev/rootdisk0")
define(NERVES_FW_APPLICATION_PART0_DEVPATH, "/dev/rootdisk0p4") # Linux part number is 1-based
define(NERVES_FW_APPLICATION_PART0_FSTYPE, "f2fs")
define(NERVES_FW_APPLICATION_PART0_TARGET, "/root")
define(NERVES_PROVISIONING, "${NERVES_SYSTEM}/images/fwup_include/provisioning.conf")
# Default paths if not specified via the commandline
define(ROOTFS, "${NERVES_SYSTEM}/images/rootfs.squashfs")
# This configuration file will create an image that has the following
# partitions:
#
# +-------------------------------+
# | GPT |
# +-------------------------------+
# | Firmware configuration data |
# | (formatted as uboot env) |
# +-------------------------------+
# | p0*: Kernel/EFI A (Readonly FAT32) |
# | /EFI/NERVES/bzImage.efi |
# | /EFI/NERVES/nerves_initramfs |
# +-------------------------------+
# | p0*: Kernel/EFI B (Readonly FAT32) |
# +-------------------------------+
# | p1*: Rootfs A (squashfs) |
# +-------------------------------+
# | p1*: Rootfs B (squashfs) |
# +-------------------------------+
# | p3: Application (f2fs) |
# +-------------------------------+
define(EFI_TYPE, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b")
define(LINUX_ROOT_X86_64_TYPE, "4f68bce3-e8cd-4db1-96e7-fbcaf984b709")
define(LINUX_FILESYSTEM_DATA_TYPE, "0fc63daf-8483-4772-8e79-3d69d8477de4")
define(NERVES_SYSTEM_DISK_UUID, "c8decfc3-2f19-4b05-85fc-d86d61e0d48c")
define(NERVES_SYSTEM_EFI_PART_UUID, "b8f50e97-5fe1-4e21-9b59-9bc6cdf86008")
define(NERVES_SYSTEM_ROOTFS_PART_UUID, "2f53b205-337c-4129-8826-2b2368598d6a")
define(NERVES_SYSTEM_APP_PART_UUID, "1b238cbb-7974-4e14-b34e-b9766fb10f8b")
define(UBOOT_ENV_OFFSET, 2048)
define(UBOOT_ENV_COUNT, 256) # 128 KB
# The EFI partition contains the bootloader configuration
# 16 MB should be plenty for now.
define(EFI_A_PART_OFFSET, 4096)
define(EFI_A_PART_COUNT, 32768)
define-eval(EFI_B_PART_OFFSET, "${EFI_A_PART_OFFSET} + ${EFI_A_PART_COUNT}")
define(EFI_B_PART_COUNT, ${EFI_A_PART_COUNT})
# Let the rootfs have room to grow up to 512 MiB
define-eval(ROOTFS_A_PART_OFFSET, "${EFI_B_PART_OFFSET} + ${EFI_B_PART_COUNT}")
define(ROOTFS_A_PART_COUNT, 1048576)
define-eval(ROOTFS_B_PART_OFFSET, "${ROOTFS_A_PART_OFFSET} + ${ROOTFS_A_PART_COUNT}")
define(ROOTFS_B_PART_COUNT, ${ROOTFS_A_PART_COUNT})
# Application data partition (4 GiB). This can be enlarged
# to fill the entire volume.
define-eval(APP_PART_OFFSET, "${ROOTFS_B_PART_OFFSET} + ${ROOTFS_B_PART_COUNT}")
define(APP_PART_COUNT, 8388608)
# Firmware archive metadata
meta-product = ${NERVES_FW_PRODUCT}
meta-description = ${NERVES_FW_DESCRIPTION}
meta-version = ${NERVES_FW_VERSION}
meta-platform = ${NERVES_FW_PLATFORM}
meta-architecture = ${NERVES_FW_ARCHITECTURE}
meta-author = ${NERVES_FW_AUTHOR}
meta-vcs-identifier = ${NERVES_FW_VCS_IDENTIFIER}
meta-misc = ${NERVES_FW_MISC}
# File resources are listed in the order that they are included in the .fw file
# This is important, since this is the order that they're written on a firmware
# update due to the event driven nature of the update system.
file-resource readme {
contents = "
In order to use this image, you'll need to run efibootmgr:
efibootmgr -c -b 0001 -d /dev/mmcblk0 -L Nerves -l /EFI/NERVES/bzImage.efi -u 'initrd=\\EFI\\NERVES\\nerves_initramfs'
This has to be done by booting off another Linux image. Ideally the eMMC loader
runs this line after loading the eMMC with the initial image.
Another option if you can enable an EFI Shell (via BIOS or by including EDK2's
shell is that start Linux up by creating a startup.nsh file with the contents:
bzImage.efi initrd=\\EFI\\NERVES\\nerves_initramfs
If you need to pass more parameters to Linux, you'll need to run efibootmgr
again. Another option is to hardcode the parameters in Linux. That is easier,
IMHO.
"
}
file-resource bzImage {
host-path = "${NERVES_SYSTEM}/images/bzImage"
}
file-resource nerves_initramfs {
host-path = "${NERVES_SYSTEM}/images/nerves_initramfs_x86_64.xz;${NERVES_SYSTEM}/images/nerves_initramfs.conf.cpio;${NERVES_SYSTEM}/images/revert.fw.cpio"
}
file-resource rootfs.img {
host-path = ${ROOTFS}
# Error out if the rootfs size exceeds the partition size
assert-size-lte = ${ROOTFS_A_PART_COUNT}
}
gpt gpt-a {
guid = ${NERVES_SYSTEM_DISK_UUID}
partition 0 {
block-offset = ${EFI_A_PART_OFFSET}
block-count = ${EFI_A_PART_COUNT}
type = ${EFI_TYPE}
guid = ${NERVES_SYSTEM_EFI_PART_UUID}
name = "EFI Partition"
}
partition 1 {
block-offset = ${ROOTFS_A_PART_OFFSET}
block-count = ${ROOTFS_A_PART_COUNT}
type = ${LINUX_ROOT_X86_64_TYPE}
guid = ${NERVES_SYSTEM_ROOTFS_PART_UUID}
name = "RootFS A Partition"
}
partition 3 {
block-offset = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = ${LINUX_FILESYSTEM_DATA_TYPE}
guid = ${NERVES_SYSTEM_APP_PART_UUID}
name = "Application Data Partition"
expand = true
}
}
gpt gpt-b {
guid = ${NERVES_SYSTEM_DISK_UUID}
partition 0 {
block-offset = ${EFI_B_PART_OFFSET}
block-count = ${EFI_B_PART_COUNT}
type = ${EFI_TYPE}
guid = ${NERVES_SYSTEM_EFI_PART_UUID}
name = "EFI Partition"
}
partition 1 {
block-offset = ${ROOTFS_B_PART_OFFSET}
block-count = ${ROOTFS_B_PART_COUNT}
type = ${LINUX_ROOT_X86_64_TYPE}
guid = ${NERVES_SYSTEM_ROOTFS_PART_UUID}
name = "RootFS B Partition"
}
partition 3 {
block-offset = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = ${LINUX_FILESYSTEM_DATA_TYPE}
guid = ${NERVES_SYSTEM_APP_PART_UUID}
name = "Application Data Partition"
expand = true
}
}
# Location where installed firmware information is stored.
# While this is called "u-boot", u-boot isn't involved in this
# setup. It just provides a convenient key/value store format.
uboot-environment uboot-env {
block-offset = ${UBOOT_ENV_OFFSET}
block-count = ${UBOOT_ENV_COUNT}
}
# This firmware task writes everything to the destination media.
# This should only be run for the first installation.
task complete {
# Only match if not mounted
require-unmounted-destination = true
on-init {
gpt_write(gpt-a)
uboot_clearenv(uboot-env)
include("${NERVES_PROVISIONING}")
uboot_setenv(uboot-env, "nerves_fw_active", "a")
uboot_setenv(uboot-env, "nerves_fw_autovalidate", "0")
uboot_setenv(uboot-env, "nerves_fw_validated", "1")
uboot_setenv(uboot-env, "nerves_fw_booted", "0")
uboot_setenv(uboot-env, "nerves_fw_devpath", ${NERVES_FW_DEVPATH})
uboot_setenv(uboot-env, "a.nerves_fw_application_part0_devpath", ${NERVES_FW_APPLICATION_PART0_DEVPATH})
uboot_setenv(uboot-env, "a.nerves_fw_application_part0_fstype", ${NERVES_FW_APPLICATION_PART0_FSTYPE})
uboot_setenv(uboot-env, "a.nerves_fw_application_part0_target", ${NERVES_FW_APPLICATION_PART0_TARGET})
uboot_setenv(uboot-env, "a.nerves_fw_product", ${NERVES_FW_PRODUCT})
uboot_setenv(uboot-env, "a.nerves_fw_description", ${NERVES_FW_DESCRIPTION})
uboot_setenv(uboot-env, "a.nerves_fw_version", ${NERVES_FW_VERSION})
uboot_setenv(uboot-env, "a.nerves_fw_platform", ${NERVES_FW_PLATFORM})
uboot_setenv(uboot-env, "a.nerves_fw_architecture", ${NERVES_FW_ARCHITECTURE})
uboot_setenv(uboot-env, "a.nerves_fw_author", ${NERVES_FW_AUTHOR})
uboot_setenv(uboot-env, "a.nerves_fw_vcs_identifier", ${NERVES_FW_VCS_IDENTIFIER})
uboot_setenv(uboot-env, "a.nerves_fw_misc", ${NERVES_FW_MISC})
uboot_setenv(uboot-env, "a.nerves_fw_uuid", "\${FWUP_META_UUID}")
fat_mkfs(${EFI_A_PART_OFFSET}, ${EFI_A_PART_COUNT})
fat_mkdir(${EFI_A_PART_OFFSET}, "/EFI")
fat_mkdir(${EFI_A_PART_OFFSET}, "/EFI/NERVES")
}
on-resource readme { fat_write(${EFI_A_PART_OFFSET}, "/README.TXT") }
on-resource bzImage { fat_write(${EFI_A_PART_OFFSET}, "/EFI/NERVES/bzImage.efi") }
on-resource nerves_initramfs { fat_write(${EFI_A_PART_OFFSET}, "/EFI/NERVES/nerves_initramfs") }
on-resource rootfs.img { raw_write(${ROOTFS_A_PART_OFFSET}) }
on-finish {
# Clear out any old data in the B partition that might be mistaken for
# a file system. This is mostly to avoid confusion in humans when
# reprogramming SDCards with unknown contents.
raw_memset(${ROOTFS_B_PART_OFFSET}, 256, 0xff)
# Invalidate the application data partition so that it is guaranteed to
# trigger the corrupt filesystem detection code on first boot and get
# formatted.
raw_memset(${APP_PART_OFFSET}, 256, 0xff)
}
}
task upgrade.a {
# This task upgrades the A partition, so make sure we're running
# on B.
require-uboot-variable(uboot-env, "nerves_fw_active", "b")
# Require that the running version of firmware has been validated.
# If it has not, then failing back is not guaranteed to work.
require-uboot-variable(uboot-env, "nerves_fw_validated", "1")
# Verify the expected platform/architecture
require-uboot-variable(uboot-env, "b.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
require-uboot-variable(uboot-env, "b.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
on-init {
info("Upgrading partition A")
# Clear some firmware information just in case this update gets
# interrupted midway. If this partition was bootable, it's not going to
# be soon.
uboot_unsetenv(uboot-env, "a.nerves_fw_version")
uboot_unsetenv(uboot-env, "a.nerves_fw_platform")
uboot_unsetenv(uboot-env, "a.nerves_fw_architecture")
uboot_unsetenv(uboot-env, "a.nerves_fw_uuid")
# Indicate that the entire partition can be cleared
trim(${EFI_A_PART_OFFSET}, ${EFI_A_PART_COUNT})
trim(${ROOTFS_A_PART_OFFSET}, ${ROOTFS_A_PART_COUNT})
# Reset the previous contents of the A boot partition
fat_mkfs(${EFI_A_PART_OFFSET}, ${EFI_A_PART_COUNT})
fat_mkdir(${EFI_A_PART_OFFSET}, "/EFI")
fat_mkdir(${EFI_A_PART_OFFSET}, "/EFI/NERVES")
}
on-resource bzImage { fat_write(${EFI_A_PART_OFFSET}, "/EFI/NERVES/bzImage.efi") }
on-resource nerves_initramfs { fat_write(${EFI_A_PART_OFFSET}, "/EFI/NERVES/nerves_initramfs") }
on-resource rootfs.img { raw_write(${ROOTFS_A_PART_OFFSET}) }
on-finish {
# Update firmware metadata
uboot_setenv(uboot-env, "a.nerves_fw_application_part0_devpath", ${NERVES_FW_APPLICATION_PART0_DEVPATH})
uboot_setenv(uboot-env, "a.nerves_fw_application_part0_fstype", ${NERVES_FW_APPLICATION_PART0_FSTYPE})
uboot_setenv(uboot-env, "a.nerves_fw_application_part0_target", ${NERVES_FW_APPLICATION_PART0_TARGET})
uboot_setenv(uboot-env, "a.nerves_fw_product", ${NERVES_FW_PRODUCT})
uboot_setenv(uboot-env, "a.nerves_fw_description", ${NERVES_FW_DESCRIPTION})
uboot_setenv(uboot-env, "a.nerves_fw_version", ${NERVES_FW_VERSION})
uboot_setenv(uboot-env, "a.nerves_fw_platform", ${NERVES_FW_PLATFORM})
uboot_setenv(uboot-env, "a.nerves_fw_architecture", ${NERVES_FW_ARCHITECTURE})
uboot_setenv(uboot-env, "a.nerves_fw_author", ${NERVES_FW_AUTHOR})
uboot_setenv(uboot-env, "a.nerves_fw_vcs_identifier", ${NERVES_FW_VCS_IDENTIFIER})
uboot_setenv(uboot-env, "a.nerves_fw_misc", ${NERVES_FW_MISC})
uboot_setenv(uboot-env, "a.nerves_fw_uuid", "\${FWUP_META_UUID}")
# Reset the validation status and boot to A
# next time.
uboot_setenv(uboot-env, "nerves_fw_active", "a")
uboot_setenv(uboot-env, "nerves_fw_validated", "0")
uboot_setenv(uboot-env, "nerves_fw_booted", "0")
gpt_write(gpt-a)
}
}
task upgrade.b {
# This task upgrades the B partition, so make sure we're running
# on A.
require-uboot-variable(uboot-env, "nerves_fw_active", "a")
# Require that the running version of firmware has been validated.
# If it has not, then failing back is not guaranteed to work.
require-uboot-variable(uboot-env, "nerves_fw_validated", "1")
# Verify the expected platform/architecture
require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
on-init {
info("Upgrading partition B")
# Clear some firmware information just in case this update gets
# interrupted midway.
uboot_unsetenv(uboot-env, "b.nerves_fw_version")
uboot_unsetenv(uboot-env, "b.nerves_fw_platform")
uboot_unsetenv(uboot-env, "b.nerves_fw_architecture")
uboot_unsetenv(uboot-env, "b.nerves_fw_uuid")
trim(${EFI_B_PART_OFFSET}, ${EFI_B_PART_COUNT})
trim(${ROOTFS_B_PART_OFFSET}, ${ROOTFS_B_PART_COUNT})
fat_mkfs(${EFI_B_PART_OFFSET}, ${EFI_B_PART_COUNT})
fat_mkdir(${EFI_B_PART_OFFSET}, "/EFI")
fat_mkdir(${EFI_B_PART_OFFSET}, "/EFI/NERVES")
}
on-resource bzImage { fat_write(${EFI_B_PART_OFFSET}, "/EFI/NERVES/bzImage.efi") }
on-resource nerves_initramfs { fat_write(${EFI_B_PART_OFFSET}, "/EFI/NERVES/nerves_initramfs") }
on-resource rootfs.img { raw_write(${ROOTFS_B_PART_OFFSET}) }
on-finish {
# Update firmware metadata
uboot_setenv(uboot-env, "b.nerves_fw_application_part0_devpath", ${NERVES_FW_APPLICATION_PART0_DEVPATH})
uboot_setenv(uboot-env, "b.nerves_fw_application_part0_fstype", ${NERVES_FW_APPLICATION_PART0_FSTYPE})
uboot_setenv(uboot-env, "b.nerves_fw_application_part0_target", ${NERVES_FW_APPLICATION_PART0_TARGET})
uboot_setenv(uboot-env, "b.nerves_fw_product", ${NERVES_FW_PRODUCT})
uboot_setenv(uboot-env, "b.nerves_fw_description", ${NERVES_FW_DESCRIPTION})
uboot_setenv(uboot-env, "b.nerves_fw_version", ${NERVES_FW_VERSION})
uboot_setenv(uboot-env, "b.nerves_fw_platform", ${NERVES_FW_PLATFORM})
uboot_setenv(uboot-env, "b.nerves_fw_architecture", ${NERVES_FW_ARCHITECTURE})
uboot_setenv(uboot-env, "b.nerves_fw_author", ${NERVES_FW_AUTHOR})
uboot_setenv(uboot-env, "b.nerves_fw_vcs_identifier", ${NERVES_FW_VCS_IDENTIFIER})
uboot_setenv(uboot-env, "b.nerves_fw_misc", ${NERVES_FW_MISC})
uboot_setenv(uboot-env, "b.nerves_fw_uuid", "\${FWUP_META_UUID}")
# Reset the validation status and boot to B next time.
uboot_setenv(uboot-env, "nerves_fw_active", "b")
uboot_setenv(uboot-env, "nerves_fw_validated", "0")
uboot_setenv(uboot-env, "nerves_fw_booted", "0")
gpt_write(gpt-b)
}
}
task upgrade.unvalidated {
require-uboot-variable(uboot-env, "nerves_fw_validated", "0")
on-init {
error("Please validate the running firmware before upgrading it again.")
}
}
task upgrade.wrong {
require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
on-init {
error("Please check the media being upgraded. It doesn't look like either the A or B partitions are active.")
}
}
task upgrade.wrongplatform {
on-init {
error("Expecting platform=${NERVES_FW_PLATFORM} and architecture=${NERVES_FW_ARCHITECTURE}")
}
}