diff options
Diffstat (limited to 'include/image-metadata.h')
-rw-r--r-- | include/image-metadata.h | 117 |
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 */ |