You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/11/02 15:12:14 UTC
incubator-mynewt-newt git commit: newt - clean up mfg image code
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/develop a1cb7024e -> cc1c2dd81
newt - clean up mfg image code
This code had gone through a few changes in requirements. This commit
rewrites parts of it without changing its behavior.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/cc1c2dd8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/cc1c2dd8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/cc1c2dd8
Branch: refs/heads/develop
Commit: cc1c2dd81204baf9235a7377c0d0814f1f35da3d
Parents: a1cb702
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Nov 2 08:12:44 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Nov 2 08:13:49 2016 -0700
----------------------------------------------------------------------
newt/mfg/create.go | 216 +++++++++++++++++++++++++++---------------------
newt/mfg/load.go | 83 +++++++------------
newt/mfg/mfg.go | 3 +-
3 files changed, 153 insertions(+), 149 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/cc1c2dd8/newt/mfg/create.go
----------------------------------------------------------------------
diff --git a/newt/mfg/create.go b/newt/mfg/create.go
index 2a7f36f..fc11f75 100644
--- a/newt/mfg/create.go
+++ b/newt/mfg/create.go
@@ -25,6 +25,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "sort"
"time"
"mynewt.apache.org/newt/newt/builder"
@@ -52,7 +53,10 @@ func insertPartIntoBlob(blob []byte, part mfgPart) {
func (mi *MfgImage) partFromImage(
imgPath string, flashAreaName string) (mfgPart, error) {
- part := mfgPart{}
+ part := mfgPart{
+ // Boot loader and images always go in device 0.
+ device: 0,
+ }
area, ok := mi.bsp.FlashMap.Areas[flashAreaName]
if !ok {
@@ -79,75 +83,155 @@ func (mi *MfgImage) partFromImage(
imgPath, flashAreaName, len(part.data), area.Size, overflow)
}
+ // If an image slot is used, the entire flash area is unwritable. This
+ // restriction comes from the boot loader's need to write status at the end
+ // of an area. Pad out part with unwriten flash (0xff). This probably
+ // isn't terribly efficient...
+ for i := 0; i < -overflow; i++ {
+ part.data = append(part.data, 0xff)
+ }
+
return part, nil
}
-func (mi *MfgImage) section0Size() int {
- greatest := 0
+func partFromRawEntry(entry MfgRawEntry, entryIdx int) mfgPart {
+ return mfgPart{
+ name: fmt.Sprintf("entry-%d (%s)", entryIdx, entry.filename),
+ offset: entry.offset,
+ data: entry.data,
+ }
+}
- bootArea := mi.bsp.FlashMap.Areas[flash.FLASH_AREA_NAME_BOOTLOADER]
- image0Area := mi.bsp.FlashMap.Areas[flash.FLASH_AREA_NAME_IMAGE_0]
- image1Area := mi.bsp.FlashMap.Areas[flash.FLASH_AREA_NAME_IMAGE_1]
+func (mi *MfgImage) targetParts() ([]mfgPart, error) {
+ parts := []mfgPart{}
- if mi.boot != nil {
- greatest = util.IntMax(greatest, bootArea.Offset+bootArea.Size)
- }
- if len(mi.images) >= 1 {
- greatest = util.IntMax(greatest, image0Area.Offset+image0Area.Size)
+ bootPath := mi.dstBootBinPath()
+ if bootPath != "" {
+ bootPart, err := mi.partFromImage(
+ bootPath, flash.FLASH_AREA_NAME_BOOTLOADER)
+ if err != nil {
+ return nil, err
+ }
+
+ parts = append(parts, bootPart)
}
- if len(mi.images) >= 2 {
- greatest = util.IntMax(greatest, image1Area.Offset+image1Area.Size)
+
+ for i := 0; i < 2; i++ {
+ imgPath := mi.dstImgPath(i)
+ if imgPath != "" {
+ areaName, err := areaNameFromImgIdx(i)
+ if err != nil {
+ return nil, err
+ }
+
+ part, err := mi.partFromImage(imgPath, areaName)
+ if err != nil {
+ return nil, err
+ }
+ parts = append(parts, part)
+ }
}
- for _, entry := range mi.rawEntries {
- greatest = util.IntMax(greatest, entry.offset+len(entry.data))
+ return parts, nil
+}
+
+func sectionSize(parts []mfgPart) int {
+ greatest := 0
+
+ for _, part := range parts {
+ end := part.offset + len(part.data)
+ greatest = util.IntMax(greatest, end)
}
return greatest
}
-// @return section-0-blob, hash-offset, error
-func (mi *MfgImage) section0Data(parts []mfgPart) ([]byte, int, error) {
- blobSize := mi.section0Size()
- blob := make([]byte, blobSize)
+func sectionFromParts(parts []mfgPart) []byte {
+ sectionSize := sectionSize(parts)
+ section := make([]byte, sectionSize)
// Initialize section 0's data as unwritten flash (0xff).
- for i, _ := range blob {
- blob[i] = 0xff
+ for i, _ := range section {
+ section[i] = 0xff
}
for _, part := range parts {
- insertPartIntoBlob(blob, part)
+ insertPartIntoBlob(section, part)
+ }
+
+ return section
+}
+
+func (mi *MfgImage) devicePartMap() (map[int][]mfgPart, error) {
+ dpMap := map[int][]mfgPart{}
+
+ // Create parts from the raw entries.
+ for i, entry := range mi.rawEntries {
+ part := partFromRawEntry(entry, i)
+ dpMap[entry.device] = append(dpMap[entry.device], part)
}
- hashOffset, err := insertMeta(blob, mi.bsp.FlashMap)
+ // Insert the boot loader and image parts into section 0.
+ targetParts, err := mi.targetParts()
if err != nil {
- return nil, 0, err
+ return nil, err
}
+ dpMap[0] = append(dpMap[0], targetParts...)
- return blob, hashOffset, nil
+ // Sort each part slice by offset.
+ for device, _ := range dpMap {
+ sortParts(dpMap[device])
+ }
+ return dpMap, nil
+}
+
+func (mi *MfgImage) deviceSectionMap() (map[int][]byte, error) {
+ dpMap, err := mi.devicePartMap()
+ if err != nil {
+ return nil, err
+ }
+
+ // Convert each part slice into a section (byte slice).
+ dsMap := map[int][]byte{}
+ for device, parts := range dpMap {
+ dsMap[device] = sectionFromParts(parts)
+ }
+
+ return dsMap, nil
}
// @return [section0blob, section1blob,...], hash, err
-func (mi *MfgImage) createSections(parts []mfgPart) (
- [][]byte, []byte, error) {
+func (mi *MfgImage) createSections() (map[int][]byte, []byte, error) {
+ dsMap, err := mi.deviceSectionMap()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if dsMap[0] == nil {
+ panic("Invalid state; no section 0")
+ }
- section0Data, hashOff, err := mi.section0Data(parts)
+ hashOffset, err := insertMeta(dsMap[0], mi.bsp.FlashMap)
if err != nil {
return nil, nil, err
}
- // XXX: Append additional sections.
+ // Calculate manufacturing hash.
+ devices := make([]int, 0, len(dsMap))
+ for device, _ := range dsMap {
+ devices = append(devices, device)
+ }
+ sort.Ints(devices)
- // Calculate manufacturing has.
- sections := [][]byte{section0Data}
+ sections := make([][]byte, len(devices))
+ for i, device := range devices {
+ sections[i] = dsMap[device]
+ }
hash := calcMetaHash(sections)
+ copy(dsMap[0][hashOffset:hashOffset+META_HASH_SZ], hash)
- // Write hash to meta region in section 0.
- copy(section0Data[hashOff:hashOff+META_HASH_SZ], hash)
-
- return sections, hash, nil
+ return dsMap, hash, nil
}
func areaNameFromImgIdx(imgIdx int) (string, error) {
@@ -161,17 +245,6 @@ func areaNameFromImgIdx(imgIdx int) (string, error) {
}
}
-func (mi *MfgImage) rawEntryParts() []mfgPart {
- parts := make([]mfgPart, len(mi.rawEntries))
- for i, entry := range mi.rawEntries {
- parts[i].name = fmt.Sprintf("entry-%d (%s)", i, entry.filename)
- parts[i].offset = entry.offset
- parts[i].data = entry.data
- }
-
- return parts
-}
-
func bootLoaderFromPaths(t *target.Target) []string {
return []string{
/* boot.elf */
@@ -308,39 +381,6 @@ func (mi *MfgImage) dstImgPath(slotIdx int) string {
MfgImageBinDir(mi.basePkg.Name(), imgIdx), pkg.ShortName(pack))
}
-func (mi *MfgImage) targetParts() ([]mfgPart, error) {
- parts := []mfgPart{}
-
- bootPath := mi.dstBootBinPath()
- if bootPath != "" {
- bootPart, err := mi.partFromImage(
- bootPath, flash.FLASH_AREA_NAME_BOOTLOADER)
- if err != nil {
- return nil, err
- }
-
- parts = append(parts, bootPart)
- }
-
- for i := 0; i < 2; i++ {
- imgPath := mi.dstImgPath(i)
- if imgPath != "" {
- areaName, err := areaNameFromImgIdx(i)
- if err != nil {
- return nil, err
- }
-
- part, err := mi.partFromImage(imgPath, areaName)
- if err != nil {
- return nil, err
- }
- parts = append(parts, part)
- }
- }
-
- return parts, nil
-}
-
// Returns a slice containing the path of each file required to build the
// manufacturing image.
func (mi *MfgImage) FromPaths() []string {
@@ -364,22 +404,12 @@ func (mi *MfgImage) FromPaths() []string {
}
// @return [section0blob, section1blob,...], hash, err
-func (mi *MfgImage) build() ([][]byte, []byte, error) {
+func (mi *MfgImage) build() (map[int][]byte, []byte, error) {
if err := mi.copyBinFiles(); err != nil {
return nil, nil, err
}
- targetParts, err := mi.targetParts()
- if err != nil {
- return nil, nil, err
- }
-
- rawParts := mi.rawEntryParts()
-
- parts := append(targetParts, rawParts...)
- sortParts(parts)
-
- sections, hash, err := mi.createSections(parts)
+ sections, hash, err := mi.createSections()
if err != nil {
return nil, nil, err
}
@@ -442,8 +472,8 @@ func (mi *MfgImage) CreateMfgImage() ([]string, error) {
return nil, util.ChildNewtError(err)
}
- for i, section := range sections {
- sectionPath := MfgSectionBinPath(mi.basePkg.Name(), i)
+ for device, section := range sections {
+ sectionPath := MfgSectionBinPath(mi.basePkg.Name(), device)
if err := ioutil.WriteFile(sectionPath, section, 0644); err != nil {
return nil, util.ChildNewtError(err)
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/cc1c2dd8/newt/mfg/load.go
----------------------------------------------------------------------
diff --git a/newt/mfg/load.go b/newt/mfg/load.go
index 6e986ae..ef75d4d 100644
--- a/newt/mfg/load.go
+++ b/newt/mfg/load.go
@@ -28,13 +28,14 @@ import (
"github.com/spf13/cast"
- "mynewt.apache.org/newt/newt/flash"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/newt/target"
"mynewt.apache.org/newt/util"
)
+const MFG_YAML_FILENAME string = "mfg.yml"
+
type partSorter struct {
parts []mfgPart
}
@@ -129,21 +130,6 @@ func (mi *MfgImage) loadRawEntry(
return raw, nil
}
-func (mi *MfgImage) areaNameToPart(areaName string) (mfgPart, bool) {
- part := mfgPart{}
-
- area, ok := mi.bsp.FlashMap.Areas[areaName]
- if !ok {
- return part, false
- }
-
- part.offset = area.Offset
- part.data = make([]byte, area.Size)
- part.name = area.Name
-
- return part, true
-}
-
func (mi *MfgImage) detectInvalidDevices() error {
sectionIds := mi.sectionIds()
deviceIds := mi.bsp.FlashMap.DeviceIds()
@@ -183,45 +169,33 @@ func (mi *MfgImage) detectOverlaps() error {
part1 mfgPart
}
- parts := []mfgPart{}
-
- // If an image slot is used, the entire flash area is unwritable. This
- // restriction comes from the boot loader's need to write status at the end
- // of an area.
- if mi.boot != nil {
- part, ok := mi.areaNameToPart(flash.FLASH_AREA_NAME_BOOTLOADER)
- if ok {
- parts = append(parts, part)
- }
- }
- if len(mi.images) >= 1 {
- part, ok := mi.areaNameToPart(flash.FLASH_AREA_NAME_IMAGE_0)
- if ok {
- parts = append(parts, part)
- }
- }
- if len(mi.images) >= 2 {
- part, ok := mi.areaNameToPart(flash.FLASH_AREA_NAME_IMAGE_1)
- if ok {
- parts = append(parts, part)
- }
- }
-
- parts = append(parts, mi.rawEntryParts()...)
- sortParts(parts)
-
overlaps := []overlap{}
- for i, part0 := range parts[:len(parts)-1] {
- part0End := part0.offset + len(part0.data)
- for _, part1 := range parts[i+1:] {
- // Parts are sorted by offset, so only one comparison is necessary
- // to detect overlap.
- if part1.offset < part0End {
- overlaps = append(overlaps, overlap{
- part0: part0,
- part1: part1,
- })
+ dpMap, err := mi.devicePartMap()
+ if err != nil {
+ return err
+ }
+
+ // Iterate flash devices in order.
+ devices := make([]int, 0, len(dpMap))
+ for device, _ := range dpMap {
+ devices = append(devices, device)
+ }
+ sort.Ints(devices)
+
+ for _, device := range devices {
+ parts := dpMap[device]
+ for i, part0 := range parts[:len(parts)-1] {
+ part0End := part0.offset + len(part0.data)
+ for _, part1 := range parts[i+1:] {
+ // Parts are sorted by offset, so only one comparison is
+ // necessary to detect overlap.
+ if part1.offset < part0End {
+ overlaps = append(overlaps, overlap{
+ part0: part0,
+ part1: part1,
+ })
+ }
}
}
}
@@ -232,7 +206,8 @@ func (mi *MfgImage) detectOverlaps() error {
part0End := overlap.part0.offset + len(overlap.part0.data)
part1End := overlap.part1.offset + len(overlap.part1.data)
- str += fmt.Sprintf("\n * [%s] (%d - %d) <=> [%s] (%d - %d)",
+ str += fmt.Sprintf("\n * s%d [%s] (%d - %d) <=> [%s] (%d - %d)",
+ overlap.part0.device,
overlap.part0.name, overlap.part0.offset, part0End,
overlap.part1.name, overlap.part1.offset, part1End)
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/cc1c2dd8/newt/mfg/mfg.go
----------------------------------------------------------------------
diff --git a/newt/mfg/mfg.go b/newt/mfg/mfg.go
index ea31f85..999c00f 100644
--- a/newt/mfg/mfg.go
+++ b/newt/mfg/mfg.go
@@ -26,8 +26,6 @@ import (
"mynewt.apache.org/newt/newt/target"
)
-const MFG_YAML_FILENAME string = "mfg.yml"
-
type MfgRawEntry struct {
device int
offset int
@@ -38,6 +36,7 @@ type MfgRawEntry struct {
// A chunk of data in the manufacturing image. Can be a firmware image or a
// raw entry (contents of a data file).
type mfgPart struct {
+ device int
offset int
data []byte
name string