summaryrefslogtreecommitdiffstats
path: root/common/bbu.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2016-03-17 16:15:11 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2016-04-06 15:41:15 +0200
commit0e4f92570eeea78e374af2b8bc9297e7d1c751d9 (patch)
tree82ffda6c8bd4430ca2de1779a006de65435063ea /common/bbu.c
parent7f73e64e8b369e655a322cd2877b5a1222f5b245 (diff)
downloadbarebox-0e4f92570eeea78e374af2b8bc9297e7d1c751d9.tar.gz
barebox-0e4f92570eeea78e374af2b8bc9297e7d1c751d9.tar.xz
bbu: print and evaluate image Metadata
With imd we can store metadata in barebox images. Let's use this information to further verify that the image that is to be flashed is the correct one. This patch extracts the device tree compatible from the image and compares it with the one from the currently running barebox. If it doesn't match the update is aborted with a warning. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/bbu.c')
-rw-r--r--common/bbu.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/common/bbu.c b/common/bbu.c
index 68812a733d..5fbef6a668 100644
--- a/common/bbu.c
+++ b/common/bbu.c
@@ -26,6 +26,7 @@
#include <fcntl.h>
#include <malloc.h>
#include <linux/stat.h>
+#include <image-metadata.h>
static LIST_HEAD(bbu_image_handlers);
@@ -125,6 +126,79 @@ bool barebox_update_handler_exists(struct bbu_data *data)
return !bbu_find_handler(data->handler_name);
}
+static int bbu_check_of_compat(struct bbu_data *data)
+{
+ struct device_node *root_node;
+ const char *machine, *str;
+ int ret;
+ struct imd_header *of_compat;
+
+ if (!IS_ENABLED(CONFIG_OFDEVICE) || !IS_ENABLED(CONFIG_IMD))
+ return 0;
+
+ of_compat = imd_find_type(data->imd_data, IMD_TYPE_OF_COMPATIBLE);
+ if (!of_compat)
+ return 0;
+
+ root_node = of_get_root_node();
+ if (!root_node)
+ return 0;
+
+ str = imd_string_data(of_compat, 0);
+
+ if (of_machine_is_compatible(str)) {
+ pr_info("Devicetree compatible \"%s\" matches current machine\n", str);
+ return 0;
+ }
+
+ ret = of_property_read_string(root_node, "compatible", &machine);
+ if (ret)
+ return 0;
+
+ if (!bbu_force(data, "machine is incompatible with \"%s\", have \"%s\"\n", str, machine))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int bbu_check_metadata(struct bbu_data *data)
+{
+ struct imd_header *imd;
+ int ret;
+ char *str;
+
+ if (!IS_ENABLED(CONFIG_IMD))
+ return 0;
+
+ if (!data->image)
+ return 0;
+
+ data->imd_data = imd_get(data->image, data->len);
+ if (IS_ERR(data->imd_data)) {
+ data->imd_data = NULL;
+ return 0;
+ }
+
+ printf("Image Metadata:\n");
+ imd_for_each(data->imd_data, imd) {
+ uint32_t type = imd_read_type(imd);
+
+ if (!imd_is_string(type))
+ continue;
+
+ str = imd_concat_strings(imd);
+
+ printf(" %s: %s\n", imd_type_to_name(type), str);
+ free(str);
+ }
+
+ ret = bbu_check_of_compat(data);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
/*
* do a barebox update with data from *data
*/
@@ -147,6 +221,10 @@ int barebox_update(struct bbu_data *data)
if (!data->devicefile)
data->devicefile = handler->devicefile;
+ ret = bbu_check_metadata(data);
+ if (ret)
+ return ret;
+
ret = handler->handler(handler, data);
if (ret == -EINTR)
printf("update aborted\n");