[Concept,3/6] video: Support a linker list of images

Message ID 20251001230537.3324058-4-sjg@u-boot.org
State New
Headers
Series video: Tidy up embedded graphical images |

Commit Message

Simon Glass Oct. 1, 2025, 11:05 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

It is inconvenient to have to access graphical images as independent
symbols. Create a new rule which handles any file mentioned in
drivers/video/images/Makefile

For each graphical image, embed in the image and create a linker-list
entry for it.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/video.h       | 46 +++++++++++++++++++++++++++++++++++++++++++
 include/video_image.h | 13 ++++++++++++
 scripts/Makefile.lib  | 38 +++++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+)
 create mode 100644 include/video_image.h
  

Comments

Heinrich Schuchardt Oct. 2, 2025, 12:16 a.m. UTC | #1
Am 2. Oktober 2025 01:05:29 MESZ schrieb Simon Glass <sjg@u-boot.org>:
>From: Simon Glass <sjg@chromium.org>
>
>It is inconvenient to have to access graphical images as independent
>symbols. Create a new rule which handles any file mentioned in
>drivers/video/images/Makefile
>
>For each graphical image, embed in the image and create a linker-list
>entry for it.
>
>Co-developed-by: Claude <noreply@anthropic.com>
>Signed-off-by: Simon Glass <sjg@chromium.org>
>---
>
> include/video.h       | 46 +++++++++++++++++++++++++++++++++++++++++++
> include/video_image.h | 13 ++++++++++++
> scripts/Makefile.lib  | 38 +++++++++++++++++++++++++++++++++++
> 3 files changed, 97 insertions(+)
> create mode 100644 include/video_image.h
>
>diff --git a/include/video.h b/include/video.h
>index 9f891cf9d30..9985f5adcf8 100644
>--- a/include/video.h
>+++ b/include/video.h
>@@ -7,7 +7,9 @@
> #ifndef _VIDEO_H_
> #define _VIDEO_H_
> 
>+#include <linker_lists.h>
> #include <stdio_dev.h>
>+#include <video_image.h>
> #ifdef CONFIG_SANDBOX
> #include <asm/state.h>
> #endif
>@@ -201,6 +203,50 @@ enum colour_idx {
> 	VID_COLOUR_COUNT
> };
> 
>+/**
>+ * struct video_image - Information about an embedded image
>+ *
>+ * This structure holds the pointers to the start and end of an image
>+ * that is embedded in the U-Boot binary, along with its name.
>+ * On 64-bit: 2*8 + VIDEO_IMAGE_NAMELEN = 32 bytes
>+ * On 32-bit: 2*4 + VIDEO_IMAGE_NAMELEN = 24 bytes
>+ *
>+ * @begin: Pointer to the start of the image data
>+ * @end: Pointer to the end of the image data
>+ * @name: Name of the image (e.g., "u_boot", "canonical"), null-terminated
>+ */
>+struct video_image {
>+	const void *begin;
>+	const void *end;
>+	char name[VIDEO_IMAGE_NAMELEN];
>+};
>+
>+/**
>+ * video_image_get() - Get the start address and size of an image
>+ *
>+ * @_name: Name of the image taken from filename (e.g. u_boot)
>+ * @_sizep: Returns the size of the image in bytes
>+ * Return: Pointer to the start of the image data
>+ */
>+#define video_image_get(_name, _sizep) ({ \
>+	struct video_image *__img = ll_entry_get(struct video_image, _name, \
>+						  video_image); \
>+	*(_sizep) = (ulong)__img->end - (ulong)__img->begin; \
>+	(void *)__img->begin; \
>+	})
>+
>+/**
>+ * video_image_getptr() - Get the start address of an image
>+ *
>+ * @_name: Name of the image taken from filename (e.g. u_boot)
>+ * Return: Pointer to the start of the image data
>+ */
>+#define video_image_getptr(_name) ({ \
>+	struct video_image *__img = ll_entry_get(struct video_image, _name, \
>+						  video_image); \
>+	(void *)__img->begin; \
>+	})
>+
> /**
>  * video_index_to_colour() - convert a color code to a pixel's internal
>  * representation
>diff --git a/include/video_image.h b/include/video_image.h
>new file mode 100644
>index 00000000000..35d6d7f1fd4
>--- /dev/null
>+++ b/include/video_image.h
>@@ -0,0 +1,13 @@
>+/* SPDX-License-Identifier: GPL-2.0+ */
>+/*
>+ * Copyright 2025 Google LLC

Can't see any Google involvement here.
For which company are you working?

>+ * Written by Simon Glass <sjg@chromium.org>

Give credit to your current sponsor.

Best regards

Heinrich

>+ */
>+
>+#ifndef __VIDEO_IMAGE_H
>+#define __VIDEO_IMAGE_H
>+
>+/* Maximum length of an embedded image name */
>+#define VIDEO_IMAGE_NAMELEN	16
>+
>+#endif /* __VIDEO_IMAGE_H */
>diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
>index 5abe428e752..e812327b585 100644
>--- a/scripts/Makefile.lib
>+++ b/scripts/Makefile.lib
>@@ -523,6 +523,44 @@ cmd_S_splash=						\
> $(obj)/%_logo.S: $(src)/%_logo.bmp
> 	$(call cmd,S_splash)
> 
>+# Handle image files in drivers/video/images without _logo suffix
>+# Generate an assembly file to wrap the image data and create a linker-list entry
>+quiet_cmd_S_image= IMAGE   $@
>+cmd_S_image=						\
>+(							\
>+	echo '\#include <video_image.h>';		\
>+	echo '.section .rodata.image.init,"a"';		\
>+	echo '.balign 16';				\
>+	echo '.global __image_$(*F)_begin';		\
>+	echo '__image_$(*F)_begin:';			\
>+	echo '.incbin "$<" ';				\
>+	echo '__image_$(*F)_end:';			\
>+	echo '.global __image_$(*F)_end';		\
>+	echo '.balign 16';				\
>+	echo '';					\
>+	echo '/* Linker list entry for this image */';	\
>+	echo '.section __u_boot_list_2_video_image_2_$(*F), "aw"'; \
>+	echo '.balign 8';				\
>+	echo '.global _u_boot_list_2_video_image_2_$(*F)'; \
>+	echo '_u_boot_list_2_video_image_2_$(*F):';	\
>+	echo '\#ifdef __LP64__';			\
>+	echo '.quad __image_$(*F)_begin';		\
>+	echo '.quad __image_$(*F)_end';			\
>+	echo '.asciz "'$(*F)'"';			\
>+	echo '.org _u_boot_list_2_video_image_2_$(*F) + 16 + VIDEO_IMAGE_NAMELEN'; \
>+	echo '\#else';					\
>+	echo '.long __image_$(*F)_begin';		\
>+	echo '.long __image_$(*F)_end';			\
>+	echo '.asciz "'$(*F)'"';			\
>+	echo '.org _u_boot_list_2_video_image_2_$(*F) + 8 + VIDEO_IMAGE_NAMELEN'; \
>+	echo '\#endif';					\
>+) > $@
>+
>+ifneq ($(filter drivers/video/images,$(obj)),)
>+$(obj)/%.S: $(src)/%.bmp
>+	$(call cmd,S_image)
>+endif
>+
> # Generate an assembly file to wrap the EFI 'Boot Graphics Resource Table' image
> quiet_cmd_S_bgrt= BGRT    $@
> # Modified for U-Boot
  

