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 2020/03/02 17:07:33 UTC

[mynewt-imgmod] branch master updated: mfg split: Don't discard trailing 0xff bytes

This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-imgmod.git


The following commit(s) were added to refs/heads/master by this push:
     new 66c90bf  mfg split: Don't discard trailing 0xff bytes
66c90bf is described below

commit 66c90bfda43352f045a4212e189fcccbe66bbc2c
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Feb 12 14:52:12 2020 -0800

    mfg split: Don't discard trailing 0xff bytes
    
    The `mfg split` command separates an mfgimg binary into several files,
    one for each flash area.
    
    Prior to this commit, imgmod would strip all trailing erase-val bytes
    (0xff) from each file.  Usually this was the correct behavior, but if
    the contents of a flash area legitimately ended with an erase-val byte,
    then the file would be corrupted during this step.
    
    The problem is that `newt` was throwing away information when it created
    mfgimages.  It embedded the specified binaries into a single mfgimage
    and filled in the gaps with erase-val bytes, and it did this without
    leaving any indication of the sizes of the binaries used as input.
    
    Newt was recently changed to include the sizes of these binaries in the
    `manifest.json` file that accompanies an mfgimage.  This commit changes
    imgmod to read these sizes from the manifest file so that it knows how
    many erase-val bytes it can safely strip.
    
    If the manifest does not contain size information (backwards
    compatibility), imgmod falls back to the old behavior or stripping all
    trailing erase-val bytes.
---
 cli/mfg_cmds.go |  2 +-
 imfg/imfg.go    | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/cli/mfg_cmds.go b/cli/mfg_cmds.go
index d8cfb18..80afb19 100644
--- a/cli/mfg_cmds.go
+++ b/cli/mfg_cmds.go
@@ -184,7 +184,7 @@ func runSplitCmd(cmd *cobra.Command, args []string) {
 		ImgmodUsage(nil, err)
 	}
 
-	nbmap, err := imfg.Split(bin, man.Device, areas, man.EraseVal)
+	nbmap, err := imfg.Split(bin, man, areas)
 	if err != nil {
 		ImgmodUsage(nil, err)
 	}
diff --git a/imfg/imfg.go b/imfg/imfg.go
index 93a0187..a8caddc 100644
--- a/imfg/imfg.go
+++ b/imfg/imfg.go
@@ -28,6 +28,7 @@ import (
 
 	"github.com/apache/mynewt-artifact/errors"
 	"github.com/apache/mynewt-artifact/flash"
+	"github.com/apache/mynewt-artifact/manifest"
 	"github.com/apache/mynewt-artifact/mfg"
 	"mynewt.apache.org/imgmod/iutil"
 )
@@ -78,8 +79,63 @@ func VerifyAreas(areas []flash.FlashArea) error {
 	return nil
 }
 
-func Split(mfgBin []byte, deviceNum int,
-	areas []flash.FlashArea, eraseVal byte) (NameBlobMap, error) {
+// areaDataEnd calculates the end offset of valid data in a flash area.  "Valid
+// data" includes all target binaries and raw sections.  If it cannot determine
+// the end of any constituent part, it returns an error.
+func areaDataEnd(area flash.FlashArea, man manifest.MfgManifest) (int, error) {
+	end := 0
+
+	// Updates `end` if the specified region extends beyond our current concept
+	// of "the end".
+	checkOne := func(offset int, size int) error {
+		a := man.FindWithinFlashAreaDevOff(man.Device, offset)
+		if a.Id != area.Id {
+			// Data belongs to a different area.
+			return nil
+		}
+
+		// Older manifests do not contain target size information.
+		if size <= 0 {
+			return errors.Errorf(
+				"failed to calculate end offset of data at %d: "+
+					"manifest lacks size",
+				offset)
+		}
+
+		subEnd := offset - a.Offset + size
+		if subEnd > end {
+			end = subEnd
+		}
+
+		return nil
+	}
+
+	for _, t := range man.Targets {
+		err := checkOne(t.Offset, t.Size)
+		if err != nil {
+			return 0, err
+		}
+	}
+
+	for _, r := range man.Raws {
+		err := checkOne(r.Offset, r.Size)
+		if err != nil {
+			return 0, err
+		}
+	}
+
+	if man.Meta != nil {
+		err := checkOne(man.Meta.EndOffset-1, 1)
+		if err != nil {
+			return 0, err
+		}
+	}
+
+	return end, nil
+}
+
+func Split(mfgBin []byte, man manifest.MfgManifest,
+	areas []flash.FlashArea) (NameBlobMap, error) {
 
 	mm := NameBlobMap{}
 
@@ -89,7 +145,7 @@ func Split(mfgBin []byte, deviceNum int,
 				"two or more flash areas with same name: \"%s\"", area.Name)
 		}
 
-		if area.Device == deviceNum {
+		if area.Device == man.Device {
 			var areaBin []byte
 			if area.Offset < len(mfgBin) {
 				end := area.Offset + area.Size
@@ -100,7 +156,17 @@ func Split(mfgBin []byte, deviceNum int,
 				areaBin = mfgBin[area.Offset:end]
 			}
 
-			mm[area.Name] = StripPadding(areaBin, eraseVal)
+			dataEnd, err := areaDataEnd(area, man)
+			if err != nil {
+				// Failed to determine the data end offset.  Just strip all
+				// trailing erase-val bytes.
+				areaBin = StripPadding(areaBin, man.EraseVal)
+			} else {
+				areaBin = areaBin[:dataEnd]
+			}
+			if len(areaBin) > 0 {
+				mm[area.Name] = areaBin
+			}
 		}
 	}