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, "The Nerves Team")
# /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 an MBR and the
# following 3 partitions:
#
# +----------------------------+
# | GPT |
# +----------------------------+
# | Firmware configuration data|
# | (formatted as uboot env) |
# +----------------------------+
# | EFI partition (FAT32) |
# | /EFI/BOOT/grub.cfg |
# | /EFI/BOOT/grubenv |
# +----------------------------+
# | p2: Rootfs A (squashfs) |
# +----------------------------+
# | p3: Rootfs B (squashfs) |
# +----------------------------+
# | p4: 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(DISK_UUID, "b443fbeb-2c93-481b-88b3-0ecb0aeba911")
define(EFI_PART_UUID, "5278721d-0089-4768-85df-b8f1b97e6684")
define(ROOTFS_A_PART_UUID, "fcc205c8-2f1c-4dcd-bef4-7b209aa15cca")
define(ROOTFS_B_PART_UUID, "0b8fb121-3cde-4f44-b323-03a5c0607f99")
define(APP_PART_UUID, "0FC63DAF-8483-4772-8E79-3D69D8477DE4")
define(UBOOT_ENV_OFFSET, 2048)
define(UBOOT_ENV_COUNT, 16) # 8 KB
# The EFI partition contains the bootloader configuration
# 16 MB should be plenty for now.
define(EFI_PART_OFFSET, 4096)
define(EFI_PART_COUNT, 31232)
# Let the rootfs have room to grow up to 512 MiB
define-eval(ROOTFS_A_PART_OFFSET, "${EFI_PART_OFFSET} + ${EFI_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 grub.cfg {
host-path = "${NERVES_SYSTEM}/images/efi-part/EFI/BOOT/grub.cfg"
}
file-resource bootx64.efi {
host-path = "${NERVES_SYSTEM}/images/efi-part/EFI/BOOT/bootx64.efi"
}
file-resource startup.nsh {
host-path = "${NERVES_SYSTEM}/images/efi-part/startup.nsh"
}
# Order the rootfs image before the grub environment resources
# so that the grub environment blobs get written last. This
# is in case the user aborts the programming midway.
file-resource rootfs.img {
host-path = ${ROOTFS}
# Error out if the rootfs size exceeds the partition size
assert-size-lte = ${ROOTFS_A_PART_COUNT}
}
file-resource grubenv_a_valid {
host-path = "${NERVES_SYSTEM}/images/grubenv_a_valid"
}
file-resource grubenv_a {
host-path = "${NERVES_SYSTEM}/images/grubenv_a"
}
file-resource grubenv_b {
host-path = "${NERVES_SYSTEM}/images/grubenv_b"
}
gpt gpt {
guid = ${DISK_UUID}
partition 0 {
block-offset = ${EFI_PART_OFFSET}
block-count = ${EFI_PART_COUNT}
type = ${EFI_TYPE}
guid = ${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 = ${ROOTFS_A_PART_UUID}
name = "RootFS A Partition"
}
partition 2 {
block-offset = ${ROOTFS_B_PART_OFFSET}
block-count = ${ROOTFS_B_PART_COUNT}
type = ${LINUX_ROOT_X86_64_TYPE}
guid = ${ROOTFS_B_PART_UUID}
name = "RootFS B Partition"
}
partition 3 {
block-offset = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = ${LINUX_FILESYSTEM_DATA_TYPE}
guid = ${APP_PART_UUID}
name = "Application Data Partition"
}
}
# 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)
fat_mkfs(${EFI_PART_OFFSET}, ${EFI_PART_COUNT})
fat_mkdir(${EFI_PART_OFFSET}, "/EFI")
fat_mkdir(${EFI_PART_OFFSET}, "/EFI/BOOT")
uboot_clearenv(uboot-env)
include("${NERVES_PROVISIONING}")
uboot_setenv(uboot-env, "nerves_fw_active", "a")
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}")
}
on-resource grub.cfg { fat_write(${EFI_PART_OFFSET}, "/EFI/BOOT/grub.cfg") }
on-resource bootx64.efi { fat_write(${EFI_PART_OFFSET}, "/EFI/BOOT/bootx64.efi") }
on-resource startup.nsh { fat_write(${EFI_PART_OFFSET}, "/startup.nsh") }
on-resource grubenv_a_valid { fat_write(${EFI_PART_OFFSET}, "/EFI/BOOT/grubenv") }
on-resource rootfs.img {
# write to the first rootfs partition
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")
# 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(${ROOTFS_A_PART_OFFSET}, ${ROOTFS_A_PART_COUNT})
}
on-resource rootfs.img {
raw_write(${ROOTFS_A_PART_OFFSET})
}
# Key step to switching over the A partition
on-resource grubenv_a {
# 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}")
# Switch over to boot the new firmware
uboot_setenv(uboot-env, "nerves_fw_active", "a")
fat_write(${EFI_PART_OFFSET}, "/EFI/BOOT/grubenv")
}
on-finish {
}
}
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")
# 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(${ROOTFS_B_PART_OFFSET}, ${ROOTFS_B_PART_COUNT})
}
on-resource rootfs.img {
raw_write(${ROOTFS_B_PART_OFFSET})
}
# Key step to switching over the B partition
on-resource grubenv_b {
# 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}")
# Switch over to boot the new firmware
uboot_setenv(uboot-env, "nerves_fw_active", "b")
fat_write(${EFI_PART_OFFSET}, "/EFI/BOOT/grubenv")
}
on-finish {
}
}
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}")
}
}