summaryrefslogtreecommitdiffstats
path: root/include/image-metadata.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/image-metadata.h')
-rw-r--r--include/image-metadata.h117
1 files changed, 117 insertions, 0 deletions
diff --git a/include/image-metadata.h b/include/image-metadata.h
new file mode 100644
index 0000000000..34dae5ce34
--- /dev/null
+++ b/include/image-metadata.h
@@ -0,0 +1,117 @@
+#ifndef __INCLUDE_IMAGE_METADTA_H
+#define __INCLUDE_IMAGE_METADTA_H
+
+/*
+ * barebox Image MetaData (IMD)
+ *
+ * IMD is a mechanism to store metadata in barebox images. With IMD
+ * it's possible to extract the release, the build timestamp and the
+ * board type from a barebox image.
+ *
+ * Since there is no fixed place in the image suitable for all SoC image
+ * types the metadata can be stored anywhere in the image and is found
+ * by iterating over the image. The metadata starts with a start header
+ * and ends with an end header. All tags in between carry the payload.
+ *
+ * Make sure source files containing IMD data are compiled with lwl-y so
+ * that the tags end up in the PBL if one exists and in the regular image
+ * without PBL.
+ *
+ * The following types exist:
+ */
+#define IMD_TYPE_START 0x640c0001
+#define IMD_TYPE_RELEASE 0x640c8002 /* The barebox release aka UTS_RELEASE */
+#define IMD_TYPE_BUILD 0x640c8003 /* build number and timestamp (UTS_VERSION) */
+#define IMD_TYPE_MODEL 0x640c8004 /* The board name this image is for */
+#define IMD_TYPE_OF_COMPATIBLE 0x640c8005 /* the device tree compatible string */
+#define IMD_TYPE_PARAMETER 0x640c8006 /* A generic parameter. Use key=value as data */
+#define IMD_TYPE_END 0x640c7fff
+#define IMD_TYPE_INVALID 0xffffffff
+
+/*
+ * The IMD header. All data is stored in little endian format in the image.
+ * The next header starts at the next 4 byte boundary after the data.
+ */
+struct imd_header {
+ uint32_t type; /* One of IMD_TYPE_* above */
+ uint32_t datalength; /* Length of the data (exluding the header) */
+};
+
+/*
+ * A IMD string. Set bit 15 of the IMD_TYPE to indicate the data is printable
+ * as string.
+ */
+struct imd_entry_string {
+ struct imd_header header;
+ char data[];
+};
+
+static inline int imd_is_string(uint32_t type)
+{
+ return (type & 0x8000) ? 1 : 0;
+}
+
+static inline int imd_type_valid(uint32_t type)
+{
+ return (type & 0xffff0000) == 0x640c0000;
+}
+
+struct imd_header *imd_next(struct imd_header *imd);
+
+#define imd_for_each(start, imd) \
+ for (imd = imd_next(start); imd_read_type(imd) != IMD_TYPE_END; imd = imd_next(imd))
+
+static inline uint32_t imd_read_le32(void *_ptr)
+{
+ uint8_t *ptr = _ptr;
+
+ return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
+}
+
+static inline uint32_t imd_read_type(struct imd_header *imd)
+{
+ return imd_read_le32(&imd->type);
+}
+
+static inline uint32_t imd_read_length(struct imd_header *imd)
+{
+ return imd_read_le32(&imd->datalength);
+}
+
+struct imd_header *imd_find_type(struct imd_header *imd, uint32_t type);
+
+extern int imd_command_verbose;
+int imd_command_setenv(const char *variable_name, const char *value);
+int imd_command(int argc, char *argv[]);
+
+#ifdef __BAREBOX__
+
+#include <linux/stringify.h>
+
+#define __BAREBOX_IMD_SECTION(_section) \
+ __attribute__ ((unused,section (__stringify(_section)))) \
+ __attribute__((aligned(4)))
+
+#define BAREBOX_IMD_TAG_STRING(_name, _type, _string, _keep_if_unused) \
+ const struct imd_entry_string __barebox_imd_##_name \
+ __BAREBOX_IMD_SECTION(.barebox_imd_ ## _keep_if_unused ## _ ## _name) = { \
+ .header.type = cpu_to_le32(_type), \
+ .header.datalength = cpu_to_le32(sizeof(_string)), \
+ .data = _string, \
+ }
+
+
+#ifdef CONFIG_IMD
+void imd_used(const void *);
+#else
+static inline void imd_used(const void *unused)
+{
+}
+#endif
+
+#define IMD_USED(_name) \
+ imd_used(&__barebox_imd_##_name)
+
+#endif /* __BAREBOX__ */
+
+#endif /* __INCLUDE_IMAGE_METADTA_H */