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 2017/03/03 00:52:24 UTC
incubator-mynewt-newt git commit: MYNEWT-509 - Newt: fail on image
flash overflow.
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/develop a404a47c6 -> 0a3ce8e9f
MYNEWT-509 - Newt: fail on image flash overflow.
Ensure each generated image leaves sufficient room at the end of its
slot for a boot trailer. Newt calculates the size of a boot trailer by
using the MCU_FLASH_MIN_WRITE_SIZE syscfg setting (newly added to each
MCU package). If this setting is not defined, newt warns the user and
assumes a min-write-size of 1.
The "-f" (force) option causes newt to only warn about overflow.
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/0a3ce8e9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/0a3ce8e9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/0a3ce8e9
Branch: refs/heads/develop
Commit: 0a3ce8e9ff3331dca7ad11853563c6da6fced01a
Parents: a404a47
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Mar 2 16:09:01 2017 -0800
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Mar 2 16:52:10 2017 -0800
----------------------------------------------------------------------
newt/builder/targetbuild.go | 113 +++++++++++++++++++++++++++++++++++++++
newt/cli/image_cmds.go | 7 ++-
newt/cli/project_cmds.go | 20 +++----
newt/cli/run_cmds.go | 5 ++
newt/cli/target_cmds.go | 7 ++-
newt/image/image.go | 9 ++++
newt/newtutil/newtutil.go | 1 +
7 files changed, 149 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0a3ce8e9/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 2576764..c522597 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -31,8 +31,10 @@ import (
log "github.com/Sirupsen/logrus"
+ "mynewt.apache.org/newt/newt/flash"
"mynewt.apache.org/newt/newt/image"
"mynewt.apache.org/newt/newt/interfaces"
+ "mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/newt/resolve"
@@ -645,6 +647,113 @@ func (t *TargetBuilder) augmentManifest(
return nil
}
+// Calculates the size of a single boot trailer. This is the amount of flash
+// that must be reserved at the end of each image slot.
+func (t *TargetBuilder) bootTrailerSize() int {
+ var minWriteSz int
+
+ entry, ok := t.res.Cfg.Settings["MCU_FLASH_MIN_WRITE_SIZE"]
+ if !ok {
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ "* Warning: target does not define MCU_FLASH_MIN_WRITE_SIZE "+
+ "setting; assuming a value of 1.\n")
+ minWriteSz = 1
+ } else {
+ val, err := util.AtoiNoOct(entry.Value)
+ if err != nil {
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ "* Warning: target specifies invalid non-integer "+
+ "MCU_FLASH_MIN_WRITE_SIZE setting; assuming a "+
+ "value of 1.\n")
+ minWriteSz = 1
+ } else {
+ minWriteSz = val
+ }
+ }
+
+ /* Mynewt boot trailer format:
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ MAGIC (16 octets) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ ~
+ * ~ Swap status (128 * min-write-size * 3) ~
+ * ~ ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Copy done | 0xff padding (up to min-write-sz - 1) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Image OK | 0xff padding (up to min-write-sz - 1) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+ tsize := 16 + // Magic.
+ 128*minWriteSz*3 + // Swap status.
+ minWriteSz + // Copy done.
+ minWriteSz // Image Ok.
+
+ log.Debugf("Min-write-size=%d; boot-trailer-size=%d", minWriteSz, tsize)
+
+ return tsize
+}
+
+// Calculates the size of the largest image that can be written to each image
+// slot.
+func (t *TargetBuilder) maxImgSizes() []int {
+ sz0 := t.bspPkg.FlashMap.Areas[flash.FLASH_AREA_NAME_IMAGE_0].Size
+ sz1 := t.bspPkg.FlashMap.Areas[flash.FLASH_AREA_NAME_IMAGE_1].Size
+ trailerSz := t.bootTrailerSize()
+
+ return []int{
+ sz0 - trailerSz,
+ sz1 - trailerSz,
+ }
+}
+
+// Verifies that each already-built image leaves enough room for a boot trailer
+// a the end of its slot.
+func (t *TargetBuilder) verifyImgSizes(li *image.Image, ai *image.Image) error {
+ maxSizes := t.maxImgSizes()
+
+ errLines := []string{}
+ if li != nil {
+ if overflow := int(li.TotalSize) - maxSizes[0]; overflow > 0 {
+ errLines = append(errLines,
+ fmt.Sprintf("loader overflows slot-0 by %d bytes "+
+ "(image=%d max=%d)",
+ overflow, li.TotalSize, maxSizes[0]))
+ }
+ if overflow := int(ai.TotalSize) - maxSizes[1]; overflow > 0 {
+ errLines = append(errLines,
+ fmt.Sprintf("app overflows slot-1 by %d bytes "+
+ "(image=%d max=%d)",
+ overflow, ai.TotalSize, maxSizes[1]))
+
+ }
+ } else {
+ if overflow := int(ai.TotalSize) - maxSizes[0]; overflow > 0 {
+ errLines = append(errLines,
+ fmt.Sprintf("app overflows slot-0 by %d bytes "+
+ "(image=%d max=%d)",
+ overflow, ai.TotalSize, maxSizes[0]))
+ }
+ }
+
+ if len(errLines) > 0 {
+ if !newtutil.NewtForce {
+ return util.NewNewtError(strings.Join(errLines, "; "))
+ } else {
+ for _, e := range errLines {
+ util.StatusMessage(util.VERBOSITY_QUIET,
+ "* Warning: %s (ignoring due to force flag)\n", e)
+ }
+ }
+ }
+
+ return nil
+}
+
// @return app-image, loader-image, error
func (t *TargetBuilder) CreateImages(version string,
keystr string, keyId uint8) (*image.Image, *image.Image, error) {
@@ -675,6 +784,10 @@ func (t *TargetBuilder) CreateImages(version string,
return nil, nil, err
}
+ if err := t.verifyImgSizes(loaderImg, appImg); err != nil {
+ return nil, nil, err
+ }
+
return appImg, loaderImg, nil
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0a3ce8e9/newt/cli/image_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/image_cmds.go b/newt/cli/image_cmds.go
index 991c4c5..5a19c63 100644
--- a/newt/cli/image_cmds.go
+++ b/newt/cli/image_cmds.go
@@ -24,6 +24,7 @@ import (
"github.com/spf13/cobra"
"mynewt.apache.org/newt/newt/builder"
+ "mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/util"
)
@@ -63,7 +64,7 @@ func createImageRunCmd(cmd *cobra.Command, args []string) {
}
if _, _, err := b.CreateImages(version, keystr, keyId); err != nil {
- NewtUsage(cmd, err)
+ NewtUsage(nil, err)
return
}
}
@@ -85,6 +86,10 @@ func AddImageCommands(cmd *cobra.Command) {
Run: createImageRunCmd,
}
+ createImageCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
+ "force", "f", false,
+ "Ignore flash overflow errors during image creation")
+
cmd.AddCommand(createImageCmd)
AddTabCompleteFn(createImageCmd, targetList)
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0a3ce8e9/newt/cli/project_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/project_cmds.go b/newt/cli/project_cmds.go
index 003a42c..a8d93b2 100644
--- a/newt/cli/project_cmds.go
+++ b/newt/cli/project_cmds.go
@@ -32,9 +32,6 @@ import (
"mynewt.apache.org/newt/util"
)
-var projectForce bool = false
-var syncForce bool = false
-
func newRunCmd(cmd *cobra.Command, args []string) {
if len(args) < 1 {
NewtUsage(cmd, util.NewNewtError("Must specify "+
@@ -78,7 +75,7 @@ func installRunCmd(cmd *cobra.Command, args []string) {
proj := TryGetProject()
interfaces.SetProject(proj)
- if err := proj.Install(false, projectForce); err != nil {
+ if err := proj.Install(false, newtutil.NewtForce); err != nil {
NewtUsage(cmd, err)
}
}
@@ -87,7 +84,7 @@ func upgradeRunCmd(cmd *cobra.Command, args []string) {
proj := TryGetProject()
interfaces.SetProject(proj)
- if err := proj.Upgrade(projectForce); err != nil {
+ if err := proj.Upgrade(newtutil.NewtForce); err != nil {
NewtUsage(cmd, err)
}
}
@@ -170,11 +167,11 @@ func syncRunCmd(cmd *cobra.Command, args []string) {
"No installed version of %s found, skipping\n",
repo.Name())
}
- if err, exists = repo.Sync(vers, syncForce); err != nil {
+ if err, exists = repo.Sync(vers, newtutil.NewtForce); err != nil {
NewtUsage(nil, err)
}
- if exists && !syncForce {
+ if exists && !newtutil.NewtForce {
util.StatusMessage(util.VERBOSITY_DEFAULT,
"Skipping resync of %s because directory exists. To "+
"force resync, add the -f (force) option.\n", repo.Name())
@@ -192,7 +189,8 @@ func AddProjectCommands(cmd *cobra.Command) {
Example: installHelpEx,
Run: installRunCmd,
}
- installCmd.PersistentFlags().BoolVarP(&projectForce, "force", "f", false,
+ installCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
+ "force", "f", false,
"Force install of the repositories in project, regardless of what "+
"exists in repos directory")
@@ -207,7 +205,8 @@ func AddProjectCommands(cmd *cobra.Command) {
Example: upgradeHelpEx,
Run: upgradeRunCmd,
}
- upgradeCmd.PersistentFlags().BoolVarP(&projectForce, "force", "f", false,
+ upgradeCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
+ "force", "f", false,
"Force upgrade of the repositories to latest state in project.yml")
cmd.AddCommand(upgradeCmd)
@@ -221,7 +220,8 @@ func AddProjectCommands(cmd *cobra.Command) {
Example: syncHelpEx,
Run: syncRunCmd,
}
- syncCmd.PersistentFlags().BoolVarP(&syncForce, "force", "f", false,
+ syncCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
+ "force", "f", false,
"Force overwrite of existing remote repositories.")
cmd.AddCommand(syncCmd)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0a3ce8e9/newt/cli/run_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/run_cmds.go b/newt/cli/run_cmds.go
index 8f923bb..16620dd 100644
--- a/newt/cli/run_cmds.go
+++ b/newt/cli/run_cmds.go
@@ -23,6 +23,8 @@ import (
"os"
"github.com/spf13/cobra"
+
+ "mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/util"
)
@@ -102,6 +104,9 @@ func AddRunCommands(cmd *cobra.Command) {
"Extra commands to send to JTAG software")
runCmd.PersistentFlags().BoolVarP(&noGDB_flag, "noGDB", "n", false,
"Do not start GDB from command line")
+ runCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
+ "force", "f", false,
+ "Ignore flash overflow errors during image creation")
cmd.AddCommand(runCmd)
AddTabCompleteFn(runCmd, func() []string {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0a3ce8e9/newt/cli/target_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index a6ea7df..786838c 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -31,6 +31,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/spf13/cobra"
"mynewt.apache.org/newt/newt/builder"
+ "mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/resolve"
"mynewt.apache.org/newt/newt/syscfg"
@@ -717,7 +718,8 @@ func AddTargetCommands(cmd *cobra.Command) {
Example: delHelpEx,
Run: targetDelCmd,
}
- delCmd.PersistentFlags().BoolVarP(&targetForce, "force", "f", false,
+ delCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
+ "force", "f", false,
"Force delete of targets with user files without prompt")
targetCmd.AddCommand(delCmd)
@@ -768,7 +770,8 @@ func AddTargetCommands(cmd *cobra.Command) {
"Unspecified settings are given default values.",
Run: targetConfigInitCmd,
}
- configInitCmd.PersistentFlags().BoolVarP(&targetForce, "force", "f", false,
+ configInitCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
+ "force", "f", false,
"Force overwrite of target configuration")
configCmd.AddCommand(configInitCmd)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0a3ce8e9/newt/image/image.go
----------------------------------------------------------------------
diff --git a/newt/image/image.go b/newt/image/image.go
index c63eb2e..3589275 100644
--- a/newt/image/image.go
+++ b/newt/image/image.go
@@ -63,6 +63,7 @@ type Image struct {
Hash []byte
SrcSkip uint // Number of bytes to skip from the source image.
HeaderSize uint // If non-zero pad out the header to this size.
+ TotalSize uint // Total size, in bytes, of the generated .img file.
}
type ImageHdr struct {
@@ -582,6 +583,14 @@ func (image *Image) Generate(loader *Image) error {
util.StatusMessage(util.VERBOSITY_VERBOSE,
"Computed Hash for image %s as %s \n",
image.TargetImg, hex.EncodeToString(image.Hash))
+
+ sz, err := imgFile.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return util.FmtNewtError("Failed to calculate file size of generated "+
+ "image %s: %s", image.TargetImg, err.Error())
+ }
+ image.TotalSize = uint(sz)
+
return nil
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0a3ce8e9/newt/newtutil/newtutil.go
----------------------------------------------------------------------
diff --git a/newt/newtutil/newtutil.go b/newt/newtutil/newtutil.go
index 824e3af..48ef4a0 100644
--- a/newt/newtutil/newtutil.go
+++ b/newt/newtutil/newtutil.go
@@ -37,6 +37,7 @@ import (
var NewtVersionStr string = "Apache Newt (incubating) version: 1.0.0-dev"
var NewtBlinkyTag string = "develop"
var NewtNumJobs int
+var NewtForce bool
const NEWTRC_DIR string = ".newt"
const REPOS_FILENAME string = "repos.yml"