Earliest splashscreen / bootsplash / screen mirroring for raspberry !

Hi coderz !

Let’s see how to install a very quick splashscreen / bootsplash for your raspberry (or almost every distro having initrd compiled in kernel).
For this tutorial we will work on a Raspberry Pi 2, on debian wheezy, and a 3.5″ TFT (tontec mz61581), supported with « God-Like » notro’s firmware.
The process will be similar for others LCD, as long as they are supported by notro’s firmware. You can even adapt this tutorial without LCD, but mirroring a single screen can be hazardous !

Principe : To achieve the quickest display, we will first write raw image to the framebuffer(s). As soon as the LCD is loaded, plymouth is displayed to get a nicer and evolutive display. While plymouth is diplayed, we will start mirroring our screens with fbcp.
To save some precious seconds, all of this will be launched trough initramfs.

Bootsplash and splashscreen are quite redundant, you may want to use only one of them !

It’s up to you to install your LCD and the wonderful fbcp !

First, let’s install the required programs :

sudo apt-get install plymouth-drm ffmpeg

Setup initramfs

Initramfs will allow us to preload some devices and programs before the normal startup operations. In practice, it’s a compressed file loaded at boot as a file system. Let’s all praise JAH and rasbian devs, we don’t have no more to compile kernel for using it !

Make initramfs image

sudo update-initramfs -c -k $(uname -r)

Tell the bootloader to use the generated image. Add this to /boot/config.txt:

initramfs initrd.img-X.XX.XX+

Use the filename reported by the update-initramfs command.

Setup loading of fbtft modules

Next let’s try to start sooner our LCD display, including it’s modules to initramfs.

First, we must list the modules that should be included and loaded in the file :
/etc/initramfs-tools/modules

spi_bcm2708
fbtft
fb_s6d02a1

You may have to change the fb_s6d02a1 according to your LCD. See your /etc/modules for inspiration !
To be sure that the SPI master is available before fbtft module is loaded, let’s script the loading.

/etc/initramfs-tools/scripts/init-top/spi

#!/bin/sh
modprobe spi_bcm2708

Make the script executable:

sudo chmod +x /etc/initramfs-tools/scripts/init-top/spi

Splashscreen

As adding program in initramfsfs will also include it’s dependencies, we will avoid using fbi or pngview to display our splashscreen. So we will write with no mercy RGB 565 files to the framebuffers :)

First let’s force screen and framebuffer resolution, choosing some low values, for they are most compatible with older screens. You may want higher values, that’s fine too.

Update /boot/config.txt to add these lines.

framebuffer_width=640
framebuffer_height=480
hdmi_group=2
hdmi_mode=4

It’s now time to prepare your image with your favorite image editor, and save 2 versions of them as png, one in 640×480, one in your LCD native resolution, 480×320 in our case.
(note that ratio don’t match,  deal with that !)

Now we need to translate them in a format that match /dev/fb*, RGB565 seems ok for our color depht. As no graphic editor did include this format, let’s use ffmpeg to convert these png to raw RGB565.

ffmpeg -vcodec png -i image640.png -vcodec rawvideo -f rawvideo -pix_fmt rgb565 /home/pi/image640.raw
ffmpeg -vcodec png -i image480.png -vcodec rawvideo -f rawvideo -pix_fmt rgb565 /home/pi/image480.raw

Including files in our initramfs is a bit tricky on first sight, as we have to create a hook script in order to do this.
We will also use this script to include fbcp in our initramfs.
Create « /etc/initramfs-tools/hooks/cpimg.sh » with this content, and make it executable :

#!/bin/sh
PREREQ=""
prereqs()
{
        echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
        prereqs
        exit 0
        ;;
esac

# fbcp
. /usr/share/initramfs-tools/hook-functions
rm -f ${DESTDIR}/etc/image640.raw
rm -f ${DESTDIR}/etc/image480.raw
cp /home/pi/image640.raw ${DESTDIR}/etc
cp /home/pi/image480.raw ${DESTDIR}/etc
chmod 666 ${DESTDIR}/etc/image640.raw
chmod 666 ${DESTDIR}/etc/image480.raw
copy_exec /home/pi/fbcp /etc 
chmod +x ${DESTDIR}/etc/fbcp 
exit 0 

As you can see, we are copying our image in the /etc initramfs directory (maybe not the best location, but we can rely on it’s existence).
If you don’t want screen mirroring, remove all fbcp related lines !

Last step, tell the system to display our images. Let’s edit our previous « /etc/initramfs-tools/scripts/init-top/spi » script and add at the bottom :

cat /etc/image640.raw >/dev/fb0
cat /etc/image480.raw >/dev/fb1

Plymouth

Tell plymouth to use /dev/fb0 or /dev/fb1. If you want to use screen mirroring, choose /dev/fb0.

echo "export FRAMEBUFFER=/dev/fb0" | sudo tee /etc/initramfs-tools/conf.d/fb0

List plymouth themes

$ plymouth-set-default-theme --list

Set theme

sudo plymouth-set-default-theme joy

Enable plymouth  : Add to /boot/cmdline.txt (all in one line)

fbcon=map:01 splash quiet plymouth.ignore-serial-consoles

You may also want to write « logo.nologo » in cmdline.txt to avoid the raspberry logo display at boot.

Screen mirroring

If you have previously include fbcp via our hook script, the only thing we’ve got to do is to launch fbcp, at the good time. Too early, the LCD won’t be initialized, too late, plymouth would appear only in one screen, being duplicated after, and that may not be enough to fullfill our thirst of perfection !

A correct way of launching fbcp is to create a launcher script in the /etc/initramfs-tools/scripts/init-bottom directory. So let’s do it !

#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
/etc/fbcp &  
exit 0

Give this script the name of your choice, and make it executable.

Putting all together

Update initramfs (add -v to get more info)

sudo update-initramfs -u

Reboot, and tadaaa !

Notes :

  • The transition between splashscreen and bootsplash is quite rough in the demo video. In practice you may achieve a soft transition using a splashscreen derivated from your choosen plymouth theme.
  • You may get a smaller initramfs size by compressing your raw image. Might be usefull for larger resolutions.
  • Give money to Notro and Tasanakorn, they deserve it !

Sources :
https://github.com/notro/fbtft/wiki/Bootsplash
https://github.com/tasanakorn
http://forums.debian.net/viewtopic.php?f=16&t=73452

3 thoughts on “Earliest splashscreen / bootsplash / screen mirroring for raspberry !

  1. Hello,
    Tried you instructions to load the raw image in the FB during the boot using initramfs.
    It works, only… two copies of the image, each half in size, are shown instead to fill the upper half screen.

    I get the exact same result if I load the raw image manually after boot by first setting fbset -depth 32, but I get the correct image when I instead use fbset -dept 16 and then fill the FB.

    To solve my problem, I have tried to use the fbset -depth 16 command in the /etc/initramfs-tools/scripts/init-top/spi script, just before loading the raw image into the buffer, but this does not seem to work, as I still get the two smaller images as before.

    What am I missing?

Laisser un commentaire