SDB:KIWI Cookbook Splash Screen
All of KIWI edit
Custom GRUB and boot splash images
This example outlines how to customize the splash screens during boot of SUSE distributions using the Bootsplash project (all distributions at the time of this writing).
Customizing the GRUB and boot splash images
Prep Time:
- 20 min + the time to create your graphic images
Cook Time:
- 20 min
Ingredients:
- a running openSUSE 11.1 or 11.2 system
- an openSUSE 11.1 or 11.2 repository
- installed recent release of the KIWI toolset (at least version 3.25)
- installed kiwi-doc package
- background image
- logo image in Scalable Vector Graphics format
- installed PHP interpreter
- installed GraphicsMagick
- installed Inkscape
- about 1 GB free disk space
Preliminaries
By default the branding of SUSE distributions is controlled by the packages bootsplash-branding* and gfxboot-branding-. The gfxboot-branding- package contains the information for the images displayed behind the GRUB menu, i.e. the menu where you select your kernel. The bootsplash-branding* contains the information about the image displayed during the actual boot process.
Customizing the boot splash and GRUB menu images requires the duplication of the directory structures of the bootsplash-branding* and gfxboot-branding- packages. To see the structures run the following commands:
rpm -qa | grep branding
This produces a list of packages. From this list you can find the exact name of the packages we are interested in. then use
rpm -ql <PACKAGE_NAME>
to see the list of directories and files provided by the package. Yes, the list for both packages is rather long, but fear not we will use a script to generate the images required for the boot splash screen. For the GRUB menu there is only one image required.
Before we get going with the image creation etc. lets create a working directory.
Customizing the boot splash images
Images for the boot splash screen
The script we will use later to generate the appropriate directory tree for the boot splash images expects PNG images for the background and SVG images for the logo with specific names to be present in the execution directory. The expected file names are as follows:
- background.png - The image background to be displayed during silent boot
- background-verbose.png - The image background to be displayed during verbose boot
- logo.svg - The logo to be used during silent boot
- logov.svg - The logo to be used during verbose boot
You may modify the script to change these names if you so desire. In this example we will stick to the names presented above.
In the working directory fire up your favorite graphics creation tool and create the background and logo images of your choice. Keep in ming the disclaimer at the beginning of the recipe. Thus you cannot go too crazy. If you already have images just copy them into the working directory with the appropriate names. If you just want to try this recipe without having to create images you may use the images below.
As you can see you do not have to have artistic skills for this.
Bootsplash directory structure generation
Create a script (bootsplash.php) with the following content in the working directory.
#!/usr/bin/php <?php //depends on graphicsmagic and rsvg $distro = "openSUSE 11.2"; $themename = "myTheme"; $themepath = "./bootsplash/$themename"; $imagepath = "/etc/bootsplash/themes/$themename/images"; //resolution, jpeg export quality pairs $resolutions = array("640x480"=>"95", "800x600"=>"95", "1024x600"=>"94", "1024x768"=>"94", "1152x768"=>"94", "1152x864"=>"93", "1280x768"=>"93", "1366x768"=>"93", "1280x800"=>"93", "1280x854"=>"93", "1280x960"=>"92", "1280x1024"=>"92", "1400x1050"=>"91", "1440x900"=>"91", "1600x1024"=>"90", "1600x1200"=>"89", "1680x1050"=>"89", "1920x1200"=>"80", "3200x1200"=>"70"); /* $resolutions = array("800x600"=>"95"); */ //create dirs if (!is_dir($themepath)) { //print "removing old theme $themename\n\n"; //exec("rm -rf ./theme/$themename"); mkdir ("./bootsplash"); mkdir ("$themepath"); mkdir ("$themepath/config"); mkdir ("$themepath/images"); } //create logos if (!is_dir('./temp')) { mkdir ("./temp"); } $cmd = "inkscape -w 180 -e ./temp/logo.png logo.svg"; //silent logo exec($cmd); $cmd = "inkscape -w 90 -e ./temp/logov.png logo.svg"; //verbose logo exec($cmd); $cmd = "gm convert -comment \"id logo deltabg stop\" ./temp/logo.png ./temp/logo.png ./temp/logo.mng"; exec($cmd); $cmd = "gm convert -colorspace gray -comment \"id logov deltabg stop\" ./temp/logov.png ./temp/logov.png ./temp/logov.mng"; exec($cmd); #exec("/usr/local/bin/convert ./building-blocks/logo.png $themepath/images/logo.mng"); copy("./temp/logo.mng", "$themepath/images/logo.mng"); copy("./temp/logov.mng", "$themepath/images/logov.mng"); while (list($res,$q) = each($resolutions)) { //scale backgrounds print "creating $res resolution images\n"; $in = "./background.png"; $inverb = "./background-verbose.png"; $silent = "$themepath/images/silent-$res.jpg"; $verbose = "$themepath/images/bootsplash-$res.jpg"; $cmd = "gm convert $in -geometry $res\! -quality $q -interlace None -colorspace YCbCr "; $cmd .= " -sampling-factor 2x2 $silent"; exec($cmd); $cmd = "gm convert $inverb -geometry $res\! -quality $q -interlace None -colorspace YCbCr "; $cmd .= " -sampling-factor 2x2 $verbose"; #$cmd = "gm convert $in -colorspace gray -geometry $res\! -quality $q -interlace None "; #$cmd .= "-colorspace YCbCr -sampling-factor 2x2 $verbose"; exec($cmd); //generate config files print "Generating config file for $res\n"; $fp = fopen("$themepath/config/bootsplash-$res.cfg", "w"); fwrite($fp, "# This is a bootsplash configuration file for\n"); fwrite($fp, "# $distro, resolution $res.\n"); fwrite($fp, "#\n"); fwrite($fp, "# See www.bootsplash.org for more information.\n"); fwrite($fp, "# created by SUSE Image Builder\n"); fwrite($fp, "#\n"); fwrite($fp, "version=3\n"); //config file version fwrite($fp, "state=1\n"); //picture is diplayed fwrite($fp, "progress_enable=0\n"); //no progress fwrite($fp, "overpaintok=1\n"); //no clue what this is fwrite($fp, "\n\n"); //colors fwrite($fp, "fgcolor=7\n"); fwrite($fp, "bgcolor=0\n\n"); //text window frame ereg("([0-9]+)x([0-9]+)", $res, $dimensions); $x = $dimensions[1]; $y = $dimensions[2]; $tx = 20; $ty = 60; $tw = $x - $tx - 10; $th = $y - $ty; fwrite($fp, "tx=$tx\n"); fwrite($fp, "ty=$ty\n"); fwrite($fp, "tw=$tw\n"); fwrite($fp, "th=$th\n"); //background fwrite($fp, "\n\njpeg=$imagepath/bootsplash-$res.jpg\n"); fwrite($fp, "silentjpeg=$imagepath/silent-$res.jpg\n"); fwrite($fp, "\n\n"); $lx = round($x/2); $ly = round($y/2)-20; fwrite($fp, "mnganim logo $imagepath/logo.mng initframe logo silent center $lx $ly\n"); //overlay title (verbose) $vlx = 2; $vly = 2; fwrite($fp, "mnganim logov $imagepath/logov.mng initframe logov origin 0 $vlx $vly\n"); //animation triggers fwrite($fp, "trigger \"isdown\" quit\n"); fwrite($fp, "trigger \"rlreached 5\" toverbose\n"); fwrite($fp, "trigger \"rlchange 0\" tosilent\n"); fwrite($fp, "trigger \"rlchange 6\" tosilent\n"); $verticalpcnt = 0.8; $width = 160; //width of the progress bar $voffset = 30; //vertical offset from the title (defined by verticalpcnt above) $x1 = $lx - round($width/2) - 4; $x2 = $x1 + $width; //$y1 = round($verticalpcnt*$y); $y1 = round($ly+$voffset); $y2 = $y1+1; //let's try a 2 pixel line fwrite($fp, "\n\n"); fwrite($fp, "progress_enable=1\n"); //enable progress fwrite($fp, "box silent noover $x1 $y1 $x2 $y2 #ffffff10\n"); //progress background $wl = "box silent inter " . $x1 . " " . ($y1 - 1) . " " . $x1 . " " . ($y1 + 1) . " #ffffff80\n"; fwrite($fp, $wl); //starting point ... $wl = "box silent " . $x1 . " " . ($y1 - 1) . " " . $x2 . " " . ($y2 + 1) . " #ffffff80\n"; fwrite($fp, $wl); //..iterated to this fclose($fp); } ?>
Thanks Jakub for the script.
Then execute the script
Once the script is complete you will have a bootsplash directory in your working directory. This contains everything you need to customize the boot splash screen.
The image tree generation script
A few notes about the image tree creation script above.
- The value of the $themename variable is arbitrary, thus you may use something more creative than myTheme. This value will be used later in the config.xml file. The requirement is that this name and the name used in the config.xml file match, thus watch out for typos.
- The numbers in the dictionary or hash after the given resolution indicate the quality for image conversion purposes. Higher quality numbers imply larger file sizes, thus you are more likely to run up against the limitations of the bootsplash system. A rough estimate is that none of the files should exceed 70K. You can influence the size of the images by varying these numbers. This is not an exact science and trial and error is inevitable.
These are about the only changes you should have to make to the script. The script also generate the configuration files and you can play with these to your hearts content until you get color positioning etc. just the way you like it.
Tackling the GRUB background
The back ground images
Fire up your favorite image editing tool and create the background images you would like to use for the GRUB menu. One file should be named back.jpg and the other pback.jpg. Using these file names will allow you to avoid hacking the configuration files. If you have the images already copy them to the working directory with these names. If you just want to follow along and get on with the example feel free to use the prepared images below.
Setting up the directory structure
With the images created we need to set up the directory structure. The images for the GRUB background need to be located in /usr/share/gfxboot/themes/THEME_NAME/{data-boot,data-install}. In addition to the images we need configuration files and a link to a Makefile.
Rather than creating all the infrastructure from scratch it is easier to piggy back on existing work. Install the gfx-devel package to use pre-configured configuration files etc.
Once installed you can copy one of the derived themes and give it your own name.
The name of your theme (myTHeme) must match the name you used in the $themename variable in the bootsplash.php script above. Next replace the images with your own.
Feel free to explore the various configuration files and modify them as you see fit. The Gfxboot page provides all the gory details you might be interested in.
Integrating the customization
With the image creation and setup for the customization out of the way we can now proceed to integrate our customization into a Kiwi image build. For this example we will use the live-iso example provided with the kiwi-doc package.
- Copy the example configuration to the working directory.
- Create the directory structure for the bootsplash theme and move or copy your theme into it.
- Create the directory structure for the gfxboot theme and move or copy the theme into it.
- Package the themes up into a tarball and move or copy the tarball into the Kiwi configuration tree.
- Edit the config.xml file with your favorite editor
- Replace the repository definition if you do not wish to pull the packages over the Internet
- Within the <preferences> element add a child element with the name <boot-theme> and the value of your theme name. In this example the configuration entry has the following form:
<boot-theme>myTheme</boot-theme>
- Within the <packages> element add a child element with the name <archive>, set the name attribute value to the name of the tarball we created previously and set the bootinclude to true. n this example the configuration entry has the following form:
<archive name="myTheme.tgz" bootinclude="true"/>
- Add the gfx-devel package as a packe to include and include it in the boot image as follows:
<package name="gfxboot-devel" bootinclude="true" bootdelete="true"/>
- Remove the lines containing the SUSE branding
With the changes applied the <packages> element should look similar to the one shown below.
<packages type="image" patternType="plusRecommended" patternPackageType="plusRecommended"> <archive name="myTheme.tgz" bootinclude="true"/> <package name="gfxboot-devel" bootinclude="true" bootdelete="true"/> <package name="kernel-default"/> <package name="bootsplash"/> <package name="ifplugd"/> <package name="vim"/> <opensusePattern name="default"/> <opensusePattern name="kde4"/> </packages>
This completes the integration of the custom images. What's left is to build and test the image.
Once the ISO image has been built by Kiwi you can test it with qemu as follows:
qemu-kvm -cdrom=/tmp/customBoot_image/IMAGE_NAME.iso