Current section

Files

Jump to
Raw

fwup.conf

# Firmware configuration file for the Beaglebone Black
#
# 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, "bbb")
define(NERVES_FW_ARCHITECTURE, "arm")
define(NERVES_FW_AUTHOR, "The Nerves Team")
define(NERVES_FW_DEVPATH, "/dev/mmcblk0")
define(NERVES_FW_APPLICATION_PART0_DEVPATH, "/dev/mmcblk0p4") # Linux part number is 1-based
define(NERVES_FW_APPLICATION_PART0_FSTYPE, "ext4")
define(NERVES_FW_APPLICATION_PART0_TARGET, "/root")
# 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 layout:
#
# +----------------------------+
# | MBR |
# +----------------------------+
# | Firmware configuration data|
# | (formatted as uboot env) |
# +----------------------------+
# | p0*: Boot A (FAT32) |
# | u-boot.img |
# | uenv.txt |
# | zImage |
# +----------------------------+
# | p0*: Boot B (FAT32) |
# +----------------------------+
# | p1*: Rootfs A (squashfs) |
# +----------------------------+
# | p1*: Rootfs B (squashfs) |
# +----------------------------+
# | p2: Unused |
# +----------------------------+
# | p3: Application (ext4) |
# +----------------------------+
#
# The p0/p1 partition points to whichever of configurations A or B that is
# active.
#
# The U-Boot environment is written directly to the SDCard/eMMC. It is not
# in any partition
define(UBOOT_ENV_OFFSET, 2048)
define(UBOOT_ENV_COUNT, 16) # 8 KB
#
# The p1 partition points to whichever of Rootfs A or B that
# is active.
# The boot partition contains MLO, u-boot.img, zImage, and has
# room for a debug uEnv.txt if desired
define(BOOT_A_PART_OFFSET, 4096)
define(BOOT_A_PART_COUNT, 28672)
define-eval(BOOT_B_PART_OFFSET, "${BOOT_A_PART_OFFSET} + ${BOOT_A_PART_COUNT}")
define(BOOT_B_PART_COUNT, ${BOOT_A_PART_COUNT})
# Let the rootfs have room to grow up to 140 MiB and align it to the nearest 1
# MB boundary
define(ROOTFS_A_PART_OFFSET, 63488)
define(ROOTFS_A_PART_COUNT, 286720)
define-eval(ROOTFS_B_PART_OFFSET, "${ROOTFS_A_PART_OFFSET} + ${ROOTFS_A_PART_COUNT}")
define(ROOTFS_B_PART_COUNT, ${ROOTFS_A_PART_COUNT})
# Application partition. This partition can occupy all of the remaining space.
# Size it to fit the destination.
define-eval(APP_PART_OFFSET, "${ROOTFS_B_PART_OFFSET} + ${ROOTFS_B_PART_COUNT}")
define(APP_PART_COUNT, 1048576)
# 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}
# 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 MLO {
host-path = "${NERVES_SYSTEM}/images/MLO"
}
file-resource u-boot.img {
host-path = "${NERVES_SYSTEM}/images/u-boot.img"
}
file-resource boot.scr {
host-path = "${NERVES_SYSTEM}/images/boot.scr"
}
file-resource zImage {
host-path = "${NERVES_SYSTEM}/images/zImage"
}
file-resource am335x-boneblack.dtb {
host-path = "${NERVES_SYSTEM}/images/am335x-boneblack.dtb"
}
file-resource am335x-bonegreen.dtb {
host-path = "${NERVES_SYSTEM}/images/am335x-bonegreen.dtb"
}
file-resource am335x-bonegreen-wireless.dtb {
host-path = "${NERVES_SYSTEM}/images/am335x-bonegreen-wireless.dtb"
}
file-resource rootfs.img {
host-path = ${ROOTFS}
# Error out if the rootfs size exceeds the partition size
assert-size-lte = ${ROOTFS_A_PART_COUNT}
}
mbr mbr-a {
partition 0 {
block-offset = ${BOOT_A_PART_OFFSET}
block-count = ${BOOT_A_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 is unused
partition 3 {
block-offset = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = 0x83 # Linux
}
}
mbr mbr-b {
partition 0 {
block-offset = ${BOOT_B_PART_OFFSET}
block-count = ${BOOT_B_PART_COUNT}
type = 0xc # FAT32
boot = true
}
partition 1 {
block-offset = ${ROOTFS_B_PART_OFFSET}
block-count = ${ROOTFS_B_PART_COUNT}
type = 0x83 # Linux
}
# partition 2 is unused
partition 3 {
block-offset = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = 0x83 # Linux
}
}
# 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 at the factory to initialize a board!
task complete {
# Only match if not mounted
require-unmounted-destination = true
on-init {
mbr_write(mbr-a)
uboot_clearenv(uboot-env)
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})
fat_mkfs(${BOOT_A_PART_OFFSET}, ${BOOT_A_PART_COUNT})
fat_setlabel(${BOOT_A_PART_OFFSET}, "BOOT-A")
}
on-resource MLO { fat_write(${BOOT_A_PART_OFFSET}, "MLO") }
on-resource u-boot.img { fat_write(${BOOT_A_PART_OFFSET}, "u-boot.img") }
on-resource boot.scr { fat_write(${BOOT_A_PART_OFFSET}, "boot.scr") }
on-resource zImage { fat_write(${BOOT_A_PART_OFFSET}, "zImage") }
on-resource am335x-boneblack.dtb { fat_write(${BOOT_A_PART_OFFSET}, "am335x-boneblack.dtb") }
on-resource am335x-bonegreen.dtb { fat_write(${BOOT_A_PART_OFFSET}, "am335x-bonegreen.dtb") }
on-resource am335x-bonegreen-wireless.dtb { fat_write(${BOOT_A_PART_OFFSET}, "am335x-bonegreen-wireless.dtb") }
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(${BOOT_B_PART_OFFSET}, 256, 0xff)
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. If this isn't done and an old SDCard is reused, the
# application data could be in a weird state.
raw_memset(${APP_PART_OFFSET}, 256, 0xff)
}
}
task upgrade.a {
# This task upgrades the A partition
require-partition-offset(1, ${ROOTFS_B_PART_OFFSET})
on-init {
info("Upgrading the A partition")
# Clear some firmware information just in case this update gets
# interrupted midway.
uboot_unsetenv(uboot-env, "a.nerves_fw_version")
# Reset the previous contents of the A boot partition
fat_mkfs(${BOOT_A_PART_OFFSET}, ${BOOT_A_PART_COUNT})
fat_setlabel(${BOOT_A_PART_OFFSET}, "BOOT-A")
}
# Write the new boot partition files and rootfs. The MBR still points
# to the B partition, so an error or power failure during this part
# won't hurt anything.
on-resource MLO { fat_write(${BOOT_A_PART_OFFSET}, "MLO") }
on-resource u-boot.img { fat_write(${BOOT_A_PART_OFFSET}, "u-boot.img") }
on-resource boot.scr { fat_write(${BOOT_A_PART_OFFSET}, "boot.scr") }
on-resource zImage { fat_write(${BOOT_A_PART_OFFSET}, "zImage") }
on-resource am335x-boneblack.dtb { fat_write(${BOOT_A_PART_OFFSET}, "am335x-boneblack.dtb") }
on-resource am335x-bonegreen.dtb { fat_write(${BOOT_A_PART_OFFSET}, "am335x-bonegreen.dtb") }
on-resource am335x-bonegreen-wireless.dtb { fat_write(${BOOT_A_PART_OFFSET}, "am335x-bonegreen-wireless.dtb") }
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})
# Switch over to boot the new firmware
uboot_setenv(uboot-env, "nerves_fw_active", "a")
mbr_write(mbr-a)
}
on-error {
}
}
task upgrade.b {
# This task upgrades the B partition
require-partition-offset(1, ${ROOTFS_A_PART_OFFSET})
on-init {
info("Upgrading the B partition")
# Clear some firmware information just in case this update gets
# interrupted midway.
uboot_unsetenv(uboot-env, "b.nerves_fw_version")
# Reset the previous contents of the B boot partition
fat_mkfs(${BOOT_B_PART_OFFSET}, ${BOOT_B_PART_COUNT})
fat_setlabel(${BOOT_B_PART_OFFSET}, "BOOT-B")
}
# Write the new boot partition files and rootfs. The MBR still points
# to the A partition, so an error or power failure during this part
# won't hurt anything.
on-resource MLO { fat_write(${BOOT_B_PART_OFFSET}, "MLO") }
on-resource u-boot.img { fat_write(${BOOT_B_PART_OFFSET}, "u-boot.img") }
on-resource boot.scr { fat_write(${BOOT_B_PART_OFFSET}, "boot.scr") }
on-resource zImage { fat_write(${BOOT_B_PART_OFFSET}, "zImage") }
on-resource am335x-boneblack.dtb { fat_write(${BOOT_B_PART_OFFSET}, "am335x-boneblack.dtb") }
on-resource am335x-bonegreen.dtb { fat_write(${BOOT_B_PART_OFFSET}, "am335x-bonegreen.dtb") }
on-resource am335x-bonegreen-wireless.dtb { fat_write(${BOOT_B_PART_OFFSET}, "am335x-bonegreen-wireless.dtb") }
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})
# Switch over to boot the new firmware
uboot_setenv(uboot-env, "nerves_fw_active", "b")
mbr_write(mbr-b)
}
on-error {
}
}
task upgrade.unexpected {
on-init {
error("Please check the media being upgraded. It doesn't look like either the A or B partitions are active.")
}
}