Super fast Linux splashscreen

Bobsleigh race picture

Here’s a simple trick that I recently rediscovered when I worked on a boot time reduction project for a customer. It’s not rocket science, but you may not be aware of it.

Our customer was using fbv to display its logo right after the system booted. This is a way to show that the system is available while you’re starting the system’s main application:

fbv -d 1 /root/logo.bmp > /dev/null 2>&1

With Grabserial and using simple instrumentation with messages issued on the serial console before and after running the command, we found that this command was taking 878 ms to execute. The customer’s system had an AT91SAM9263 ARM SOC from Atmel, running at 200 MHz.

Even if fbv is a simple program (22 KB on ARM, compiled with shared libraries), decoding the logo image is still expensive. Here’s a way to get this compute cost out of your boot sequence. All you have to do is display your logo on your framebuffer, and then capture the framebuffer contents in a file:

fbv -d 1 /root/logo.bmp
cp /dev/fb0 /root/logo.fb

The new file is now a little bigger, 230400 bytes instead of 76990. However, displaying your boot logo can now be done by a simple copy:

dd if=/root/logo.fb of=/dev/fb0 bs=230400 count=1 > /dev/null 2>&1

This command now runs in only 54 ms. That’s only 6% of the initial execution time! The advantage of this approach is that it works with any kind of framebuffer pixel format, as long as you have at least one program that knows how to write to your own framebuffer.

Note that the dd command was used to read and write the logo in one shot, rather than copying in multiple chunks. We found that the equivalent cp and cat commands were slightly slower. Of course, the benchmark results will vary from one system to another. Our customer had heavily optimized their NOR flash access time. If you run this on a very slow storage device, using a much faster CPU, the time to display the logo may be several impacted by the time taken to read a bigger file from slower storage.

To get even better performance, another trick is to compress the framebuffer contents with LZO (supported by BusyBox), which is very fast at decompressing, and requires very little memory to run:

lzop -9 /root/logo.fb

The new /root/logo.fb.lzop file is now only 2987 bytes big. Of course, the compression rate will depend on your logo image. In our case, the splashscreen contains mostly white space and a simple monochrome company logo. The new command to put in your startup scripts is now:

lzopcat /root/logo.fb.lzo > /dev/fb0

The execution time is now just 52.5 ms! With a faster CPU, the time reduction would have been even bigger.

The ultimate trick for having a real and possibly animated splashscreen would be to implement your own C program, directly writing to the framebuffer memory in mmap() mode. Here’s a nice tutorial showing how easy it can be.

Author: Michael Opdenacker

Michael Opdenacker is the founder of Bootlin. He is best known for all the free embedded Linux and kernel training materials that he created together with Thomas Petazzoni. He is always looking for ways to increase performance, reduce size and boot time, and to maximize Linux' world domination. More details...

17 thoughts on “Super fast Linux splashscreen”

  1. Have you inquired into the source of the original slowness of fbv .bmp display: is it fbv or the BMP image format? (If it’s the former, maybe we should try to improve it too ; if it’s the latter, well… you have already given some solutions but maybe using a different format would help too.)

    1. Hi Rodolphe,

      No, I haven’t investigated the exact cause of fbv’s slowness. Looking at the code, I just suspected that the CPU intensive parts lied in image format decoding. However, fbv could have its own issues too.



  2. Hi Michael
    I have tried this
    fbv -d 1 /root/logo.bmp
    cp /dev/fb0 /root/logo.fb

    the new logo.fb is 4.3 mb big while the bmp image I used was 2kb. I took another bmp image and again it was 4.3 mb. Am I missing something?

  3. Hi Michael,
    This is nice info about frame buffer. I need same but slight change. I tried fbv – on ARM board – saying command not found and not able to find the screen change while using /dev/fb0. i am looking for bootup-logo screen change. i am using frame buffer and mmap functions from user-space program but unable to.

    i tried with some pixel values we send to the /dev/fb0 then i am getting some rectangle box with some color — as given value.

    Now i need to change that program with jpg image. can you help in this.


    Viswanath K

      1. Thank you for the reply. In my build, those packages are having. so i am tried to write a small frame-buffer application program, it is working with bmp files. Not able to load the jpeg , i think jpeg decoder or an fbi(image viewer)is required. There is a link libexif and fbida – but not able to load in board(AM335x-sitara kit).


        Viswanath K

  4. Hi Michael, I came across your blog while I was researching ways to hide splash screens and logs that Linux is spewing while it’s booting up. I was thinking to display company logo from a frame buffer, keep displaying while the system boots and then switch to the normal frame buffer when the application starts.

    Can you give me some pointers and ideas if this is possible to do?

    I’m using x86-64 SBC and Ubuntu 14.04 as embdedded distribution.

    Regards, Dragan

    1. Android is a bit out of topic, here. You could hack the way it boots and display a custom spashscreen, but it’s probably best to use Android’s own mechanisms (sorry, I don’t have them in mind… you’ll have to look them up).

  5. Thanks for sharing. Very Helpful.
    How can we show animated splash or video splash within 1 sec requirement?


  6. Thanks for sharing this tricks.
    Will be very helpful.

    I’m using buildroot 2016.08.01 to generate a rootfs for the Freescale iMX6 SoloX Sabre SD board and I don’t find where to get lzopcat.

    I found lzop in the buildroot package list and in the busybox config but no way to find lzopcat.

    A google search didn’t give me the solution.

    Where can I fint this lzopcat utility ?

    1. Just try a “make install” after selecting lzop in the configuration. You will find a usr/bin/lzopcat file. At least I checked that with the latest git sources.

      You may also try with “lzop -c”, which should be equivalent to lzopcat.


Leave a Reply