Packages
nerves_system_vultr
0.21.0
0.31.0
0.30.5
0.30.4
0.30.3
0.30.2
0.30.1
0.30.0
0.29.0
0.28.3
0.28.2
0.28.1
0.28.0
0.27.1
0.27.0
0.26.1
0.26.0
0.25.1
0.25.0
0.24.1
0.24.0
0.23.0
0.22.1
0.22.0
0.21.1
0.21.0
0.20.2
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
retired
0.16.0
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.0
0.2.1
0.2.0
Nerves System - Vultr
Current section
Files
Jump to
Current section
Files
nerves_system_vultr
fwup.conf
fwup.conf
# Firmware configuration file for a Vultr Server Image
require-fwup-version="0.15.0" # For the trim() call
#
# 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 Vultr Image")
define(NERVES_FW_DESCRIPTION, "")
define(NERVES_FW_VERSION, "${NERVES_SDK_VERSION}")
define(NERVES_FW_PLATFORM, "vultr")
define(NERVES_FW_ARCHITECTURE, "x86_64")
define(NERVES_FW_AUTHOR, "The Nerves Team")
define(NERVES_FW_DEVPATH, "/dev/vda")
define(NERVES_FW_APPLICATION_PART0_DEVPATH, "/dev/vda4") # Linux part number is 1-based
define(NERVES_FW_APPLICATION_PART0_FSTYPE, "ext4")
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:
#
# +----------------------------+
# | MBR w/ Grub boot code |
# +----------------------------+
# | grub.img (<256K) |
# +----------------------------+
# | Firmware configuration data|
# | (formatted as uboot env) |
# +----------------------------+
# | Boot partition (FAT32) |
# | /boot/grub/grub.cfg |
# | /boot/grub/grubenv |
# +----------------------------+
# | p2: Rootfs A (squashfs) |
# +----------------------------+
# | p3: Rootfs B (squashfs) |
# +----------------------------+
# | p4: Application (ext4) |
# +----------------------------+
define(UBOOT_ENV_OFFSET, 2048)
define(UBOOT_ENV_COUNT, 16) # 8 KB
# The boot partition contains the bootloader configuration
# 16 MB should be plenty for now.
define(BOOT_PART_OFFSET, 4096)
define(BOOT_PART_COUNT, 31232)
# Let the rootfs have room to grow up to 256 MiB
define-eval(ROOTFS_A_PART_OFFSET, "${BOOT_PART_OFFSET} + ${BOOT_PART_COUNT}")
define(ROOTFS_A_PART_COUNT, 524288)
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 (10 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, 20971520)
# 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.img {
host-path = "${NERVES_SYSTEM}/images/grub.img"
}
file-resource grub.cfg {
host-path = "${NERVES_SYSTEM}/images/grub.cfg"
}
# 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"
}
mbr mbr {
bootstrap-code-host-path = "${NERVES_SYSTEM}/images/boot.img"
partition 0 {
block-offset = ${BOOT_PART_OFFSET}
block-count = ${BOOT_PART_COUNT}
type = 0xc # FAT32
boot = true
}
partition 1 {
block-offset = ${ROOTFS_A_PART_OFFSET}
block-count = ${ROOTFS_A_PART_COUNT}
type = 0x83 # Linux
}
partition 2 {
block-offset = ${ROOTFS_B_PART_OFFSET}
block-count = ${ROOTFS_B_PART_COUNT}
type = 0x83 # Linux
}
partition 3 {
block-offset = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = 0x83 # Linux
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 {
mbr_write(mbr)
fat_mkfs(${BOOT_PART_OFFSET}, ${BOOT_PART_COUNT})
fat_mkdir(${BOOT_PART_OFFSET}, "/boot")
fat_mkdir(${BOOT_PART_OFFSET}, "/boot/grub")
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.img { raw_write(1) }
on-resource grub.cfg { fat_write(${BOOT_PART_OFFSET}, "/boot/grub/grub.cfg") }
on-resource grubenv_a_valid { fat_write(${BOOT_PART_OFFSET}, "/boot/grub/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-path-on-device("/", "/dev/vda3")
# 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(${BOOT_PART_OFFSET}, "/boot/grub/grubenv")
}
on-finish {
}
}
task upgrade.b {
# This task upgrades the B partition, so make sure we're running
# on A.
require-path-on-device("/", "/dev/vda2")
# 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(${BOOT_PART_OFFSET}, "/boot/grub/grubenv")
}
on-finish {
}
}
task upgrade.unexpected {
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}")
}
}
task provision {
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 {
include("${NERVES_PROVISIONING}")
}
}
task provision.wrongplatform {
on-init {
error("Expecting platform=${NERVES_FW_PLATFORM} and architecture=${NERVES_FW_ARCHITECTURE}")
}
}