summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-07-28 07:22:40 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-08-07 06:13:52 +0200
commit97e81f2d78f30fb4936f0f6fe52b317d8dbc9881 (patch)
treeb260ea65a17293c2e826ce03930052106bcfc618 /scripts
parent7b0d00c46566f1abe261c79efa63baa88ae55e47 (diff)
downloadbarebox-97e81f2d78f30fb4936f0f6fe52b317d8dbc9881.tar.gz
barebox-97e81f2d78f30fb4936f0f6fe52b317d8dbc9881.tar.xz
Add support for metadata in barebox images
It's often useful to get some information about a barebox image before starting or flashing it. This patch introduces barebox Image MetaData (IMD). When enabled a barebox image will contain a list of tags containing the desired information. We have tags for: - the barebox release (2014.07.0-00160-g035de50-dirty) - the build timestamp (#741 Mon Jul 28 15:08:54 CEST 2014) - the board model the image is intended for - the device tree toplevel compatible property Also there is an additional generic key-value store which stores parameters for which no dedicated tag exists. In this patch it is used for the memory size an image supports. Since there is no fixed offset in a barebox image which can be used for storing the information, the metadata is stored somewhere in the image and found by iterating over the image. This works for most image types, but obviously not for SoC images which are encoded or encrypted in some way. There is a 'imd' tool compiled from the same sources for barebox, for the compile host and for the target, so the metadata information is available whereever needed. For device tree boards the model and of_compatible tags are automatically generated. Example output of the imd tool for a Phytec phyFLEX image: build: #889 Wed Jul 30 16:08:54 CEST 2014 release: 2014.07.0-00167-g6b2070d-dirty parameter: memsize=1024 of_compatible: phytec,imx6x-pbab01 phytec,imx6dl-pfla02 fsl,imx6dl model: Phytec phyFLEX-i.MX6 Duallite Carrier-Board Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.lib2
-rw-r--r--scripts/bareboximd.c161
-rwxr-xr-xscripts/gen-dtb-s42
4 files changed, 206 insertions, 1 deletions
diff --git a/scripts/Makefile b/scripts/Makefile
index 9c77680a17..2050ec497d 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -10,6 +10,7 @@ hostprogs-y += fix_size
hostprogs-y += bareboxenv
hostprogs-y += bareboxcrc32
hostprogs-y += kernel-install
+hostprogs-$(CONFIG_IMD) += bareboximd
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
hostprogs-$(CONFIG_ARCH_MVEBU) += kwbimage kwboot
hostprogs-$(CONFIG_ARCH_NETX) += gen_netx_image
@@ -29,6 +30,7 @@ subdir-$(CONFIG_ARCH_TEGRA) += tegra
targetprogs-$(CONFIG_BAREBOXENV_TARGET) += bareboxenv-target
targetprogs-$(CONFIG_KERNEL_INSTALL_TARGET) += kernel-install-target
targetprogs-$(CONFIG_BAREBOXCRC32_TARGET) += bareboxcrc32-target
+targetprogs-$(CONFIG_IMD_TARGET) += bareboximd-target
# Let clean descend into subdirs
subdir- += basic kconfig setupmbr
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index b546c42bd9..7d97d573ab 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -210,7 +210,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
# Generate an assembly file to wrap the output of the device tree compiler
quiet_cmd_dt_S_dtb = DTB $@
-cmd_dt_S_dtb = $(srctree)/scripts/gen-dtb-s $(subst -,_,$(*F)) $< > $@
+cmd_dt_S_dtb = $(srctree)/scripts/gen-dtb-s $(subst -,_,$(*F)) $< $(CONFIG_IMD) > $@
$(obj)/%.dtb.S: $(obj)/%.dtb $(srctree)/scripts/gen-dtb-s FORCE
$(call if_changed,dt_S_dtb)
diff --git a/scripts/bareboximd.c b/scripts/bareboximd.c
new file mode 100644
index 0000000000..a3622af821
--- /dev/null
+++ b/scripts/bareboximd.c
@@ -0,0 +1,161 @@
+/*
+ * (C) Copyright 2014 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ *
+ */
+
+#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <asm-generic/errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#include "../include/image-metadata.h"
+
+static void debug(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!imd_command_verbose)
+ return;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+int imd_command_setenv(const char *variable_name, const char *value)
+{
+ fprintf(stderr, "-s option ignored\n");
+
+ return -EINVAL;
+}
+
+static int read_file_2(const char *filename, size_t *size, void **outbuf, loff_t max_size)
+{
+ off_t fsize;
+ ssize_t rsize;
+ int ret, fd;
+ void *buf;
+
+ *size = 0;
+ *outbuf = NULL;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno));
+ return -errno;
+ }
+
+ fsize = lseek(fd, 0, SEEK_END);
+ if (fsize == -1) {
+ fprintf(stderr, "Cannot get size %s: %s\n", filename, strerror(errno));
+ ret = -errno;
+ goto close;
+ }
+
+ if (fsize < max_size)
+ max_size = fsize;
+
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ fprintf(stderr, "Cannot seek to start %s: %s\n", filename, strerror(errno));
+ ret = -errno;
+ goto close;
+ }
+
+ buf = malloc(max_size);
+ if (!buf) {
+ fprintf(stderr, "Cannot allocate memory\n");
+ ret = -ENOMEM;
+ goto close;
+ }
+
+ *outbuf = buf;
+ while (*size < max_size) {
+ rsize = read(fd, buf, max_size-*size);
+ if (rsize == 0) {
+ ret = -EIO;
+ goto free;
+ } else if (rsize < 0) {
+ if (errno == EAGAIN)
+ continue;
+ else {
+ ret = -errno;
+ goto free;
+ }
+ } /* ret > 0 */
+ buf += rsize;
+ *size += rsize;
+ }
+
+ ret = 0;
+ goto close;
+free:
+ *outbuf = NULL;
+ free(buf);
+close:
+ close(fd);
+ return ret;
+}
+
+static unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
+{
+ return strtoul(cp, endp, base);
+}
+
+#include "../common/imd.c"
+
+static void usage(const char *prgname)
+{
+ printf(
+"Extract metadata from a barebox image\n"
+"\n"
+"Usage: %s [OPTIONS] FILE\n"
+"Options:\n"
+"-t <type> only show information of <type>\n"
+"-n <no> for tags with multiple strings only show string <no>\n"
+"\n"
+"Without options all information available is printed. Valid types are:\n"
+"release, build, model, of_compatible\n",
+ prgname);
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ ret = imd_command(argc, argv);
+ if (ret == -ENOSYS) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (ret)
+ fprintf(stderr, "%s\n", strerror(-ret));
+
+ return ret ? 1 : 0;
+}
diff --git a/scripts/gen-dtb-s b/scripts/gen-dtb-s
index 44136b0369..434612f362 100755
--- a/scripts/gen-dtb-s
+++ b/scripts/gen-dtb-s
@@ -2,8 +2,46 @@
name=$1
dtb=$2
+imd=$3
echo "#include <asm-generic/barebox.lds.h>"
+
+le32() {
+ printf ".byte 0x%02x, 0x%02x, 0x%02x, 0x%02x\n" \
+ $(($1 & 0xff)) \
+ $((($1 >> 8) & 0xff)) \
+ $((($1 >> 16) & 0xff)) \
+ $((($1 >> 24) & 0xff))
+}
+
+FDTGET=scripts/dtc/fdtget
+
+if [ "$imd" = "y" ]; then
+ echo ".section .barebox_imd_0.${name},\"a\""
+ echo ".global __imd_${name}_start"
+ echo "__imd_${name}_start:"
+
+ compat=$($FDTGET -d notfound -t bi "$dtb" / compatible | sed "s^ ^,^g")
+ if [ "$compat" != "notfound" ]; then
+
+ compatlen=$($FDTGET -t s "$dtb" / compatible | wc -c)
+ le32 0x640c8005
+ le32 $compatlen
+ echo ".byte " $compat
+ echo ".balign 4"
+ fi
+
+ model=$($FDTGET -d notfound -t bi "$dtb" / model | sed "s^ ^,^g")
+
+ if [ "$model" != "notfound" ]; then
+ modellen=$($FDTGET -t s "$dtb" / model | wc -c)
+ le32 0x640c8004
+ le32 $compatlen
+ echo ".byte " $model
+ echo ".balign 4"
+ fi
+fi
+
echo ".section .dtb.rodata.${name},\"a\""
echo ".balign STRUCT_ALIGNMENT"
echo ".global __dtb_${name}_start"
@@ -12,3 +50,7 @@ echo ".incbin \"$dtb\""
echo "__dtb_${name}_end:"
echo ".global __dtb_${name}_end"
echo ".balign STRUCT_ALIGNMENT"
+
+if [ "$imd" = "y" ]; then
+ echo ".word __imd_${name}_start"
+fi