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 <ccoll...@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 + } } }