[U-Boot] [PATCH 1/2] lcd: implement a callback for splashimage

Nikita Kiryanov nikita at compulab.co.il
Sun Feb 24 17:19:22 CET 2013


On some architectures certain values of splashimage will lead to
a data abort exception.

Document the problem, and implement a callback for splashimage to
reject such values.

Cc: Anatolij Gustschin <agust at denx.de>
Cc: Wolfgang Denk <wd at denx.de>
Signed-off-by: Nikita Kiryanov <nikita at compulab.co.il>
Acked-by: Igor Grinberg <grinberg at compulab.co.il>
---

 README                     |   11 +++++++++++
 common/lcd.c               |   26 ++++++++++++++++++++++++++
 doc/README.displaying-bmps |   27 +++++++++++++++++++++++++++
 include/env_callback.h     |    7 +++++++
 4 files changed, 71 insertions(+)
 create mode 100644 doc/README.displaying-bmps

diff --git a/README b/README
index d8cb394..f1e416a 100644
--- a/README
+++ b/README
@@ -1530,6 +1530,17 @@ CBFS (Coreboot Filesystem) support
 		allows for a "silent" boot where a splash screen is
 		loaded very quickly after power-on.
 
+		CONFIG_SPLASHIMAGE_GUARD
+
+		If this option is set, then U-Boot will prevent the environment
+		variable "splashimage" from being set to a problematic address
+		(see README.displaying-bmps and README.arm-unaligned-accesses).
+		This option is useful for targets where, due to alignment
+		restrictions, an improperly aligned BMP image will cause a data
+		abort. If you don't think you will not have problems with
+		unaligned accesses (for example because your toolchain prevents
+		them) there is no need to set this option.
+
 		CONFIG_SPLASH_SCREEN_ALIGN
 
 		If this option is set the splash image can be freely positioned
diff --git a/common/lcd.c b/common/lcd.c
index 66d4f94..5d54168 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -33,6 +33,8 @@
 #include <common.h>
 #include <command.h>
 #include <stdarg.h>
+#include <search.h>
+#include <env_callback.h>
 #include <linux/types.h>
 #include <stdio_dev.h>
 #if defined(CONFIG_POST)
@@ -1084,6 +1086,30 @@ static void *lcd_logo(void)
 #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
 }
 
+#ifdef CONFIG_SPLASHIMAGE_GUARD
+static int on_splashimage(const char *name, const char *value, enum env_op op,
+	int flags)
+{
+	ulong addr;
+	int aligned;
+
+	if (op == env_op_delete)
+		return 0;
+
+	addr = simple_strtoul(value, NULL, 16);
+	/* See README.displaying-bmps */
+	aligned = (addr % 4 == 2);
+	if (!aligned) {
+		printf("Invalid splashimage value. Value must be 16 bit aligned, but not 32 bit aligned\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
+#endif
+
 void lcd_position_cursor(unsigned col, unsigned row)
 {
 	console_col = min(col, CONSOLE_COLS - 1);
diff --git a/doc/README.displaying-bmps b/doc/README.displaying-bmps
new file mode 100644
index 0000000..3311541
--- /dev/null
+++ b/doc/README.displaying-bmps
@@ -0,0 +1,27 @@
+If you are experiencing hangups/data-aborts when trying to display a BMP image,
+the following might be relevant to your situation...
+
+Some architectures cannot handle unaligned memory accesses, and an attempt to
+perform one will lead to a data abort. On such architectures it is necessary to
+make sure all data is properly aligned, and in many situations simply choosing
+a 32 bit aligned address is enough to ensure proper alignment. This is not
+always the case when dealing with data that has an internal layout such as a
+BMP image:
+
+BMP images have a header that starts with 2 byte-size fields followed by mostly
+32 bit fields. The packed struct that represents this header can be seen below:
+
+typedef struct bmp_header {
+	/* Header */
+	char signature[2];
+	__u32	file_size;
+	__u32	reserved;
+	__u32	data_offset;
+	... etc
+} __attribute__ ((packed)) bmp_header_t;
+
+When placed in an aligned address such as 0x80a00000, char signature offsets
+the __u32 fields into unaligned addresses (in our example 0x80a00002,
+0x80a00006, and so on...). When these fields are accessed by U-Boot, a 32 bit
+access is generated at a non-32-bit-aligned address, causing a data abort.
+The proper alignment for BMP images is therefore: 32-bit-aligned-address + 2.
diff --git a/include/env_callback.h b/include/env_callback.h
index c583120..62428d1 100644
--- a/include/env_callback.h
+++ b/include/env_callback.h
@@ -41,6 +41,12 @@
 #define SILENT_CALLBACK
 #endif
 
+#ifdef CONFIG_SPLASHIMAGE_GUARD
+#define SPLASHIMAGE_CALLBACK "splashimage:splashimage,"
+#else
+#define SPLASHIMAGE_CALLBACK
+#endif
+
 /*
  * This list of callback bindings is static, but may be overridden by defining
  * a new association in the ".callbacks" environment variable.
@@ -51,6 +57,7 @@
 	"bootfile:bootfile," \
 	"loadaddr:loadaddr," \
 	SILENT_CALLBACK \
+	SPLASHIMAGE_CALLBACK \
 	"stdin:console,stdout:console,stderr:console," \
 	CONFIG_ENV_CALLBACK_LIST_STATIC
 
-- 
1.7.10.4



More information about the U-Boot mailing list