Coverage Report

Created: 2026-10-17 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/barebox/include/image-metadata.h
Line
Count
Source
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
#ifndef __INCLUDE_IMAGE_METADTA_H
3
#define __INCLUDE_IMAGE_METADTA_H
4
5
/*
6
 * barebox Image MetaData (IMD)
7
 *
8
 * IMD is a mechanism to store metadata in barebox images. With IMD
9
 * it's possible to extract the release, the build timestamp and the
10
 * board type from a barebox image.
11
 *
12
 * Since there is no fixed place in the image suitable for all SoC image
13
 * types the metadata can be stored anywhere in the image and is found
14
 * by iterating over the image. The metadata starts with a start header
15
 * and ends with an end header. All tags in between carry the payload.
16
 *
17
 * Make sure source files containing IMD data are compiled with lwl-y so
18
 * that the tags end up in the PBL if one exists and in the regular image
19
 * without PBL.
20
 *
21
 * The following types exist:
22
 */
23
0
#define IMD_TYPE_START    0x640c0001
24
#define IMD_TYPE_RELEASE  0x640c8002 /* The barebox release aka UTS_RELEASE */
25
#define IMD_TYPE_BUILD    0x640c8003 /* build number and timestamp (UTS_VERSION) */
26
#define IMD_TYPE_MODEL    0x640c8004 /* The board name this image is for */
27
#define IMD_TYPE_OF_COMPATIBLE  0x640c8005 /* the device tree compatible string */
28
0
#define IMD_TYPE_PARAMETER  0x640c8006 /* A generic parameter. Use key=value as data */
29
#define IMD_TYPE_BUILDSYSTEM  0x640c8007 /* The buildsystem version barebox was built with */
30
0
#define IMD_TYPE_CRC32    0x640c1007 /* the checksum of the barebox images */
31
0
#define IMD_TYPE_END    0x640c7fff
32
0
#define IMD_TYPE_INVALID  0xffffffff
33
34
0
#define IMD_CRC32_FLAG_TAG_VALID  (1 << 0)
35
36
/*
37
 * The IMD header. All data is stored in little endian format in the image.
38
 * The next header starts at the next 4 byte boundary after the data.
39
 */
40
struct imd_header {
41
  uint32_t type;    /* One of IMD_TYPE_* above */
42
  uint32_t datalength;  /* Length of the data (exluding the header) */
43
};
44
45
/*
46
 * A IMD string. Set bit 15 of the IMD_TYPE to indicate the data is printable
47
 * as string.
48
 */
49
struct imd_entry_string {
50
  struct imd_header header;
51
  char data[];
52
};
53
54
static inline int imd_is_string(uint32_t type)
55
0
{
56
0
  return (type & 0x8000) ? 1 : 0;
57
0
}
Unexecuted instantiation: imd.c:imd_is_string
Unexecuted instantiation: imd-barebox.c:imd_is_string
58
59
/*
60
 * A IMD int.
61
 */
62
struct imd_entry_crc32 {
63
  struct imd_header header;
64
  uint32_t data;
65
  uint32_t flags;
66
};
67
68
static inline int imd_is_crc32(uint32_t type)
69
0
{
70
0
  return type == IMD_TYPE_CRC32;
71
0
}
Unexecuted instantiation: imd.c:imd_is_crc32
Unexecuted instantiation: imd-barebox.c:imd_is_crc32
72
73
static inline int imd_crc32_is_valid(uint32_t flags)
74
0
{
75
0
  return (flags & IMD_CRC32_FLAG_TAG_VALID) ? 1 : 0;
76
0
}
Unexecuted instantiation: imd.c:imd_crc32_is_valid
Unexecuted instantiation: imd-barebox.c:imd_crc32_is_valid
77
78
0
static inline int imd_type_valid(uint32_t type) {
79
0
  return (type & 0xffff0000) == 0x640c0000;
80
0
}
Unexecuted instantiation: imd.c:imd_type_valid
Unexecuted instantiation: imd-barebox.c:imd_type_valid
81
82
const struct imd_header *imd_next(const struct imd_header *imd);
83
84
#define imd_for_each(start, imd) \
85
0
  for (imd = imd_next(start); imd_read_type(imd) != IMD_TYPE_END; imd = imd_next(imd))
