tree: 180be0e306569a5383b55275f0a2492fe1c42a9d [path history] [tgz]
  1. build.go
  2. decode.go
  3. emit.go
  4. misc.go
  5. part.go
  6. paths.go
  7. README.md
newt/mfg/README.md

mfg

Definitions:

TermLong NameMeaning
FlashdevFlash deviceA single piece of flash hardware. E.g., “internal flash”, or “external SPI flash”.
MfgimageManufacturing imageA set of files describing the entire contents of a single flashdev. At manufacturing time, a separate mfgimage is created for each of the device's flashdevs.
Mfgimage main binaryThe binary file in an mfgimage that actually gets written to a flashdev.
MMRManufacturing Meta RegionA chunk of read-only data included in an mfgimage. Contains identifying information for the mfgimage and other data that stays with the device until end of life.

Manifest

Each mfgimage contains a manifest.json file. A manufacturing manifest contains metadata describing the mfgimage.

Top-level

Manufacturing manifests are formatted as a JSON object consisting of key-value pairs. Complex entries are further described in follow-up tables.

KeyDescription
nameName of mfgimage (informational).
build_timeTime mfgimage was created (informational).
formatThe format version of the mfgimage binary. The current version is 2
mfg_hashThe SHA256 of the mfgimage binary. To verify this hash, the embedded hash (if any) must be zeroed out prior to the calculation.
versionThe version number of this particular mfgimage (informational).
deviceThe integer index of the flash device this mfgimage is intended for.
bin_pathThe relative path of the main binary within the mfgimage.
hex_pathThe relative path of the hex version of the main binary within the mfgimage.
bspThe name of the BSP package that mfgimage was build for.
signaturesIf the mfgimage is signed, this is an array of all the signatures.
flash_mapThe BSP flash map at the time the mfgimage was created.
targetsAn array of entries, each corresponding to a Mynewt target that is present in the mfgimage.
metaA set of key-value pairs describing the manufacturing meta region (MMR)

Signatures

Mfgimages are signed to ensure integrity. Typically, Mynewt images embedded in the mfgimage are individually signed, so are already protected. The rest of the data in the mfgimage--boot loader, MMRs, configuration data, etc--is not individually signed. It is this second class of data that is protected by mfgimage signatures.

To sign an mfgimage, use the private key to sign the mfg_hash.

The signatures element is an array of objects, each consisting of the following key-value pairs:

KeyDescription
keyThe first four bytes of the SHA256 of the public key (hex string format).
sigThe full signature (hex string format).

Flash Map

Every mfgimage contains a flash map in its manifest. This information is present, even the MMR does not actually contain a flash map.

In the manifest, the flash_map entry is an array of flash area objects, each consisting of the following key-valur pairs:

KeyDescription
nameThe name of the flash area, as specified in bsp.yml.
idThe numeric ID of the flash area.
deviceThe numeric identifer of the flash device where the area resides.
offsetThe offset of the start of the flash area within its flash device.
sizeThe size of the flash area, in bytes.

Targets

Most mfgimages contain at least one target. A target can be either of 1) boot loader, or 2) Mynewt image. In the manifest, the targets entry indicates the targets present in the mfgimage. This entry is an array of target objects, each consisting of the following key-value pairs:

KeyDescription
nameThe name of the target, as specified in its pkg.yml file.
offsetThe offset of the target binary within the mfgimage main binary.
image_pathOnly present for image targets. The relative path of the Mynewt image file.
bin_pathOnly present for non-image targets. The relative path of the target binary.
manifest_pathThe relative path of the target manifest.

Meta

The meta manifest object describes the contents of an mfgimage's MMR. It consists of the following key-value pairs:

KeyDescription
end_offsetOne past the end of the MMR region, within the mfgimage main binary.
sizeThe size of the MMR, in bytes.
hash_presenttrue if the MMR contains a hash TLV; false otherwise.
flash_map_presenttrue if the MMR contains a set of flash area TLVs; false otherwise.
mmrsAn array of references to external MMRs.

MMR Structure

Every mfgimage contains an MMR (manufacturing meta region). The MMR is always located at the end of a flash area (that is, the last byte in the MMR occupies the last byte in the flash area).

In a boot mfgimage, the MMR must go in the first flash area, i.e., the area containing the boot loader. A non-boot mfgimage can place its MMR in any flash area.

