For the impatient
The process to set it up is the following:U-Boot > ext2load mmc 1 10000000 /water-conservation1024x600.bmp.gz 745898 bytes read in 219 ms (3.2 MiB/s) U-Boot > sf probe SF: Detected SST25VF016B with page size 4 KiB, total 2 MiB U-Boot > sf erase c2000 +${filesize} U-Boot > sf write 10000000 c2000 ${filesize} U-Boot > setenv splashimage 12000000 U-Boot > setenv splashpos m,m U-Boot > setenv splashsize ${filesize} U-Boot > saveenv
- The image is copied into SPI flash so it is tied to the board and won’t change with different boot devices.
- For splashimage, pick somewhere in the valid range.
- The variable splashpos is optional and setting it to m,m will center the image.
- SPI NOR flash is 2 MiB so your max image size is 1302528 bytes, 2 MiB – c2000 bytes.
- It can handle most bmp formats as well as gzipped versions as show above.
Background
U-Boot provides the bmp command for working with bitmaps. You can load an image from an SD card and display them like this:U-Boot > ls mmc 1 <DIR> 4096 . <DIR> 4096 .. <DIR> 16384 lost+found ... 1152138 water2.bmp 1843338 water1.bmp 1152138 water-conservation800x480.bmp 1843338 water-conservation1024x600.bmp 1843338 splash.bmp 134538 boundarydevicesx240.bmp 745898 water-conservation1024x600.bmp.gz U-Boot > ext2load mmc 1 10000000 /water-conservation1024x600.bmp.gz 745898 bytes read in 219 ms (3.2 MiB/s) U-Boot > bmp i 10000000 Image size : 1024 x 600 Bits per pixel: 24 Compression : 0 U-Boot > bmp d 10000000With this capability we could do something like adding the following line to the top of 6x_bootscript (or to the bootcmd environment variable), will cause u-boot to look for a bitmap image named splash.bmp in the root directory of the filesystem from whatever you’re booting from.
${fs}load ${dtype} ${disk}:1 10000000 /splash.bmp && bmp d 10000000 ;
See this post for more details about the bootscript and bootcmd
There are 2 major downsides with this method. One, if there’s no boot media attached to the board you get Tux. Two, it’s slow and fleeting. You still see Tux and the version info for a second or 2 because it only runs once the bootcmd has been called after the 1 second boot delay and if you continue to boot into Linux or something else which has it’s own splash screen or simply clears the screen, you’ll only see your image for a second anyway.
SPI NOR and splashimage
We want displaying the splash screen to work regardless of whether there’s an SD card or anything else plugged in to boot from and we want it displayed immediately on boot up (without seeing Tux or U-Boot output).
The first part can be solved using flash. Our boards have 2 MiB of non-volatile SPI NOR flash, part of which we use to store U-Boot and the environment variables. We can store an image here with U-Boot’s sf commands. Assuming you’ve just loaded an image to RAM at address 10000000 (see above), the process looks like this:
U-Boot > sf probe SF: Detected SST25VF016B with page size 4 KiB, total 2 MiB U-Boot > sf erase c2000 +${filesize} U-Boot > sf write 10000000 c2000 ${filesize} U-Boot > sf read 12000000 c2000 ${filesize} U-Boot > bmp d 12000000The filesize environment variable is automatically set to the size of the file just loaded (in hex which is what we need). Why did we write to SPI location c2000 besides that’s where loadsplash expects it? The SPI NOR memory map looks like this:
0..bffff - U-Boot 0xc0000..0xc1fff - environment
The free space in flash is from c2000 to the end, so that’s where we put the image.
The second part, displaying immediately at bootup, is covered by taking advantage of the CONFIG_SPLASH_SCREEN option in U-Boot. When U-Boot is compiled with this enabled, immediately on startup it will look for an environment variable named splashimage and read an address out of it. It’ll then try to load and display a bmp image from that location in RAM.
Sounds easy enough, but now we have another problem. U-Boot’s splash screen feature is expecting the image in RAM and our image is stored in NOR flash. To solve this we’ve committed some code changes to the staging branch. This key change is an added default environment variable loadsplash:
loadsplash=if sf probe ; then sf read ${splashimage} c2000 ${splashsize} ; fiObviously, when run it will copy an image from c2000 in flash to the location in splashimage, the place where U-Boot will look for it. You can try running it manually using the run command:
U-Boot > run loadsplash SF: Detected SST25VF016B with page size 4 KiB, total 2 MiB U-Boot > bmp d ${splashimage}So, at startup, if splashimage and splashsize and loadsplash exist, U-Boot will try to run loadsplash. Splashimage, is as we mentioned the address that U-Boot will look for the splash screen bmp so we load it there and splashsize is the size in hex of the image you copied to SPI NOR. You’ll have to set those 2 variables using setenv:
U-Boot > setenv splashimage 12000000 U-Boot > setenv splashpos m,m U-Boot > setenv splashsize ${filesize} U-Boot > saveenv
After setting these variables appropriately, you’re done. Reset and you should see your image displayed instantly.
Conclusion
I admit that it does seem like quite a process going on behind the scenes for something as simple as displaying a splash image but we’ve aimed for it to be as easy to use (or ignore) as possible from the your perspective