86
87
static inline uint32_t imd_read_le32(const void *_ptr)
88
0
{
89
0
  const uint8_t *ptr = _ptr;
90
91
0
  return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
92
0
}
Unexecuted instantiation: imd.c:imd_read_le32
Unexecuted instantiation: imd-barebox.c:imd_read_le32
93
94
static inline uint32_t imd_read_type(const struct imd_header *imd)
95
0
{
96
0
  return imd_read_le32(&imd->type);
97
0
}
Unexecuted instantiation: imd.c:imd_read_type
Unexecuted instantiation: imd-barebox.c:imd_read_type
98
99
static inline uint32_t imd_read_length(const struct imd_header *imd)
100
0
{
101
0
  return imd_read_le32(&imd->datalength);
102
0
}
Unexecuted instantiation: imd.c:imd_read_length
Unexecuted instantiation: imd-barebox.c:imd_read_length
103
104
static inline uint32_t imd_read_flags(const struct imd_entry_crc32 *imd)
105
0
{
106
0
  return imd_read_le32(&imd->flags);
107
0
}
Unexecuted instantiation: imd.c:imd_read_flags
Unexecuted instantiation: imd-barebox.c:imd_read_flags
108
109
const struct imd_header *imd_find_type(const struct imd_header *imd,
110
               uint32_t type);
111
112
const struct imd_header *imd_get(const void *buf, int size);
113
const char *imd_string_data(const struct imd_header *imd, int index);
114
const uint32_t *imd_uint32_data(const struct imd_header *imd);
115
uint32_t *imd_uint32_flags(const struct imd_header *imd);
116
const char *imd_type_to_name(uint32_t type);
117
char *imd_concat_strings(const struct imd_header *imd);
118
const char *imd_get_param(const struct imd_header *imd, const char *name);
119
120
extern int imd_command_verbose;
121
int imd_command_setenv(const char *variable_name, const char *value);
122
int imd_command(int argc, char *argv[]);
123
int imd_verify_crc32(void *buf, size_t size);
124
125
#ifdef __BAREBOX__
126
127
#include <linux/stringify.h>
128
#include <linux/compiler_types.h>
129
130
#define __BAREBOX_IMD_SECTION(_section) \
131
  __ll_elem(_section) __attribute__((aligned(4)))
132
133
#define BAREBOX_IMD_TAG_STRING(_name, _type, _string, _keep_if_unused)      \
134
  const struct imd_entry_string __barebox_imd_##_name       \
135
  __BAREBOX_IMD_SECTION(.barebox_imd_ ## _keep_if_unused ## _ ## _name) = { \
136
    .header.type = cpu_to_le32(_type),          \
137
    .header.datalength = cpu_to_le32(sizeof(_string)),      \
138
    .data = _string,              \
139
  }
140
141
#define BAREBOX_IMD_CRC(_name, _crc, _keep_if_unused)         \
142
  const struct imd_entry_crc32 __barebox_imd_##__name       \
143
  __BAREBOX_IMD_SECTION(.barebox_imd_ ## _keep_if_unused ## _ ## _name) = { \
144
    .header.type = cpu_to_le32(IMD_TYPE_CRC32),       \
145
    .header.datalength = cpu_to_le32(sizeof(uint32_t) * 2),     \
146
    .data = _crc,               \
147
  }
148
149
#ifdef CONFIG_IMD
150
void imd_used(const void *);
151
#else
152
static inline void imd_used(const void *unused)
153
{
154
}
155
#endif
156
157
#define IMD_USED(_name) \
158
  imd_used(&__barebox_imd_##_name)
159
160
__attribute__((deprecated("IMD entries are now always referenced if DT itself is")))
161
static inline void IMD_USED_OF(void)
162
0
{}
Unexecuted instantiation: imd.c:IMD_USED_OF
Unexecuted instantiation: imd-barebox.c:IMD_USED_OF
163
164
#define IMD_USED_OF(_name) IMD_USED_OF()
165
166
#endif /* __BAREBOX__ */
167
168
#endif /* __INCLUDE_IMAGE_METADTA_H */