The reason a boot mfgimage‘s MMR must go in the boot loader area is to solve a boot strapping problem. The flash map that bsp.yml defines is not necessarily the flash map that every device uses; it is just the flash map that gets embedded in newly built mfg images. This is so becauase the flash map itself is embedded in the boot mfgimage’s MMR. If we change the contents of bsp.yml and then start manufacturing devices with a new mfgimage, we now have two different flash maps being used in the field, even after all devices get upgraded to the latest firmware. Since MMR-0 itself contains the flash map, the firmware must not require a flash map lookup to find this MMR (i.e., chicken and egg). So this initial MMR always gets placed in the boot loader area and the firmware is hardcoded to look for it there.

An MMR has three basic components: header, TLVs, and footer.

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -,
    |Version (0x01) |                  0xff padding                 |   >-- Header
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -'
    |   TLV type    |   TLV size    | TLV data ("TLV size" bytes)   ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               ~
    ~                                                               ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   TLV type    |   TLV size    | TLV data ("TLV size" bytes)   ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               ~
    ~                                                               ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -,
    |   Region size                 |         0xff padding          |   \
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    >- Footer
    |                       Magic (0x3bb2a269)                      |   /
    +-+-+-+-+-+--+-+-+-+-end of boot loader area+-+-+-+-+-+-+-+-+-+-+ -'

All numeric fields are in host byte order (typically little endian).

The number of TLVs is variable; two are shown above for illustrative purposes.

Header

FieldDescription
VersionManufacturing meta version number; always 0x01.

TLVs

FieldDescription
TLV typeIndicates the type of data to follow.
TLV sizeThe number of bytes of data to follow.
TLV dataTLV-size bytes of data.

Footer

FieldDescription
Region sizeThe size, in bytes, of the entire manufacturing meta region; includes header, TLVs, and footer.
Magicindicates the presence of the manufacturing meta region.

Design

artifact/mfg

The artifact library defines the Mfg type. An Mfg is a barebones representation of an mfgimage. It contains a raw binary of everything except the MMR, and a slice of MMR TLVs. An Mfg is be converted to a flat byte slice with the following sequence:

  1. Calculate the SHA256 and add it to the MMR (Mfg#CalcHash())
  2. Extract the byte-slice representation (Mfg#Bytes())

An Mfg can be parsed from a byte slice using the Parse() function.

newt/mfg

High level

The newt tool creates mfgimages from:

  1. An mfg definition (including an mfg.yml file).
  2. Build artifacts for each target specified in the mfg.yml file.

Therefore, mfgimage creation typically goes something like this:

  1. Build boot loader: newt build <...>
  2. Create [signed, encrypted] images: newt create-image -2 <...> 1.2.3.4
  3. Build mfgimage: newt mfg create <...>

An mfgimage created by newt consists of:

  1. The binary flashdev contents.
  2. A manifest.json file describing the mfgimage.
  3. Build artifacts that were used as inputs.
Details

Newt performs a sequence of data structure transformations to produce the outputs listed above. In the sequence depicted below, objects are enclosed in [brackets], steps are enclosed in (parentheses).

          (decode)          (build)          (emit)
[MfgDecoder] --> [MfgBuilder] --> [MfgEmitter] --> [OUTPUT]

The steps are described below.

1. Decode

Newt parses and verifies the mfg.yml file.

2. Build

Newt uses the output of the decode step to determine which targets are included in the mfgimage. It ensures the targets have been built and that they all share the same BSP. Finally, it produces an artifact/Mfg object from the necessary binary files.

3. Emit

Newt produces the manifest and writes all the mfgimage files to disk.

File structure

Below is an example of an mfgimage's file structure:

bin/mfgs/<mfg-name>/
├── manifest.json
├── mfgimg.bin
├── mfgimg.hex
└── targets
    ├── 0
    │   ├── binary.bin
    │   ├── elf.elf
    │   ├── image.hex
    │   └── manifest.json
    ├── 1
    │   ├── elf.elf
    │   ├── image.hex
    │   ├── image.img
    │   └── manifest.json
    └── <N>
        ├── <...>
      <...>

Each of these files is described below:

FilenameDescription
manifest.jsonJSON file describing the mfgimage contents.
mfgimg.binThe mfgimage binary. This gets written to a Mynewt device.
mfgimg.hexThe hex version of the mfgimage binary. This gets written to a Mynewt device.
targetsA directory containing information about each target embedded in the mfgimage.
0/1/NCorreponds to an individual target. Targets are numbered in the order they appear in mfg.yml.
x/binary.binOnly present for boot loader targets. Contains the boot loader binary generated from the target.
x/elf.elfThe ELF file corresponding to the target binary.
x/image.imgOnly present for non-boot targets. Contains the image generated from the target.
x/image.hexContains the hex version of the image or boot loader binary generated from the target.
x/manifest.jsonJSON file describing the target.