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.

About Michael Opdenacker

Michael Opdenacker is the founder of Free Electrons. 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...
This entry was posted in Technical and tagged , , , , . Bookmark the permalink.

10 Responses to Super fast Linux splashscreen

  1. Bharat Gohil says:

    Hi ,

    Nice!Found useful.
    Can we display logo from bootloader?

    Regards,
    Bharat gohil

  2. Rodolphe Ortalo says:

    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.)

    • 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.

      Thanks,

      Michael.

  3. mrigendra says:

    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?

  4. Viswa says:

    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.

    regards,

    Viswanath K

    • I’d suggest to fix the “command not found” error first. How can this work if the shell can’t find fbv?

      • Viswa says:

        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).

        regards,

        Viswanath K

Leave a Reply

Your email address will not be published. Required fields are marked *