Patch

diff --git a/include/video.h b/include/video.h
index 9f891cf9d30..9985f5adcf8 100644
--- a/include/video.h
+++ b/include/video.h
@@ -7,7 +7,9 @@ 
 #ifndef _VIDEO_H_
 #define _VIDEO_H_
 
+#include <linker_lists.h>
 #include <stdio_dev.h>
+#include <video_image.h>
 #ifdef CONFIG_SANDBOX
 #include <asm/state.h>
 #endif
@@ -201,6 +203,50 @@  enum colour_idx {
 	VID_COLOUR_COUNT
 };
 
+/**
+ * struct video_image - Information about an embedded image
+ *
+ * This structure holds the pointers to the start and end of an image
+ * that is embedded in the U-Boot binary, along with its name.
+ * On 64-bit: 2*8 + VIDEO_IMAGE_NAMELEN = 32 bytes
+ * On 32-bit: 2*4 + VIDEO_IMAGE_NAMELEN = 24 bytes
+ *
+ * @begin: Pointer to the start of the image data
+ * @end: Pointer to the end of the image data
+ * @name: Name of the image (e.g., "u_boot", "canonical"), null-terminated
+ */
+struct video_image {
+	const void *begin;
+	const void *end;
+	char name[VIDEO_IMAGE_NAMELEN];
+};
+
+/**
+ * video_image_get() - Get the start address and size of an image
+ *
+ * @_name: Name of the image taken from filename (e.g. u_boot)
+ * @_sizep: Returns the size of the image in bytes
+ * Return: Pointer to the start of the image data
+ */
+#define video_image_get(_name, _sizep) ({ \
+	struct video_image *__img = ll_entry_get(struct video_image, _name, \
+						  video_image); \
+	*(_sizep) = (ulong)__img->end - (ulong)__img->begin; \
+	(void *)__img->begin; \
+	})
+
+/**
+ * video_image_getptr() - Get the start address of an image
+ *
+ * @_name: Name of the image taken from filename (e.g. u_boot)
+ * Return: Pointer to the start of the image data
+ */
+#define video_image_getptr(_name) ({ \
+	struct video_image *__img = ll_entry_get(struct video_image, _name, \
+						  video_image); \
+	(void *)__img->begin; \
+	})
+
 /**
  * video_index_to_colour() - convert a color code to a pixel's internal
  * representation
diff --git a/include/video_image.h b/include/video_image.h
new file mode 100644
index 00000000000..35d6d7f1fd4
--- /dev/null
+++ b/include/video_image.h
@@ -0,0 +1,13 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2025 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __VIDEO_IMAGE_H
+#define __VIDEO_IMAGE_H
+
+/* Maximum length of an embedded image name */
+#define VIDEO_IMAGE_NAMELEN	16
+
+#endif /* __VIDEO_IMAGE_H */
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 5abe428e752..e812327b585 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -523,6 +523,44 @@  cmd_S_splash=						\
 $(obj)/%_logo.S: $(src)/%_logo.bmp
 	$(call cmd,S_splash)
 
