Skip to content

Commit

Permalink
Move configuration out of nerves_system_br/boards
Browse files Browse the repository at this point in the history
  • Loading branch information
fhunleth committed Jun 27, 2016
1 parent 99367e3 commit 887aea7
Show file tree
Hide file tree
Showing 10 changed files with 1,018 additions and 8 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ Loading the `legoev3_ports` driver automatically disables the port. To leave it

options legoev3_ports disable_in_port=1

See the `rootfs_additions` for updating or overriding this file.

## Supported USB WiFi devices

The base image includes drivers and firmware for Ralink RT53xx
Expand Down Expand Up @@ -100,10 +102,28 @@ If [available in Hex](https://hex.pm/docs/publish), the package can be installed
[applications: [:nerves_system_ev3]]
end

## SDCard vs. internal NAND Flash notes

The EV3 brick has a 16 MB NAND Flash inside it that's connected to SPI bus 0.
It doesn't look like the ev3dev project has included support for it yet except
in their version of u-boot. The means that it can only be programmed using the
Lego supplied tools. The 16 MB NAND Flash also has a couple other issues. First,
it appears to be super slow. This leads to them copying the whole image to
DRAM instead of reading it as needed. It appears that this uses up 10 MB of
DRAM compared to running off the SDCard. This is significant when you consider
that the board only has 64 MB total DRAM. On the other hand, programming the
internal NAND Flash is cool and the direction that we'd prefer to go on
production systems.

Currently, the u-boot in the internal NAND Flash that's supplied by Lego and the
ev3dev project expects the `uImage` in the first VFAT partition. Ideally, it
would extract it out of the rootfs so that we could implement more atomic
firmware updates. To avoid the need to reflash the firmware to use Nerves, I'm
staying with the existing mechanism.

## ev3dev

This port draws subtantially on the [ev3dev](http://www.ev3dev.org/)
This port draws substantially on the [ev3dev](http://www.ev3dev.org/)
project. In general, if there's a way to do something in ev3dev,
it can be made to work in Nerves. Nerves uses the same Linux kernel
from the ev3dev project and enables the same set of custom drivers
Expand Down
203 changes: 203 additions & 0 deletions fwup.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# Firmware configuration file for the Beaglebone Black

# 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 |
# +----------------------------+
# | Boot partition (FAT32) |
# | u-boot.img |
# | uenv.txt |
# | zImage |
# +----------------------------+
# | p1*: Rootfs A (squashfs) |
# +----------------------------+
# | p1*: Rootfs B (squashfs) |
# +----------------------------+
# | p2: Application (FAT32) |
# +----------------------------+
#
# 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_PART_OFFSET, 63)
define(BOOT_PART_COUNT, 16321)

# Let the rootfs have room to grow up to 128 MiB and align
# it to the nearest 1 MB boundary
define(ROOTFS_A_PART_OFFSET, 16384)
define(ROOTFS_A_PART_COUNT, 289044)
define(ROOTFS_B_PART_OFFSET, 305428)
define(ROOTFS_B_PART_COUNT, 289044)

# Application partition
# NOTE: Keep the total amount used under 1.78 GiB so that
# everything fits in the "2 GB" eMMC.
define(APP_PART_OFFSET, 594472)
define(APP_PART_COUNT, 1048576)

# Firmware metadata
meta-product = "Nerves Firmware"
meta-description = ""
meta-version = ${NERVES_SDK_VERSION}
meta-platform = "ev3"
meta-architecture = "arm"
meta-author = "Frank Hunleth"

# 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 uImage {
host-path = "${NERVES_SYSTEM}/images/uImage"
}
file-resource rootfs.img {
host-path = ${ROOTFS}
}

mbr mbr-a {
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 = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = 0xc # FAT32
}
# partition 3 is unused
}

mbr mbr-b {
partition 0 {
block-offset = ${BOOT_PART_OFFSET}
block-count = ${BOOT_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 {
block-offset = ${APP_PART_OFFSET}
block-count = ${APP_PART_COUNT}
type = 0xc # FAT32
}
# partition 3 is unused
}

# This firmware task writes everything to the destination media
task complete {
# Only match if not mounted
require-unmounted-destination = true

# Everything that gets written can be verified on the fly.
# This speeds things up, since we don't care about detecting
# errors before data gets written.
verify-on-the-fly = true

on-init {
mbr_write(mbr-a)

fat_mkfs(${BOOT_PART_OFFSET}, ${BOOT_PART_COUNT})
fat_setlabel(${BOOT_PART_OFFSET}, "BOOT")
}

on-resource uImage { fat_write(${BOOT_PART_OFFSET}, "uImage") }

on-resource rootfs.img {
# write to the first rootfs partition
raw_write(${ROOTFS_A_PART_OFFSET})
}

on-finish {
# Initialize the app partition last so that the boot
# partition can be written in one go.
fat_mkfs(${APP_PART_OFFSET}, ${APP_PART_COUNT})
fat_setlabel(${APP_PART_OFFSET}, "APPDATA")
}
}

task upgrade.a {
# This task upgrades the A partition
require-partition1-offset = ${ROOTFS_B_PART_OFFSET}

# Since the upgrade won't run until it has been finalized, it's ok
# to write data as it is read.
verify-on-the-fly = true

on-init {
# Erase any old saved files from previous upgrades
fat_rm(${BOOT_PART_OFFSET}, "uImage.pre")
}

# Write the new firmware and Linux images, but don't
# commit them. That way if the user aborts midway, we
# still are using the original firmware.
on-resource uImage { fat_write(${BOOT_PART_OFFSET}, "uImage.new") }

on-resource rootfs.img {
# write to the first rootfs partition
raw_write(${ROOTFS_A_PART_OFFSET})
}

on-finish {
# Switch over to boot the new firmware
mbr_write(mbr-a)

fat_mv(${BOOT_PART_OFFSET}, "uImage", "uImage.pre")
fat_mv(${BOOT_PART_OFFSET}, "uImage.new", "uImage")
}

on-error {
# Clean up in case something goes wrong
fat_rm(${BOOT_PART_OFFSET}, "uImage.new")
}
}

task upgrade.b {
# This task upgrades the B partition
require-partition1-offset = ${ROOTFS_A_PART_OFFSET}

# Since the upgrade won't run until it has been finalized, it's ok
# to write data as it is read.
verify-on-the-fly = true

on-init {
fat_rm(${BOOT_PART_OFFSET}, "uImage.pre")
}

on-resource uImage { fat_write(${BOOT_PART_OFFSET}, "uImage.new") }

on-resource rootfs.img {
# write to the first rootfs partition
raw_write(${ROOTFS_B_PART_OFFSET})
}

on-finish {
# Switch over to boot the new firmware
mbr_write(mbr-b)

fat_mv(${BOOT_PART_OFFSET}, "uImage", "uImage.pre")
fat_mv(${BOOT_PART_OFFSET}, "uImage.new", "uImage")
}

on-error {
# Clean up in case something goes wrong
fat_rm(${BOOT_PART_OFFSET}, "uImage.new")
}
}
Loading

0 comments on commit 887aea7

Please sign in to comment.