GRUB - Pseudo-Graphical Mode and Fonts

For a long time I've been using a block of code I didn't understand from someone else's grub.cfg to get GRUB into its pseudo-graphical mode. GRUB defaults to the equivalent of an 80x25 terminal, but the pseudo-graphical modes allow higher resolutions (meaning more text on screen), user-defined fonts, and background images.

grub> loadfont $prefix/fonts/unicode.pf2  # this doesn't seem to be necessary?
grub> insmod all_video
grub> insmod gfxterm
grub> terminal_output gfxterm

My guess is that you don't have to specify the font because GRUB will load it automatically? Do make sure it's available though or this probably won't work ... In fact it's probably best you load the font explicitly.

To find out what video modes are available (and which one is being used):

grub> videoinfo
...
  0x117 1024 x  768 x 16 (2048)  Direct color, mask: 5/6/5/0  pos: 11/5/0/0
* 0x118 1024 x  768 x 32 (4096)  Direct color, mask: 8/8/8/8  pos: 16/8/0/24
  0x112  640 x  480 x 32 (2560)  Direct color, mask: 8/8/8/8  pos: 16/8/0/24
...
EDID version: 1.1
  Preferred mode: 1280x800
...

The one with the leading '*' is the currently chosen mode. Since I have to copy this by hand (GRUB doesn't have screen capture that I'm aware of), I've excised a great deal of the output. There was an intro, including information on the video drivers available and lots of other modes - none of which were 1280x800, presumably because GRUB doesn't support that even if the monitor prefers it. The output varies considerably from machine to machine. NOTE that the videoinfo command won't show you the available modes until you've loaded the all_video driver.

To change to another video mode:

grub> set gfxmode=800x600
grub> terminal_output console ; terminal_output gfxterm

Make sure the value you set is a valid one from the output of videoinfo. Just setting a new value isn't enough: you have to restart the graphical terminal by switching to another terminal mode and then back to gfxterm.

A useful feature of gfxterm is that it accepts multiple, comma-separated resolutions. Each will be tried in order until it finds a working mode: so try the 'good' modes first and make sure to have a good fallback:

set gfxmode=1920x1200,1920x1080,1024x768,800x600,640x480,auto

This is less useful at the command line where you can run videoinfo and see what's available, but it's a huge boon in scripts.

Fonts

To create and use different fonts, use the grub-mkfont command - I recommend you read man grub-mkfont. The command claims to be able to convert "common font file formats" although it doesn't appear to expand on what those might be. So I assumed that this included standard X fonts:

$ sudo apt-get update ; sudo apt-get install xfonts-terminus
...
$ dpkg -L xfonts-terminus | grep 8859-1.pcf | grep n_iso
/usr/share/fonts/X11/misc/ter-u32n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u14n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u28n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u24n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u18n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u20n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u22n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u12n_iso-8859-1.pcf.gz
/usr/share/fonts/X11/misc/ter-u16n_iso-8859-1.pcf.gz
$ grub-mkfont --output=terminus12.pf2 /usr/share/fonts/X11/misc/ter-u12n_iso-8859-1.pcf.gz
$ grub-mkfont --output=terminus16.pf2 /usr/share/fonts/X11/misc/ter-u16n_iso-8859-1.pcf.gz
$ grub-mkfont --output=terminus20.pf2 /usr/share/fonts/X11/misc/ter-u20n_iso-8859-1.pcf.gz
$ grub-mkfont --output=terminus24.pf2 /usr/share/fonts/X11/misc/ter-u24n_iso-8859-1.pcf.gz
$ grub-mkfont --output=terminus28.pf2 /usr/share/fonts/X11/misc/ter-u28n_iso-8859-1.pcf.gz
$ ls
terminus12.pf2  terminus20.pf2  terminus28.pf2
terminus16.pf2  terminus24.pf2  unicode.pf2

dpkg -L <package-name> lists all the files in the package. I filtered to find anything with my preferred code page (8859-1) and 'n' (indicating 'normal' rather than 'b' for 'bold'). Then convert the fonts. Since there was no output, I assumed it was succeeding. I copied the resulting PF2 files onto the GRUB USB stick under /boot/grub/fonts/ (the location isn't essential given that you can specify a full path to load the font files, but loadfont assumes this is the default location). Then, after booting GRUB:

grub> loadfont $prefix/fonts/terminus20.pf2
grub> insmod all_video
grub> insmod gfxterm
grub> terminal_output gfxterm

And I have a different font. I've always been a fan of the Terminus fonts, so it was nice to be able to use them here.

Changing fonts (as opposed to setting the initial font) turns out to have the same problem as changing resolutions (above). You have to give the terminal mode a kick in the ass to get its attention:

grub> loadfont $prefix/fonts/terminus12.pf2 ; terminal_output console ; terminal_output gfxterm

Font Warning / Follow-up

The Terminus fonts converted perfectly, but several other attempts have resulted in fonts that ... work, but not well. Some conversions fail entirely. The "Artwiz Kates" (pcf) font converted without complaint, but has underlining under all words, and when I converted Droid Sans Mono Slashed I ended up with a very similar problem - except at the 24 size, at which point I got some cropping at the bottom. So apparently converting fonts is a crapshoot.

Another problem with converting fonts is that most of them don't have line-draw characters, so if you use them in combination with GRUB's default menu system the box around the menu looks really horrible. This is why unicode.pf2 is the default ...

Bibliography