[PATCH 4/4] tools: zynqmpimage: print partition names

Brandon Maier brandon.maier at collins.com
Thu Jan 4 19:50:09 CET 2024


Each partition may belong to an image, which has a name. That name can
be useful for debugging as it helps identify where the partition came
from.

Signed-off-by: Brandon Maier <brandon.maier at collins.com>
---

 tools/zynqmpimage.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
 tools/zynqmpimage.h | 49 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)

diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
index 307edd63ebb..4db9877127e 100644
--- a/tools/zynqmpimage.c
+++ b/tools/zynqmpimage.c
@@ -135,6 +135,53 @@ static int zynqmpimage_verify_header(unsigned char *ptr, int image_size,
 	return 0;
 }
 
+static struct image_header *
+find_partition_image(const struct zynqmp_header *zynqhdr,
+		     const struct partition_header *ph)
+{
+	struct partition_header *ph_walk;
+	struct image_header *ih;
+	int i;
+
+	for_each_zynqmp_image(zynqhdr, ih) {
+		for_each_zynqmp_part_in_image(zynqhdr, i, ph_walk, ih) {
+			if (ph == ph_walk)
+				return ih;
+		}
+	}
+
+	return NULL;
+}
+
+static void print_partition_name(const struct zynqmp_header *zynqhdr,
+				 const struct partition_header *ph)
+{
+	const struct image_header *ih;
+	size_t word_len;
+	char *name;
+	int i;
+
+	ih = find_partition_image(zynqhdr, ph);
+	if (!ih)
+		return;
+
+	/* Name is stored in big-endian words, find the terminating word and
+	 * byte-swap into a new buffer
+	 */
+	word_len = strlen((char *)ih->image_name);
+	word_len = ALIGN(word_len + 1, 4);
+
+	name = calloc(1, word_len);
+	if (!name)
+		return;
+
+	for (i = 0; i < word_len / 4; i++)
+		((uint32_t *)name)[i] = uswap_32(ih->image_name[i]);
+
+	printf("    Image name : %s\n", name);
+	free(name);
+}
+
 static void print_partition(const void *ptr, const struct partition_header *ph)
 {
 	uint32_t attr = le32_to_cpu(ph->attributes);
@@ -163,6 +210,7 @@ static void print_partition(const void *ptr, const struct partition_header *ph)
 	       dest_cpus[(attr & PART_ATTR_DEST_CPU_MASK) >> 8],
 	       dest_devs[(attr & PART_ATTR_DEST_DEVICE_MASK) >> 4]);
 
+	print_partition_name(ptr, ph);
 	printf("    Offset     : 0x%08x\n", le32_to_cpu(ph->offset) * 4);
 	printf("    Size       : %lu (0x%lx) bytes\n", len, len);
 	if (len != len_unenc)
diff --git a/tools/zynqmpimage.h b/tools/zynqmpimage.h
index 32be0d125fd..7c47dc0763b 100644
--- a/tools/zynqmpimage.h
+++ b/tools/zynqmpimage.h
@@ -51,6 +51,14 @@ struct image_header_table {
 	uint32_t checksum;		  /* 0x3c */
 };
 
+struct image_header {
+	uint32_t next_image_header_offset;		/* 0x00 */
+	uint32_t corresponding_partition_header;	/* 0x04 */
+	uint32_t __reserved1;				/* 0x08 */
+	uint32_t partition_count;			/* 0x0c */
+	uint32_t image_name[];				/* 0x10 */
+};
+
 #define PART_ATTR_VEC_LOCATION		0x800000
 #define PART_ATTR_BS_BLOCK_SIZE_MASK	0x700000
 #define     PART_ATTR_BS_BLOCK_SIZE_DEFAULT	0x000000
@@ -193,4 +201,45 @@ static inline size_t zynqmp_part_count(const struct zynqmp_header *zynqhdr)
 			zynqmp_part_first(_zynqhdr), \
 			zynqmp_part_count(_zynqhdr))
 
+static inline struct partition_header *
+zynqmp_part_in_image_first(const struct zynqmp_header *zynqhdr,
+			   const struct image_header *ih)
+{
+	return zynqmp_get_offset(zynqhdr, ih->corresponding_partition_header);
+}
+
+static inline size_t zynqmp_part_in_image_count(const struct image_header *ih)
+{
+	return le32_to_cpu(ih->partition_count);
+}
+
+#define for_each_zynqmp_part_in_image(_zynqhdr, _iter, _ph, _ih) \
+	_for_each_zynqmp_part(_zynqhdr, _iter, _ph, \
+			zynqmp_part_in_image_first(_zynqhdr, _ih), \
+			zynqmp_part_in_image_count(_ih))
+
+static inline struct image_header *
+zynqmp_image_first(const struct zynqmp_header *zynqhdr)
+{
+	struct image_header_table *iht;
+
+	iht = zynqmp_get_iht(zynqhdr);
+	if (!iht)
+		return NULL;
+
+	return zynqmp_get_offset(zynqhdr, iht->image_header_offset);
+}
+
+static inline struct image_header *
+zynqmp_image_next(const struct zynqmp_header *zynqhdr,
+		  const struct image_header *ih)
+{
+	return zynqmp_get_offset(zynqhdr, ih->next_image_header_offset);
+}
+
+#define for_each_zynqmp_image(_zynqhdr, _ih) \
+	for (_ih = zynqmp_image_first(_zynqhdr); \
+	     _ih; \
+	     _ih = zynqmp_image_next(_zynqhdr, _ih))
+
 #endif /* _ZYNQMPIMAGE_H_ */
-- 
2.43.0



More information about the U-Boot mailing list