Commit c0880485 authored by Nikita Kiryanov's avatar Nikita Kiryanov Committed by Tom Rini
Browse files

lcd: implement a callback for splashimage

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 <>
Cc: Wolfgang Denk <>
Signed-off-by: default avatarNikita Kiryanov <>
Acked-by: default avatarIgor Grinberg <>
parent 48ec5291
......@@ -1530,6 +1530,17 @@ CBFS (Coreboot Filesystem) support
allows for a "silent" boot where a splash screen is
loaded very quickly after power-on.
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 think you will not have problems with unaligned
accesses (for example because your toolchain prevents them)
there is no need to set this option.
If this option is set the splash image can be freely positioned
......@@ -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)
......@@ -1099,6 +1101,30 @@ static void *lcd_logo(void)
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);
void lcd_position_cursor(unsigned col, unsigned row)
console_col = min(col, CONSOLE_COLS - 1);
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.
......@@ -41,6 +41,12 @@
#define SPLASHIMAGE_CALLBACK "splashimage:splashimage,"
* 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," \
"stdin:console,stdout:console,stderr:console," \
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment