summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile4
-rw-r--r--tools/aisimage.c1
-rw-r--r--tools/buildman/control.py9
-rw-r--r--tools/fit_image.c98
-rw-r--r--tools/image-host.c208
-rw-r--r--tools/mkimage.h2
-rw-r--r--tools/patman/gitutil.py21
-rwxr-xr-xtools/patman/patman.py2
-rw-r--r--tools/patman/series.py4
9 files changed, 300 insertions, 49 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 93f4a84..4630f03 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -78,6 +78,7 @@ BIN_FILES-$(CONFIG_KIRKWOOD) += kwboot$(SFX)
# Source files which exist outside the tools directory
EXT_OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += common/env_embedded.o
EXT_OBJ_FILES-y += common/image.o
+EXT_OBJ_FILES-$(CONFIG_FIT) += common/image-fit.o
EXT_OBJ_FILES-y += lib/crc32.o
EXT_OBJ_FILES-y += lib/md5.o
EXT_OBJ_FILES-y += lib/sha1.o
@@ -95,6 +96,7 @@ NOPED_OBJ_FILES-y += aisimage.o
NOPED_OBJ_FILES-y += kwbimage.o
NOPED_OBJ_FILES-y += pblimage.o
NOPED_OBJ_FILES-y += imximage.o
+NOPED_OBJ_FILES-y += image-host.o
NOPED_OBJ_FILES-y += omapimage.o
NOPED_OBJ_FILES-y += mkenvimage.o
NOPED_OBJ_FILES-y += mkimage.o
@@ -202,7 +204,9 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \
$(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
+ $(obj)image-fit.o \
$(obj)image.o \
+ $(obj)image-host.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
$(obj)pblimage.o \
diff --git a/tools/aisimage.c b/tools/aisimage.c
index c645708..659df8c 100644
--- a/tools/aisimage.c
+++ b/tools/aisimage.c
@@ -32,7 +32,6 @@
#define WORD_ALIGN0 4
#define WORD_ALIGN(len) (((len)+WORD_ALIGN0-1) & ~(WORD_ALIGN0-1))
#define MAX_CMD_BUFFER 4096
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static uint32_t ais_img_size;
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index 8d7b9b5..4319ce7 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -111,6 +111,10 @@ def DoBuildman(options, args):
print col.Color(col.RED, str)
sys.exit(1)
count = gitutil.CountCommitsInBranch(options.git_dir, options.branch)
+ if count is None:
+ str = "Branch '%s' not found or has no upstream" % options.branch
+ print col.Color(col.RED, str)
+ sys.exit(1)
count += 1 # Build upstream commit also
if not count:
@@ -137,6 +141,11 @@ def DoBuildman(options, args):
upstream_commit = gitutil.GetUpstream(options.git_dir, options.branch)
series = patchstream.GetMetaDataForList(upstream_commit, options.git_dir,
1)
+ # Conflicting tags are not a problem for buildman, since it does not use
+ # them. For example, Series-version is not useful for buildman. On the
+ # other hand conflicting tags will cause an error. So allow later tags
+ # to overwrite earlier ones.
+ series.allow_overwrite = True
series = patchstream.GetMetaDataForList(range_expr, options.git_dir, None,
series)
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 76bbba1..cc123dd 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -47,6 +47,48 @@ static int fit_check_image_types (uint8_t type)
return EXIT_FAILURE;
}
+int mmap_fdt(struct mkimage_params *params, const char *fname, void **blobp,
+ struct stat *sbuf)
+{
+ void *ptr;
+ int fd;
+
+ /* Load FIT blob into memory (we need to write hashes/signatures) */
+ fd = open(fname, O_RDWR | O_BINARY);
+
+ if (fd < 0) {
+ fprintf(stderr, "%s: Can't open %s: %s\n",
+ params->cmdname, fname, strerror(errno));
+ unlink(fname);
+ return -1;
+ }
+
+ if (fstat(fd, sbuf) < 0) {
+ fprintf(stderr, "%s: Can't stat %s: %s\n",
+ params->cmdname, fname, strerror(errno));
+ unlink(fname);
+ return -1;
+ }
+
+ ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ fprintf(stderr, "%s: Can't read %s: %s\n",
+ params->cmdname, fname, strerror(errno));
+ unlink(fname);
+ return -1;
+ }
+
+ /* check if ptr has a valid blob */
+ if (fdt_check_header(ptr)) {
+ fprintf(stderr, "%s: Invalid FIT blob\n", params->cmdname);
+ unlink(fname);
+ return -1;
+ }
+
+ *blobp = ptr;
+ return fd;
+}
+
/**
* fit_handle_file - main FIT file processing function
*
@@ -65,7 +107,7 @@ static int fit_handle_file (struct mkimage_params *params)
char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
int tfd;
struct stat sbuf;
- unsigned char *ptr;
+ void *ptr;
/* Flattened Image Tree (FIT) format handling */
debug ("FIT format handling\n");
@@ -87,57 +129,25 @@ static int fit_handle_file (struct mkimage_params *params)
if (system (cmd) == -1) {
fprintf (stderr, "%s: system(%s) failed: %s\n",
params->cmdname, cmd, strerror(errno));
- unlink (tmpfile);
- return (EXIT_FAILURE);
- }
-
- /* load FIT blob into memory */
- tfd = open (tmpfile, O_RDWR|O_BINARY);
-
- if (tfd < 0) {
- fprintf (stderr, "%s: Can't open %s: %s\n",
- params->cmdname, tmpfile, strerror(errno));
- unlink (tmpfile);
- return (EXIT_FAILURE);
- }
-
- if (fstat (tfd, &sbuf) < 0) {
- fprintf (stderr, "%s: Can't stat %s: %s\n",
- params->cmdname, tmpfile, strerror(errno));
- unlink (tmpfile);
- return (EXIT_FAILURE);
- }
-
- ptr = mmap (0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED,
- tfd, 0);
- if (ptr == MAP_FAILED) {
- fprintf (stderr, "%s: Can't read %s: %s\n",
- params->cmdname, tmpfile, strerror(errno));
- unlink (tmpfile);
- return (EXIT_FAILURE);
+ goto err_system;
}
- /* check if ptr has a valid blob */
- if (fdt_check_header (ptr)) {
- fprintf (stderr, "%s: Invalid FIT blob\n", params->cmdname);
- unlink (tmpfile);
- return (EXIT_FAILURE);
- }
+ tfd = mmap_fdt(params, tmpfile, &ptr, &sbuf);
+ if (tfd < 0)
+ goto err_mmap;
/* set hashes for images in the blob */
- if (fit_set_hashes (ptr)) {
+ if (fit_add_verification_data(ptr)) {
fprintf (stderr, "%s Can't add hashes to FIT blob",
params->cmdname);
- unlink (tmpfile);
- return (EXIT_FAILURE);
+ goto err_add_hashes;
}
/* add a timestamp at offset 0 i.e., root */
if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) {
fprintf (stderr, "%s: Can't add image timestamp\n",
params->cmdname);
- unlink (tmpfile);
- return (EXIT_FAILURE);
+ goto err_add_timestamp;
}
debug ("Added timestamp successfully\n");
@@ -153,6 +163,14 @@ static int fit_handle_file (struct mkimage_params *params)
return (EXIT_FAILURE);
}
return (EXIT_SUCCESS);
+
+err_add_timestamp:
+err_add_hashes:
+ munmap(ptr, sbuf.st_size);
+err_mmap:
+err_system:
+ unlink(tmpfile);
+ return -1;
}
static int fit_check_params (struct mkimage_params *params)
diff --git a/tools/image-host.c b/tools/image-host.c
new file mode 100644
index 0000000..d944d0f
--- /dev/null
+++ b/tools/image-host.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "mkimage.h"
+#include <bootstage.h>
+#include <image.h>
+#include <sha1.h>
+#include <time.h>
+#include <u-boot/crc.h>
+#include <u-boot/md5.h>
+
+/**
+ * fit_set_hash_value - set hash value in requested has node
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @value: hash value to be set
+ * @value_len: hash value length
+ *
+ * fit_set_hash_value() attempts to set hash value in a node at offset
+ * given and returns operation status to the caller.
+ *
+ * returns
+ * 0, on success
+ * -1, on failure
+ */
+static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
+ int value_len)
+{
+ int ret;
+
+ ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
+ if (ret) {
+ printf("Can't set hash '%s' property for '%s' node(%s)\n",
+ FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
+ fdt_strerror(ret));
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * fit_image_process_hash - Process a single subnode of the images/ node
+ *
+ * Check each subnode and process accordingly. For hash nodes we generate
+ * a hash of the supplised data and store it in the node.
+ *
+ * @fit: pointer to the FIT format image header
+ * @image_name: name of image being processes (used to display errors)
+ * @noffset: subnode offset
+ * @data: data to process
+ * @size: size of data in bytes
+ * @return 0 if ok, -1 on error
+ */
+static int fit_image_process_hash(void *fit, const char *image_name,
+ int noffset, const void *data, size_t size)
+{
+ uint8_t value[FIT_MAX_HASH_LEN];
+ const char *node_name;
+ int value_len;
+ char *algo;
+
+ node_name = fit_get_name(fit, noffset, NULL);
+
+ if (fit_image_hash_get_algo(fit, noffset, &algo)) {
+ printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
+ node_name, image_name);
+ return -1;
+ }
+
+ if (calculate_hash(data, size, algo, value, &value_len)) {
+ printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
+ algo, node_name, image_name);
+ return -1;
+ }
+
+ if (fit_set_hash_value(fit, noffset, value, value_len)) {
+ printf("Can't set hash value for '%s' hash node in '%s' image node\n",
+ node_name, image_name);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * fit_image_add_verification_data() - calculate/set hash data for image node
+ *
+ * This adds hash values for a component image node.
+ *
+ * All existing hash subnodes are checked, if algorithm property is set to
+ * one of the supported hash algorithms, hash value is computed and
+ * corresponding hash node property is set, for example:
+ *
+ * Input component image node structure:
+ *
+ * o image@1 (at image_noffset)
+ * | - data = [binary data]
+ * o hash@1
+ * |- algo = "sha1"
+ *
+ * Output component image node structure:
+ *
+ * o image@1 (at image_noffset)
+ * | - data = [binary data]
+ * o hash@1
+ * |- algo = "sha1"
+ * |- value = sha1(data)
+ *
+ * For signature details, please see doc/uImage.FIT/signature.txt
+ *
+ * @fit: Pointer to the FIT format image header
+ * @image_noffset: Requested component image node
+ * @return: 0 on success, <0 on failure
+ */
+int fit_image_add_verification_data(void *fit, int image_noffset)
+{
+ const char *image_name;
+ const void *data;
+ size_t size;
+ int noffset;
+
+ /* Get image data and data length */
+ if (fit_image_get_data(fit, image_noffset, &data, &size)) {
+ printf("Can't get image data/size\n");
+ return -1;
+ }
+
+ image_name = fit_get_name(fit, image_noffset, NULL);
+
+ /* Process all hash subnodes of the component image node */
+ for (noffset = fdt_first_subnode(fit, image_noffset);
+ noffset >= 0;
+ noffset = fdt_next_subnode(fit, noffset)) {
+ const char *node_name;
+ int ret = 0;
+
+ /*
+ * Check subnode name, must be equal to "hash" or "signature".
+ * Multiple hash nodes require unique unit node
+ * names, e.g. hash@1, hash@2, signature@1, etc.
+ */
+ node_name = fit_get_name(fit, noffset, NULL);
+ if (!strncmp(node_name, FIT_HASH_NODENAME,
+ strlen(FIT_HASH_NODENAME))) {
+ ret = fit_image_process_hash(fit, image_name, noffset,
+ data, size);
+ }
+ if (ret)
+ return -1;
+ }
+
+ return 0;
+}
+
+int fit_add_verification_data(void *fit)
+{
+ int images_noffset;
+ int noffset;
+ int ret;
+
+ /* Find images parent node offset */
+ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+ if (images_noffset < 0) {
+ printf("Can't find images parent node '%s' (%s)\n",
+ FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+ return images_noffset;
+ }
+
+ /* Process its subnodes, print out component images details */
+ for (noffset = fdt_first_subnode(fit, images_noffset);
+ noffset >= 0;
+ noffset = fdt_next_subnode(fit, noffset)) {
+ /*
+ * Direct child node of the images parent node,
+ * i.e. component image node.
+ */
+ ret = fit_image_add_verification_data(fit, noffset);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/tools/mkimage.h b/tools/mkimage.h
index ea45f5c..e07a615 100644
--- a/tools/mkimage.h
+++ b/tools/mkimage.h
@@ -42,6 +42,8 @@
#define debug(fmt,args...)
#endif /* MKIMAGE_DEBUG */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
#define MKIMAGE_TMPFILE_SUFFIX ".tmp"
#define MKIMAGE_MAX_TMPFILE_LEN 256
#define MKIMAGE_DEFAULT_DTC_OPTIONS "-I dts -O dtb -p 500"
diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py
index e31da15..b7f6739 100644
--- a/tools/patman/gitutil.py
+++ b/tools/patman/gitutil.py
@@ -56,10 +56,14 @@ def GetUpstream(git_dir, branch):
Returns:
Name of upstream branch (e.g. 'upstream/master') or None if none
"""
- remote = command.OutputOneLine('git', '--git-dir', git_dir, 'config',
- 'branch.%s.remote' % branch)
- merge = command.OutputOneLine('git', '--git-dir', git_dir, 'config',
- 'branch.%s.merge' % branch)
+ try:
+ remote = command.OutputOneLine('git', '--git-dir', git_dir, 'config',
+ 'branch.%s.remote' % branch)
+ merge = command.OutputOneLine('git', '--git-dir', git_dir, 'config',
+ 'branch.%s.merge' % branch)
+ except:
+ return None
+
if remote == '.':
return merge
elif remote and merge:
@@ -78,9 +82,11 @@ def GetRangeInBranch(git_dir, branch, include_upstream=False):
branch: Name of branch
Return:
Expression in the form 'upstream..branch' which can be used to
- access the commits.
+ access the commits. If the branch does not exist, returns None.
"""
upstream = GetUpstream(git_dir, branch)
+ if not upstream:
+ return None
return '%s%s..%s' % (upstream, '~' if include_upstream else '', branch)
def CountCommitsInBranch(git_dir, branch, include_upstream=False):
@@ -90,9 +96,12 @@ def CountCommitsInBranch(git_dir, branch, include_upstream=False):
git_dir: Directory containing git repo
branch: Name of branch
Return:
- Number of patches that exist on top of the branch
+ Number of patches that exist on top of the branch, or None if the
+ branch does not exist.
"""
range_expr = GetRangeInBranch(git_dir, branch, include_upstream)
+ if not range_expr:
+ return None
pipe = [['git', '--git-dir', git_dir, 'log', '--oneline', '--no-decorate',
range_expr],
['wc', '-l']]
diff --git a/tools/patman/patman.py b/tools/patman/patman.py
index a8061a9..7a317c5 100755
--- a/tools/patman/patman.py
+++ b/tools/patman/patman.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
#
# Copyright (c) 2011 The Chromium OS Authors.
#
diff --git a/tools/patman/series.py b/tools/patman/series.py
index 783b3dd..85ed316 100644
--- a/tools/patman/series.py
+++ b/tools/patman/series.py
@@ -40,6 +40,7 @@ class Series(dict):
notes: List of lines in the notes
changes: (dict) List of changes for each version, The key is
the integer version number
+ allow_overwrite: Allow tags to overwrite an existing tag
"""
def __init__(self):
self.cc = []
@@ -49,6 +50,7 @@ class Series(dict):
self.cover = None
self.notes = []
self.changes = {}
+ self.allow_overwrite = False
# Written in MakeCcFile()
# key: name of patch file
@@ -72,7 +74,7 @@ class Series(dict):
"""
# If we already have it, then add to our list
name = name.replace('-', '_')
- if name in self:
+ if name in self and not self.allow_overwrite:
values = value.split(',')
values = [str.strip() for str in values]
if type(self[name]) != type([]):