+# Handle image files in drivers/video/images without _logo suffix
+# Generate an assembly file to wrap the image data and create a linker-list entry
+quiet_cmd_S_image= IMAGE   $@
+cmd_S_image=						\
+(							\
+	echo '\#include <video_image.h>';		\
+	echo '.section .rodata.image.init,"a"';		\
+	echo '.balign 16';				\
+	echo '.global __image_$(*F)_begin';		\
+	echo '__image_$(*F)_begin:';			\
+	echo '.incbin "$<" ';				\
+	echo '__image_$(*F)_end:';			\
+	echo '.global __image_$(*F)_end';		\
+	echo '.balign 16';				\
+	echo '';					\
+	echo '/* Linker list entry for this image */';	\
+	echo '.section __u_boot_list_2_video_image_2_$(*F), "aw"'; \
+	echo '.balign 8';				\
+	echo '.global _u_boot_list_2_video_image_2_$(*F)'; \
+	echo '_u_boot_list_2_video_image_2_$(*F):';	\
+	echo '\#ifdef __LP64__';			\
+	echo '.quad __image_$(*F)_begin';		\
+	echo '.quad __image_$(*F)_end';			\
+	echo '.asciz "'$(*F)'"';			\
+	echo '.org _u_boot_list_2_video_image_2_$(*F) + 16 + VIDEO_IMAGE_NAMELEN'; \
+	echo '\#else';					\
+	echo '.long __image_$(*F)_begin';		\
+	echo '.long __image_$(*F)_end';			\
+	echo '.asciz "'$(*F)'"';			\
+	echo '.org _u_boot_list_2_video_image_2_$(*F) + 8 + VIDEO_IMAGE_NAMELEN'; \
+	echo '\#endif';					\
+) > $@
+
+ifneq ($(filter drivers/video/images,$(obj)),)
+$(obj)/%.S: $(src)/%.bmp
+	$(call cmd,S_image)
+endif
+
 # Generate an assembly file to wrap the EFI 'Boot Graphics Resource Table' image
 quiet_cmd_S_bgrt= BGRT    $@
 # Modified for U-Boot