You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/03/08 20:11:46 UTC
incubator-mynewt-newt git commit: Add download/debug commands.
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/rename_project_app b1c09ba2b -> 32463b455
Add download/debug commands.
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/32463b45
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/32463b45
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/32463b45
Branch: refs/heads/rename_project_app
Commit: 32463b4559f4d5380074ba5b8cdca4656bfb84d3
Parents: b1c09ba
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Mar 8 11:11:17 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Mar 8 11:11:17 2016 -0800
----------------------------------------------------------------------
newt/builder/buildutil.go | 8 +
newt/builder/cmds.go | 68 +++++++++
newt/builder/download.go | 81 ++++++++++
newt/image/cmds.go | 72 +++++++++
newt/image/image.go | 329 +++++++++++++++++++++++++++++++++++++++++
newt/newt.go | 2 +
newt/target/cmds.go | 41 -----
newt/target/image.go | 328 ----------------------------------------
newt/target/target.go | 16 +-
9 files changed, 567 insertions(+), 378 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/builder/buildutil.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index 06de849..0091def 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -69,6 +69,14 @@ func (b *Builder) logFeatures() {
cli.StatusMessage(cli.VERBOSITY_VERBOSE, buffer.String())
}
+func (b *Builder) featureString() string {
+ featureString := ""
+ for feature, _ := range b.features {
+ featureString = featureString + " " + feature
+ }
+ return featureString
+}
+
// Makes sure all packages with required APIs have been augmented a dependency
// which satisfies that requirement. If there are any unsatisfied
// requirements, an error is returned.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/builder/cmds.go
----------------------------------------------------------------------
diff --git a/newt/builder/cmds.go b/newt/builder/cmds.go
index a6f2c89..472ae6d 100644
--- a/newt/builder/cmds.go
+++ b/newt/builder/cmds.go
@@ -118,6 +118,50 @@ func testRunCmd(cmd *cobra.Command, args []string) {
}
}
+func downloadRunCmd(cmd *cobra.Command, args []string) {
+ if len(args) < 1 {
+ cli.NewtUsage(cmd, util.NewNewtError("Must specify target"))
+ }
+
+ targetName := args[0]
+ t := target.GetTargets()[targetName]
+ if t == nil {
+ cli.NewtUsage(cmd, util.NewNewtError("Invalid target name"))
+ }
+
+ b, err := NewBuilder(t)
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ err = b.Download()
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+
+func debugRunCmd(cmd *cobra.Command, args []string) {
+ if len(args) < 1 {
+ cli.NewtUsage(cmd, util.NewNewtError("Must specify target"))
+ }
+
+ targetName := args[0]
+ t := target.GetTargets()[targetName]
+ if t == nil {
+ cli.NewtUsage(cmd, util.NewNewtError("Invalid target name"))
+ }
+
+ b, err := NewBuilder(t)
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ err = b.Debug()
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+
func AddCommands(cmd *cobra.Command) {
buildHelpText := ""
buildHelpEx := ""
@@ -154,4 +198,28 @@ func AddCommands(cmd *cobra.Command) {
}
cmd.AddCommand(testCmd)
+
+ downloadHelpText := "Download project image to target for <target-name>."
+ downloadHelpEx := " newt download <target-name>\n"
+
+ downloadCmd := &cobra.Command{
+ Use: "download",
+ Short: "Download built target to board",
+ Long: downloadHelpText,
+ Example: downloadHelpEx,
+ Run: downloadRunCmd,
+ }
+ cmd.AddCommand(downloadCmd)
+
+ debugHelpText := "Download project image to target for <target-name>.";
+ debugHelpEx := " newt debug <target-name>\n"
+
+ debugCmd := &cobra.Command{
+ Use: "debug",
+ Short: "Open debugger session to target",
+ Long: debugHelpText,
+ Example: debugHelpEx,
+ Run: debugRunCmd,
+ }
+ cmd.AddCommand(debugCmd)
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/builder/download.go
----------------------------------------------------------------------
diff --git a/newt/builder/download.go b/newt/builder/download.go
new file mode 100644
index 0000000..0cbba72
--- /dev/null
+++ b/newt/builder/download.go
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package builder
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "mynewt.apache.org/newt/newt/cli"
+ "mynewt.apache.org/newt/newt/project"
+ "mynewt.apache.org/newt/util"
+)
+
+func (b *Builder) Download() error {
+ if b.target.App() == nil {
+ return util.NewNewtError("app package not specified")
+ }
+
+ /*
+ * Populate the package and feature sets.
+ */
+ err := b.prepBuild()
+ if err != nil {
+ return err
+ }
+
+ bspPath := b.Bsp.BasePath()
+ downloadScript := filepath.Join(bspPath, b.Bsp.DownloadScript)
+ binBaseName := b.target.BinBasePath()
+ featureString := b.featureString()
+
+ downloadCmd := fmt.Sprintf("%s %s %s %s",
+ downloadScript, bspPath, binBaseName, featureString)
+
+ rsp, err := cli.ShellCommand(downloadCmd)
+ fmt.Printf("%s", rsp)
+
+ return err
+}
+
+func (b *Builder) Debug() error {
+ if b.target.App() == nil {
+ return util.NewNewtError("app package not specified")
+ }
+
+ /*
+ * Populate the package and feature sets.
+ */
+ err := b.prepBuild()
+ if err != nil {
+ return err
+ }
+
+ bspPath := b.Bsp.BasePath()
+ debugScript := filepath.Join(bspPath, b.Bsp.DebugScript)
+ binBaseName := b.target.BinBasePath()
+ featureString := b.featureString()
+
+ os.Chdir(project.GetProject().Path())
+
+ cmdLine := []string{debugScript, bspPath, binBaseName, featureString}
+ return cli.ShellInteractiveCommand(cmdLine)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/image/cmds.go
----------------------------------------------------------------------
diff --git a/newt/image/cmds.go b/newt/image/cmds.go
new file mode 100644
index 0000000..d169b21
--- /dev/null
+++ b/newt/image/cmds.go
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package image
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+ "mynewt.apache.org/newt/newt/cli"
+ "mynewt.apache.org/newt/newt/target"
+ "mynewt.apache.org/newt/util"
+)
+
+func createImageRunCmd(cmd *cobra.Command, args []string) {
+ if len(args) < 2 {
+ cli.NewtUsage(cmd, util.NewNewtError("Must specify target and version"))
+ }
+
+ targetName := args[0]
+ t := target.GetTargets()[targetName]
+ if t == nil {
+ cli.NewtUsage(cmd, util.NewNewtError("Invalid target name"))
+ }
+
+ image, err := NewImage(t)
+ if err != nil {
+ fmt.Println(err)
+ }
+ err = image.SetVersion(args[1])
+ if err != nil {
+ cli.NewtUsage(cmd, err)
+ }
+ err = image.Generate()
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+
+func AddCommands(cmd *cobra.Command) {
+ createImageHelpText := "Create image by adding image header to created "+
+ "binary file for <target-name>. Version number in the header is set "+
+ "to be <version>."
+ createImageHelpEx := " newt create-image <target-name> <version>\n"
+ createImageHelpEx += " newt create-image my_target1 1.2.0\n"
+ createImageHelpEx += " newt create-image my_target1 1.2.0.3\n"
+
+ createImageCmd := &cobra.Command{
+ Use: "create-image",
+ Short: "Add image header to target binary",
+ Long: createImageHelpText,
+ Example: createImageHelpEx,
+ Run: createImageRunCmd,
+ }
+ cmd.AddCommand(createImageCmd)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/image/image.go
----------------------------------------------------------------------
diff --git a/newt/image/image.go b/newt/image/image.go
new file mode 100644
index 0000000..edd3bfd
--- /dev/null
+++ b/newt/image/image.go
@@ -0,0 +1,329 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package image
+
+import (
+ "bytes"
+ "crypto/sha256"
+ "encoding/binary"
+ "encoding/json"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+
+ "mynewt.apache.org/newt/newt/target"
+ "mynewt.apache.org/newt/util"
+)
+
+type ImageVersion struct {
+ Major uint8
+ Minor uint8
+ Rev uint16
+ BuildNum uint32
+}
+
+type Image struct {
+ target *target.Target
+
+ sourceBin string
+ targetImg string
+ ManifestFile string
+ version ImageVersion
+
+ hash []byte
+}
+
+type ImageHdr struct {
+ Magic uint32
+ TlvSz uint32
+ HdrSz uint32
+ ImgSz uint32
+ Flags uint32
+ Vers ImageVersion
+ Pad uint32
+}
+
+type ImageTrailerTlv struct {
+ Type uint8
+ Pad uint8
+ Len uint16
+}
+
+const (
+ IMAGE_MAGIC = 0x96f3b83c /* Image header magic */
+)
+
+const (
+ IMAGE_HEADER_SIZE = 32
+)
+
+/*
+ * Image header flags.
+ */
+const (
+ IMAGE_F_PIC = 0x00000001
+ IMAGE_F_HAS_SHA256 = 0x00000002 /* Image contains hash TLV */
+)
+
+/*
+ * Image trailer TLV types.
+ */
+const (
+ IMAGE_TLV_SHA256 = 1
+)
+
+/*
+ * Data that's going to go to build manifest file
+ */
+type ImageManifest struct {
+ Date string `json:"build_time"`
+ Version string `json:"build_version"`
+ Hash string `json:"id"`
+ Image string `json:"image"`
+ Pkgs []*ImageManifestPkg `json:"pkgs"`
+ TgtVars []string `json:"target"`
+}
+
+type ImageManifestPkg struct {
+ Name string `json:"name"`
+ Version string `json:"version,omitempty"`
+ Hash string `json:"hash"`
+}
+
+func NewImage(t *target.Target) (*Image, error) {
+ image := &Image{
+ target: t,
+ }
+
+ image.sourceBin = t.ElfPath() + ".bin"
+ image.targetImg = t.ImagePath()
+ return image, nil
+}
+
+func (image *Image) SetVersion(versStr string) error {
+ var err error
+ var major uint64
+ var minor uint64
+ var rev uint64
+ var buildNum uint64
+
+ components := strings.Split(versStr, ".")
+ major, err = strconv.ParseUint(components[0], 10, 8)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+ versStr))
+ }
+ if len(components) > 1 {
+ minor, err = strconv.ParseUint(components[1], 10, 8)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+ versStr))
+ }
+ }
+ if len(components) > 2 {
+ rev, err = strconv.ParseUint(components[2], 10, 16)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+ versStr))
+ }
+ }
+ if len(components) > 3 {
+ buildNum, err = strconv.ParseUint(components[3], 10, 32)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+ versStr))
+ }
+ }
+ image.version.Major = uint8(major)
+ image.version.Minor = uint8(minor)
+ image.version.Rev = uint16(rev)
+ image.version.BuildNum = uint32(buildNum)
+ log.Printf("[VERBOSE] Assigning version number %d.%d.%d.%d\n",
+ image.version.Major, image.version.Minor,
+ image.version.Rev, image.version.BuildNum)
+
+ buf := new(bytes.Buffer)
+ err = binary.Write(buf, binary.LittleEndian, image.version)
+ if err != nil {
+ fmt.Printf("Bombing out\n")
+ return nil
+ }
+
+ return nil
+}
+
+func (image *Image) Generate() error {
+ binFile, err := os.Open(image.sourceBin)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Can't open target binary %s: %s",
+ image.sourceBin, err.Error()))
+ }
+ defer binFile.Close()
+
+ binInfo, err := binFile.Stat()
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Can't stat target binary %s: %s",
+ image.sourceBin, err.Error()))
+ }
+
+ imgFile, err := os.OpenFile(image.targetImg,
+ os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Can't open target image %s: %s",
+ image.targetImg, err.Error()))
+ }
+ defer imgFile.Close()
+
+ /*
+ * Compute hash while updating the file.
+ */
+ hash := sha256.New()
+
+ /*
+ * First the header
+ */
+ hdr := &ImageHdr{
+ Magic: IMAGE_MAGIC,
+ TlvSz: 4 + 32,
+ HdrSz: IMAGE_HEADER_SIZE,
+ ImgSz: uint32(binInfo.Size()),
+ Flags: IMAGE_F_HAS_SHA256,
+ Vers: image.version,
+ Pad: 0,
+ }
+
+ err = binary.Write(imgFile, binary.LittleEndian, hdr)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to serialize image hdr: %s",
+ err.Error()))
+ }
+ err = binary.Write(hash, binary.LittleEndian, hdr)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
+ err.Error()))
+ }
+
+ /*
+ * Followed by data.
+ */
+ dataBuf := make([]byte, 1024)
+ for {
+ cnt, err := binFile.Read(dataBuf)
+ if err != nil && err != io.EOF {
+ return util.NewNewtError(fmt.Sprintf("Failed to read from %s: %s",
+ image.sourceBin, err.Error()))
+ }
+ if cnt == 0 {
+ break
+ }
+ _, err = imgFile.Write(dataBuf[0:cnt])
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to write to %s: %s",
+ image.targetImg, err.Error()))
+ }
+ _, err = hash.Write(dataBuf[0:cnt])
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
+ err.Error()))
+ }
+ }
+
+ image.hash = hash.Sum(nil)
+
+ /*
+ * Trailer with hash of the data
+ */
+ tlv := &ImageTrailerTlv{
+ Type: IMAGE_TLV_SHA256,
+ Pad: 0,
+ Len: uint16(len(image.hash)),
+ }
+ err = binary.Write(imgFile, binary.LittleEndian, tlv)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
+ "trailer: %s", err.Error()))
+ }
+ _, err = imgFile.Write(image.hash)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to append hash: %s",
+ err.Error()))
+ }
+
+ return nil
+}
+
+func (image *Image) CreateManifest() error {
+ versionStr := fmt.Sprintf("%d.%d.%d.%d",
+ image.version.Major, image.version.Minor,
+ image.version.Rev, image.version.BuildNum)
+ hashStr := fmt.Sprintf("%x", image.hash)
+ timeStr := time.Now().Format(time.RFC3339)
+
+ manifest := &ImageManifest{
+ Version: versionStr,
+ Hash: hashStr,
+ Image: filepath.Base(image.targetImg),
+ Date: timeStr,
+ }
+/*
+ for _, builtPkg := range BuiltPkgs {
+ imgPkg := &ImageManifestPkg{
+ Name: builtPkg.Name,
+ Version: builtPkg.Version,
+ Hash: builtPkg.Hash,
+ }
+ manifest.Pkgs = append(manifest.Pkgs, imgPkg)
+ }
+*/
+ vars := image.target.Vars
+ var keys []string
+ for k := range vars {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+ for _, k := range keys {
+ manifest.TgtVars = append(manifest.TgtVars, k+"="+vars[k])
+ }
+ file, err := os.Create(image.ManifestFile)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Cannot create manifest file %s: %s",
+ image.ManifestFile, err.Error()))
+ }
+ defer file.Close()
+
+ buffer, err := json.MarshalIndent(manifest, "", " ")
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Cannot encode manifest: %s",
+ err.Error()))
+ }
+ _, err = file.Write(buffer)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Cannot write manifest file: %s",
+ err.Error()))
+ }
+
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/newt.go
----------------------------------------------------------------------
diff --git a/newt/newt.go b/newt/newt.go
index 4cb8ad6..9b05f55 100644
--- a/newt/newt.go
+++ b/newt/newt.go
@@ -25,6 +25,7 @@ import (
"mynewt.apache.org/newt/newt/builder"
"mynewt.apache.org/newt/newt/cli"
+ "mynewt.apache.org/newt/newt/image"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/newt/target"
@@ -91,6 +92,7 @@ func main() {
pkg.AddCommands(cmd)
target.AddCommands(cmd)
builder.AddCommands(cmd)
+ image.AddCommands(cmd)
cmd.Execute()
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/target/cmds.go
----------------------------------------------------------------------
diff --git a/newt/target/cmds.go b/newt/target/cmds.go
index 00bdfae..9069574 100644
--- a/newt/target/cmds.go
+++ b/newt/target/cmds.go
@@ -208,31 +208,6 @@ func targetDelCmd(cmd *cobra.Command, args []string) {
"Target %s successfully removed\n", args[0])
}
-func createImageRunCmd(cmd *cobra.Command, args []string) {
- if len(args) < 2 {
- cli.NewtUsage(cmd, util.NewNewtError("Must specify target and version"))
- }
-
- targetName := args[0]
- t := GetTargets()[targetName]
- if t == nil {
- cli.NewtUsage(cmd, util.NewNewtError("Invalid target name"))
- }
-
- image, err := NewImage(t)
- if err != nil {
- fmt.Println(err)
- }
- err = image.SetVersion(args[1])
- if err != nil {
- cli.NewtUsage(cmd, err)
- }
- err = image.Generate()
- if err != nil {
- fmt.Println(err)
- }
-}
-
func AddCommands(cmd *cobra.Command) {
targetHelpText := ""
targetHelpEx := ""
@@ -307,20 +282,4 @@ func AddCommands(cmd *cobra.Command) {
}
targetCmd.AddCommand(delCmd)
-
- createImageHelpText := "Create image by adding image header to created "+
- "binary file for <target-name>. Version number in the header is set "+
- "to be <version>."
- createImageHelpEx := " newt create-image <target-name> <version>\n"
- createImageHelpEx += " newt create-image my_target1 1.2.0\n"
- createImageHelpEx += " newt create-image my_target1 1.2.0.3\n"
-
- createImageCmd := &cobra.Command{
- Use: "create-image",
- Short: "Add image header to target binary",
- Long: createImageHelpText,
- Example: createImageHelpEx,
- Run: createImageRunCmd,
- }
- cmd.AddCommand(createImageCmd)
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/target/image.go
----------------------------------------------------------------------
diff --git a/newt/target/image.go b/newt/target/image.go
deleted file mode 100644
index 1964e5a..0000000
--- a/newt/target/image.go
+++ /dev/null
@@ -1,328 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package target
-
-import (
- "bytes"
- "crypto/sha256"
- "encoding/binary"
- "encoding/json"
- "fmt"
- "io"
- "log"
- "os"
- "path/filepath"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "mynewt.apache.org/newt/util"
-)
-
-type ImageVersion struct {
- Major uint8
- Minor uint8
- Rev uint16
- BuildNum uint32
-}
-
-type Image struct {
- target *Target
-
- sourceBin string
- targetImg string
- ManifestFile string
- version ImageVersion
-
- hash []byte
-}
-
-type ImageHdr struct {
- Magic uint32
- TlvSz uint32
- HdrSz uint32
- ImgSz uint32
- Flags uint32
- Vers ImageVersion
- Pad uint32
-}
-
-type ImageTrailerTlv struct {
- Type uint8
- Pad uint8
- Len uint16
-}
-
-const (
- IMAGE_MAGIC = 0x96f3b83c /* Image header magic */
-)
-
-const (
- IMAGE_HEADER_SIZE = 32
-)
-
-/*
- * Image header flags.
- */
-const (
- IMAGE_F_PIC = 0x00000001
- IMAGE_F_HAS_SHA256 = 0x00000002 /* Image contains hash TLV */
-)
-
-/*
- * Image trailer TLV types.
- */
-const (
- IMAGE_TLV_SHA256 = 1
-)
-
-/*
- * Data that's going to go to build manifest file
- */
-type ImageManifest struct {
- Date string `json:"build_time"`
- Version string `json:"build_version"`
- Hash string `json:"id"`
- Image string `json:"image"`
- Pkgs []*ImageManifestPkg `json:"pkgs"`
- TgtVars []string `json:"target"`
-}
-
-type ImageManifestPkg struct {
- Name string `json:"name"`
- Version string `json:"version,omitempty"`
- Hash string `json:"hash"`
-}
-
-func NewImage(t *Target) (*Image, error) {
- image := &Image{
- target: t,
- }
-
- image.sourceBin = t.ElfPath() + ".bin"
- image.targetImg = t.ImagePath()
- return image, nil
-}
-
-func (image *Image) SetVersion(versStr string) error {
- var err error
- var major uint64
- var minor uint64
- var rev uint64
- var buildNum uint64
-
- components := strings.Split(versStr, ".")
- major, err = strconv.ParseUint(components[0], 10, 8)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
- versStr))
- }
- if len(components) > 1 {
- minor, err = strconv.ParseUint(components[1], 10, 8)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
- versStr))
- }
- }
- if len(components) > 2 {
- rev, err = strconv.ParseUint(components[2], 10, 16)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
- versStr))
- }
- }
- if len(components) > 3 {
- buildNum, err = strconv.ParseUint(components[3], 10, 32)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
- versStr))
- }
- }
- image.version.Major = uint8(major)
- image.version.Minor = uint8(minor)
- image.version.Rev = uint16(rev)
- image.version.BuildNum = uint32(buildNum)
- log.Printf("[VERBOSE] Assigning version number %d.%d.%d.%d\n",
- image.version.Major, image.version.Minor,
- image.version.Rev, image.version.BuildNum)
-
- buf := new(bytes.Buffer)
- err = binary.Write(buf, binary.LittleEndian, image.version)
- if err != nil {
- fmt.Printf("Bombing out\n")
- return nil
- }
-
- return nil
-}
-
-func (image *Image) Generate() error {
- binFile, err := os.Open(image.sourceBin)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Can't open target binary %s: %s",
- image.sourceBin, err.Error()))
- }
- defer binFile.Close()
-
- binInfo, err := binFile.Stat()
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Can't stat target binary %s: %s",
- image.sourceBin, err.Error()))
- }
-
- imgFile, err := os.OpenFile(image.targetImg,
- os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Can't open target image %s: %s",
- image.targetImg, err.Error()))
- }
- defer imgFile.Close()
-
- /*
- * Compute hash while updating the file.
- */
- hash := sha256.New()
-
- /*
- * First the header
- */
- hdr := &ImageHdr{
- Magic: IMAGE_MAGIC,
- TlvSz: 4 + 32,
- HdrSz: IMAGE_HEADER_SIZE,
- ImgSz: uint32(binInfo.Size()),
- Flags: IMAGE_F_HAS_SHA256,
- Vers: image.version,
- Pad: 0,
- }
-
- err = binary.Write(imgFile, binary.LittleEndian, hdr)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to serialize image hdr: %s",
- err.Error()))
- }
- err = binary.Write(hash, binary.LittleEndian, hdr)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
- err.Error()))
- }
-
- /*
- * Followed by data.
- */
- dataBuf := make([]byte, 1024)
- for {
- cnt, err := binFile.Read(dataBuf)
- if err != nil && err != io.EOF {
- return util.NewNewtError(fmt.Sprintf("Failed to read from %s: %s",
- image.sourceBin, err.Error()))
- }
- if cnt == 0 {
- break
- }
- _, err = imgFile.Write(dataBuf[0:cnt])
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to write to %s: %s",
- image.targetImg, err.Error()))
- }
- _, err = hash.Write(dataBuf[0:cnt])
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
- err.Error()))
- }
- }
-
- image.hash = hash.Sum(nil)
-
- /*
- * Trailer with hash of the data
- */
- tlv := &ImageTrailerTlv{
- Type: IMAGE_TLV_SHA256,
- Pad: 0,
- Len: uint16(len(image.hash)),
- }
- err = binary.Write(imgFile, binary.LittleEndian, tlv)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
- "trailer: %s", err.Error()))
- }
- _, err = imgFile.Write(image.hash)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to append hash: %s",
- err.Error()))
- }
-
- return nil
-}
-
-func (image *Image) CreateManifest() error {
- versionStr := fmt.Sprintf("%d.%d.%d.%d",
- image.version.Major, image.version.Minor,
- image.version.Rev, image.version.BuildNum)
- hashStr := fmt.Sprintf("%x", image.hash)
- timeStr := time.Now().Format(time.RFC3339)
-
- manifest := &ImageManifest{
- Version: versionStr,
- Hash: hashStr,
- Image: filepath.Base(image.targetImg),
- Date: timeStr,
- }
-/*
- for _, builtPkg := range BuiltPkgs {
- imgPkg := &ImageManifestPkg{
- Name: builtPkg.Name,
- Version: builtPkg.Version,
- Hash: builtPkg.Hash,
- }
- manifest.Pkgs = append(manifest.Pkgs, imgPkg)
- }
-*/
- vars := image.target.Vars
- var keys []string
- for k := range vars {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- for _, k := range keys {
- manifest.TgtVars = append(manifest.TgtVars, k+"="+vars[k])
- }
- file, err := os.Create(image.ManifestFile)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Cannot create manifest file %s: %s",
- image.ManifestFile, err.Error()))
- }
- defer file.Close()
-
- buffer, err := json.MarshalIndent(manifest, "", " ")
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Cannot encode manifest: %s",
- err.Error()))
- }
- _, err = file.Write(buffer)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Cannot write manifest file: %s",
- err.Error()))
- }
-
- return nil
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/32463b45/newt/target/target.go
----------------------------------------------------------------------
diff --git a/newt/target/target.go b/newt/target/target.go
index c48affe..32727f5 100644
--- a/newt/target/target.go
+++ b/newt/target/target.go
@@ -132,24 +132,22 @@ func (target *Target) Bsp() *pkg.LocalPackage {
return mypkg
}
-func (target *Target) ElfPath() string {
+func (target *Target) BinBasePath() string {
appPkg := target.App()
if appPkg == nil {
return ""
}
return appPkg.BasePath() + "/bin/" + target.Package().Name() + "/" +
- appPkg.Name() + ".elf"
+ appPkg.Name()
}
-func (target *Target) ImagePath() string {
- appPkg := target.App()
- if appPkg == nil {
- return ""
- }
+func (target *Target) ElfPath() string {
+ return target.BinBasePath() + ".elf"
+}
- return appPkg.BasePath() + "/bin/" + target.Package().Name() + "/" +
- appPkg.Name() + ".img"
+func (target *Target) ImagePath() string {
+ return target.BinBasePath() + ".img"
}
// Save the target's configuration elements