GRUB splash image how-(not)-to for my Jnode PC

This actually has very little to do with Jnode, really, but I thought other Jnode folks might benefit, so here goes!

For no good reason today, I decided to replace the stock GNU GRUB Legacy (0.97) on my Jnode system with a version that supports a splashimage (like the versions shipped with Fedora, RedHat, or Debian Linux) and wrote up what I went through to help others who might be struck with the same insane impulse!

Warning: What follows is not for the faint-of-heart!

If you aren't sure what GRUB splash images are, you can learn plenty about them here:

For my splash image, I chose one of the "official" GRUB logos mentioned on the GRUB home page at
However, the images there are too small to make good, clear splash images from.

You can get high resolution originals from the original artist at Karol Krenski's home site (in the "Logos" section):

I chose grub.png, since I look more like the crazy bearded guy than a chef, and I like that the crazy guy is actually looking into the disk, rather than just standing on it.

I found the best way to create a clean 14-color splash image from grub.png was to:
1. gimp jnode/gui/images/background.png

2. Use the eyedropper (Tools > Color Picker) to sample the blue color (#4682b4) as the foreground color in GIMP.

3. File > Open grub.png

4. Use the bucket fill (Tools > Paint > Bucket Fill) to replace the transparent area around the logo with the Jnode desktop blue color.

5. Squish the image down to 640x480 splash image size with Image > Scale > 640 x 480, Interpolation: Cubic

6. Manually "posterize" the image with Image > Mode > Indexed, 8 colors, No dithering, No transparent dithering
Note: I chose 8 colors to force the hands and hair to one solid color and avoid the "banding" effect you normally get with RGB images cut down to a small indexed range, or when you use Gimp's included Posterize function.

7. Convert back to RGB with Image > Mode > RGB (as setup for the next step)

8. Convert down to the final 14-color indexed splash image format with Image > Mode > Indexed, 14 colors, No dithering, No transparent dithering

9. It's art, not science. So, you might have to play around with Gimp until you are happy with final output.

10. Save As an actual splash image file with File > Save As, grublogo.xpm and exit Gimp.

11. Compress the grublogo.xpm with gzip -9v grublogo.xpm

Now you have a "boot-ready" GRUB logo... all you need is a GRUB which can show it!

DISCLAIMER (I hate em, but widespread lack of common sense forces us to endure them.)
The instructions below are recreated from memory from my build on Fedora 8. Everyone not building on my machine at my house will have to adapt accordingly! Your mileage will vary. !!! Backup anything you care about first !!! These steps can destroy your all of your filesystems, mangle your partition tables, and render all OSes on a system unbootable in a variety of fun and interesting ways. Use at your own risk! If you break it, you own both halves. I am not responsible, in any way, for anything you choose to do from reading this. Do not run any step you do not fully understand the consequences of. You have been warned.

Still here?

Put your priest on danger money, and get to work in a temporary directory of your own choosing, on your buildbox:
1. Import Yoshinori Okuji's GPG key (if needed):
buildbox:~/work/$ gpg --recv-keys FE06BDEF

2. Download the GRUB Legacy GPG signature file:
buildbox:~/work/$ wget

3. Download grub-0.97-19.src.rpm from any Fedora Project mirror, such as:
buildbox:~/work/$ wget

4. Extract the CPIO archive from the RPM:
buildbox:~/work/$ rpm2cpio grub-0.97-19.src.rpm > grub-0.97-19.src.cpio

5. Extract GRUB from the CPIO archive
buildbox:~/work/$ cpio -i -I grub-0.97-19.src.cpio

6. Use gpg to verify the GRUB source from the RPM/CPIO archive:
buildbox:~/work/$ gpg grub-0.97.tar.gz.sig

7. Unpack Grub Legacy:
buildbox:~/work/$ tar zxvf grub-0.97.tar.gz

8. Move into the Grub source tree:
buildbox:~/work/$ cd grub-0.97

9. Patch Grub Legacy to include splashimage support:
buildbox:~/work/grub-0.97$ patch -p1 < ../grub-fedora-8.patch

11. Examine the grub.spec to see Fedora 8 build steps, compiler flags, and overall process :
buildbox:~/work/grub-0.97$ more ../grub.spec
Note: I wanted to make sure I understood how Fedora was building it, including general steps, specific flags, etc.

12. Setup CFLAGS for build (from grub.spec)
buildbox:~/work/grub-0.97$ CFLAGS="-Os -g -fno-strict-aliasing -Wall -Werror -Wno-shadow -Wno-unused -static";export CFLAGS

13. Update autoconf files
buildbox:~/work/grub-0.97$ autoupdate -v

14. Run autoconf to build configure script.
buildbox:~/work/grub-0.97$ autoconf

15. Run configure script:
buildbox:~/work/grub-0.97$ ./configure --disable-auto-linux-mem-opt

16. Make the binaries
buildbox:~/work/grub-0.97$ make

17. Check them
buildbox:~/work/grub-0.97$ make check
Note: ffs_stage1_5 and ufs_stage1_5 failed here. All I wanted to see was e2fs_stage1_5 and fat_stage1_5 pass.

18. Cut-and-paste this (very cheesy) script to update your Jnode source tree.
NOTE: This is what we call "worst-practice" shell scripting. Do not emulate this in the real world or people will laugh at you and call you names.

mkdir -p $TARGET
cp stage1/stage1 $TARGET
cp stage2/e2fs_stage1_5 $TARGET
cp stage2/fat_stage1_5 $TARGET
cp stage2/ffs_stage1_5 $TARGET
cp stage2/iso9660_stage1_5 $TARGET
cp stage2/jfs_stage1_5 $TARGET
cp stage2/minix_stage1_5 $TARGET
cp stage2/reiserfs_stage1_5 $TARGET
cp stage2/ufs2_stage1_5 $TARGET
cp stage2/vstafs_stage1_5 $TARGET
cp stage2/xfs_stage1_5 $TARGET
cp stage2/stage2 $TARGET
tar cvf grub-0.97-i386-pc.tar grub-0.97-i386-pc
gzip -9v grub-0.97-i386-pc.tar

cp grub-0.97-i386-pc.tar.gz $TARGET
cp stage1/stage1 $TARGET/grub.s1
cp stage2/fat_stage1_5 $TARGET/fat.s15
cp stage2/stage2 $TARGET/grub.s2
cp stage2/stage2_eltorito $TARGET/eltorito.s2

19. Run the script to update your Jnode source tree:
buildbox:~/work/grub-0.97$ sh ./

NOTE: The next steps were done on a separate machine with an EXT2 disk, not on my buildbox.
Your steps will vary for VMware, USB, or FAT filesystem boots.

20. Copy the new Grub Legacy with splashimage support to your Jnode box (your steps will vary for VMware or USB):
For this, I booted my Jnode PC with a Fedora Core 5 rescue disk (originally used to create the appropriate EXT2 filesystem with), enabled the rescue mode networking, and copied the GRUB pieces into place manually.
FC5 Rescue# mkdir /mnt/hda
FC5 Rescue# mount /dev/hda1 /mnt/hda
FC5 Rescue# cd /mnt/hda/boot/grub
FC5 Rescue:/mnt/hda/boot/grub# scp buildbox:work/grub-0.97/grub-0.97-i386-pc.tar.gz .
FC5 Rescue:/mnt/hda/boot/grub# tar zxvf grub-0.97-i386-pc.tar.gz
FC5 Rescue:/mnt/hda/boot/grub# mv grub-0.97-i386-pc/boot/grub/* .
FC5 Rescue:/mnt/hda/boot/grub# rm -r grub-0.97-i386-pc
FC5 Rescue:/mnt/hda/boot/grub# scp buildbox:work/grub-0.97/grub/grub . # copy over the statically compiled grub shell, for the next step.

21. Setup your GRUB menu:
FC5 Rescue:/mnt/hda/boot/grub# ln menu.lst grub.conf # Fedora sources uses grub.conf by default instead of menu.lst. I just use both.
FC5 Rescue:/mnt/hda/boot/grub# scp buildbox:grub/grublogo.xpm.gz .
FC5 Rescue:/mnt/hda/boot/grub# vi menu.lst # or grub.conf
# Insert this line somewhere close the top of menu.lst, after the comments, and before your first Title block:

22. Install Grub to the drive (Here be hard-drive eatin' dragons!):
FC5 Rescue:mnt/hda/boot/grub# ./grub
grub> root (hd0,0)
grub> setup (hd0)
grub> quit

23. Cleanup and reboot
FC5 Rescue:/mnt/hda/boot/grub# cd / # to get out of the mount point
FC5 Rescue# umount /mnt/hda
FC5 Rescue# exit # to reboot from rescue image

24. Remove the CD, and let the system boot to your new splashimage version of GRUB.
Be sure to actually boot Jnode with it to verify that all GRUB stages work!

Now, wasn't that easy?

Yes, I would love to see any comments, criticisms, corrections, fixes, simplifications, streamlining, or any other sort of improvement to this process.
I just wanted to get something out there to add a bit of eye-candy to Jnode systems for Jnode hackers to wow their friends with, just that extra little bit more.

Robert "Exile In Paradise" Murphey