Firmware
Atlas provides several ready-to-use firmware packages to make it easy to get started with virtual devices.
The package format for MCU firmware is explained in our MCU Firmware Packages article.
The package format for Linux firmware is explained in our Linux Firmware Packages article.
In addition to stock firmware, you can create your own custom firmware packages to run on virtual devices, which you can upload through the web interface or using our REST or Python API.
General Boot Flow
Models in Atlas are generally configured to boot either with Linux firmware or MCU firmware. Linux firmware implies a boot flow that closely resembles the boot flow found on a board starting at the hand off from a second stage boot loader to the Linux kernel. Specifically this means that the board does not start at the reset vector, but at the entry to the Linux kernel. The firmware package uploaded to the board is required to contain a firmware object that is generally an ELF format executable that is loaded into memory. The loader then the PC to the entry point mimicking the behavior of most boot loaders.
The MCU flow implies that the board starts from the reset vector with the option of appearing to start from a debugger. In practice during software development most micro-controller boards are booted from a debugger that dynamically loads the binary into FLASH and/or RAM rather than using an external flash programmer - so the user flow has been optimized for this use-case.
To use this flow, the firmware package uploaded to the board is required to contain a file named "firmware" that will be loaded into the device prior to the simulated MCU power-on-reset (PoR) event. This file is usually an ELF, but may also be a nested zip archive, Motorola SREC, or Intel HEX file format. This binary should be built in such a way to include code for the MCU's Vector Table, as the MCU will read from it during PoR to set its stack pointer (SP) and program counter (PC).
The use-case defined above is intended to mimic the workflow of real hardware with an attached debugger that does the work of provisioning and releasing the target under test. To mimic the boot flow of a board without a simulated debugger we recommend using a flattened image of the boot storage device as the Firmware Object, the storage for boot device can then either be omitted, contain a second identical copy, or contains 0xFF filling all bytes of the storage.
General Firmware Package Structure
All firmware used by Atlas shares a general structure: a firmware object, zero or more storage objects, zero or more platform specific files, and a description file. All of these are packaged together into a zip archive that is uploaded via web interface or REST API.
Firmware Objects
Every firmware package must contain a firmware object, generally named either firmware or kernel. Generally this is either: an ELF format binary, a Linux kernel, or zip containing a load.txt and several binary objects. If the firmware object is an ELF file or Linux kernel it is loaded into memory as if loaded by a boot loader. If the firmware object is a zip file it is assumed to contain an load.txt that contains a lists of file names and memory offsets. Each file is them memcpy'd into RAM at the address specified without any additional processing. An example load.txt:
name:rom-image.wic.nopt load:0x11000000
name:encrypted_blob.bin load:0x31000000
name:encrypted_blob2.bin load:0x31080000
Storage Objects
Many systems include some number of non-volatile storage devices, such as FLASH, eMMC, SD-CARD, or hard drive. The specific names and sizes are documented in the "Details" entry for the device. This will also document which files are required and which optional and what the default values are for optional files.
Platform Specific Files
In most cases where a Linux kernel is used as the firmware a device tree blob, or DTB, is a required platform file. Additionally, a few Linux platforms also require a system.map file. Over time Atlas will be migrating away from the use of the Linux kernel as a loadable module in the direction of a bootloader binary that can be reasonably called firmware.