Translate

Image of Modern Operating Systems (3rd Edition)
Image of Beginning Google Maps API 3
Image of Linux Kernel Development (3rd Edition)
Image of Advanced Programming in the UNIX Environment, Second Edition (Addison-Wesley Professional Computing Series)

Boot Fedora 14 Using UEFI and GRUB2

In a recent post I demonstrated how to UEFI-install Fedora 14. This installed a modified version of Legacy GRUB which was built to execute on EFI platforms. In this post I show you how to install an EFI version of GRUB2 which can be used to boot Fedora 14 instead of using the version of Legacy GRUB that comes with Fedora 14.

The version of GRUB2 that I used is 1.99-Beta0. Use bzr to obtain the current version from the GRUB repo. You may also need to install the autoconf and automake packages as they are required to build GRUB2. If you want to build the grub-mkfont utility, required if you want to create fonts for GRUB2, you also need the freetype-devel package.

$ bzr branch http://bzr.savannah.gnu.org/r/grub/trunk/grub
$ cd grub
$ ./autogen.sh
$ ./configure –with-platform=efi –enable-grub-mkfont
…..
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need devmapper library)
With memory debugging: No
efiemu runtime: No (not available on efi)
grub-mkfont: Yes
*******************************************************
$ make

The next few scripts assume that you are going to place the required GRUB2 files in the /boot/efi/EFI/grub2 subdirectory. You will need to change these scripts if you want to put GRUB2 somewhere else. So long as GRUB2 is on the ESP (EFI System Partition) which is mounted on /boot/efi it does not really matter where it is located.

Invoke this script from ../grub/grub-core to build the final GRUB2 image (grub2.efi) and install the image plus all the loadable modules and their associated .lst files.

#!/bin/bash

../grub-mkimage -O x86_64-efi -d . -o grub2.efi -p "" \
     boot normal part_gpt fat ext2 lvm configfile lspci \
     ls reboot datetime loadenv search help

cp grub2.efi *.mod *.lst /boot/efi/EFI/grub2/


You will also need to create a GRUB2 configuration file called grub.cfg in the /boot/efi/EFI/grub2 subdirectory. Here is a simple configuration file. It assumes that your GNU/Linux partition is the second partition on the first disk. Change this if necessary. The kernel version will probably need to be changed to match your particular kernel.

timeout=30
default=0
set color_normal=white/black
set color_highlight=yellow/black

menuentry "Fedora 14 (2.6.35.6-48.fc14.x86_64)" {
   set root='(hd0,gpt2)'
   linux /vmlinuz-2.6.35.6-48.fc14.x86_64 ro root=/dev/mapper/vg_ultra-lv_root rd_LVM_LV=vg_ultra/lv_root rd_LVM_LV=vg_ultra/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYTABLE=us rhgb quiet
   initrd /initramfs-2.6.35.6-48.fc14.x86_64.img
}

Note the change in syntax from GRUB v1.97 for the root variable. The syntax was (hd0, 2); now it is (hd0, gpt2).

You should now be able to reboot your system and use your EFI boot manager or EFI shell to invoke \efi\grub2\grub2.efi and then boot into Fedora 14 via GRUB2.

With GRUB2 you can optionally display a background image behind the menu and change the font used to display text. For this, you need to install the gfxterm graphical output terminal.

To display text in gfxterm, at least one font must be loaded so that suitable glyphs are available to be painted onto the screen. GRUB2 uses a custom bitmap font format called PFF2. The format was designed to provide a bitmap font format that is simple to use, compact, and cleanly supports Unicode. The standard file extension for PFF2 font files is .pf2. However, no pre-built PFF2 files are supplied with the GRUB2 sources. Instead you have to source a suitable Unicode font file and use the grub-mkfont utility to convert the source format file into the PFF2 format.

A GRUB2 font must include at least the ASCII character set, since most GRUB2 messages are encoded in ASCII and should also include a number of other glyphs such as ISO 8859-1 (Latin-1), Latin Extended A, Latin Extended B, arrows, box and block characters. All fonts must use Unicode codes. Currently only monochrome bitmap fonts are supported.

A good source of suitable glyphs for GRUB2 are the GNU Unifont glyphs. These are available as BCD (Bitmap Distribution Format), PCF (Portable Compiled Format) and TTF (True Type Format) files. This particular font is included as the xfonts-unifont package in the Debian and Ubuntu distributions but not in Fedora.

The grub-mkfont utility supports every font format that the freetype library supports including PCF, BDF and TTF. Note that bitmap font formats like PCF and BDF are more suitable for use with GRUB2 than outline fonts like TTF.

$ ./grub-mkfont –help
Usage: ./grub-mkfont [OPTIONS] FONT_FILES

Options:
-o, –output=FILE_NAME set output file name
–ascii-bitmaps save only the ASCII bitmaps
–width-spec create width summary file
-i, –index=N set face index
-r, –range=A-B[,C-D] set font range
-n, –name=S set font family name
-s, –size=N set font size
-d, –desc=N set font descent
-c, –asce=N set font ascent
-b, –bold convert to bold font
-a, –force-autohint force autohint
–no-hinting disable hinting
–no-bitmap ignore bitmap strikes when loading
-h, –help display this message and exit
-V, –version print version information and exit
-v, –verbose print verbose messages


Here are some examples of how to use grub-mkfont to convert glyphs from unifont.bdf.gz to PPF2 format:

# create ASCII .pf2 file
$ grub-mkfont –output=ascii.pf2 –range=0×0-0x7f unifont.bdf.gz

# create ASCII, Latin-1, Latin A, Latin B, arrows, box and block .pf2 file
$ grub-mkfont –output=myfont.pf2 –range=0×0000-0×0241,0×2190-0x21FF,0×2500-0x259f unifont.bdf.gz

Loading a font into GRUB2 is a two stage operation:

# load font module
insmod font

# load font file
loadfont /boot/grub/unifont.pf2

Internally, text strings appear to be stored as C character strings. A paint_char() routine is used to “paint” a glyph representing a specific character onto the screen via a simple look-up table. I see no evidence that this code currently supports multibyte or wide character strings.

To display a background image, the image must first, if necessary, be converted into one of the image formats currently supported by GRUB2. These are JPG, TGA and PNG. See ../grub/grub-core/video/readers/*.c for more information. A suitable image size is 640 x 480 or larger. If necessary, you can use the background_image -m stretch mode option to scale an image to fill the whole screen. The help text for background_image also shows a normal mode but from checking the GRUB2 source code, I see this is not implemented.

A number of operations are necessary to display a background image:

# load image file reading module
insmod tga

# set use_bg variable to true
use_bg=true

# call background_image command with pathname of image to load
background_image /efi/grub2/image/fedora14.tga

Here is an example GRUB2 configuration file which displays a background image ferora14.tga and uses fonts from myfont.pf2.

timeout=30
default=0

if loadfont /efi/grub2/font/myfont.pf2
then
   set gfxmode="1024x768x32"
   set gfxpayload=keep
   insmod tga
   insmod gfxterm
   insmod efi_gop
   terminal_output gfxterm
   terminal gfxterm
   use_bg=true
   background_image /efi/grub2/image/fedora14.tga
fi

set color_normal=white/black
set color_highlight=yellow/black

menuentry "Fedora 14 (2.6.35.6-48.fc14.x86_64)" {
   set root='(hd0,gpt2)'
   linux /vmlinuz-2.6.35.6-48.fc14.x86_64 ro root=/dev/mapper/vg_ultra-lv_root rd_LVM_LV=vg_ultra/lv_root rd_LVM_LV=vg_ultra/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYTABLE=us rhgb quiet
    initrd /initramfs-2.6.35.6-48.fc14.x86_64.img
}
  
menuentry "Fedora 14 (2.6.35.6-45.fc14.x86_64)" {
   set root='(hd0,gpt2)'
   linux /vmlinuz-2.6.35.6-45.fc14.x86_64 ro root=/dev/mapper/vg_ultra-lv_root rd_LVM_LV=vg_ultra/lv_root rd_LVM_LV=vg_ultra/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYTABLE=us rhgb quiet nolapic
   initrd /initramfs-2.6.35.6-45.fc14.x86_64.img
}

menuentry "Reboot" {
   reboot
}

If you want to experiment with GRUB2 syntax in an emulated environment, you can build an emulator called grub-emu. It can be built in a number of configurations with curses being the default configuration.

Here is how to build the SDL-enabled version of the emulator on Fedora 14. You need to have the ncurses-devel,usb-devel and SDL-devel packages installed.

./configure –with-platform=emu –enable-grub-emu-sdl –enable-grub-emu-usb
cd grub-core
cp grub-emu *.mod *.lst /boot/efi/EFI/grub-emu
cd /boot/efi/EFI/grub-emu
./grub-emu -d /boot/efi/EFI/grub-emu/


How SDL-enabled grub-emu works is interesting. An SDL-enabled window will only appear if your grub.cfg contains a graphical terminal, otherwise the emulator occupies your current terminal window.

You cannot interact with the graphics window directly. If it has keyboard focus nothing will happen. You have to enter the commands into the terminal window used to invoke grub-emu. It took me a while to figure it out as it is not documented anywhere. Looking at the source code, the GRUB2 developers took a shortcut (or, as some would say, a pragmatic design decision) by leaving the curses keyboard input code in place in ../kern/emu/console.c and just changing the display code to use ../video/emu/sdl.c

Here is a screenshot of grub-emu at the grub command prompt

grub2 emulator 1

and here is a screenshot of grub-emu executing the videotest command.

grub2 emulator 2

If you have problems with keyboard input when using the emulator, try commenting out the line wtimeout(stdscr, 100); in the grub_ncurses_getkey function in ../kern/emu/console.c. On fast platforms this modification will almost certainly be required. You can exit grub-emu using the emulator-specific exit command but it is likely that your terminal window will be messed up as a result. Typing stty sane a couple of times in the terminal windows fixes the problem. The problem is due to the fact that grub_exit() does not call grub_console_fini() to terminate curses (and hence restore the original terminal capabilities) before exiting.

GRUB2 is a fast moving target and it’s developers seem to think that it is perfectly acceptable to depreciate or change functionally on a whim. Fairly major changes where made to the EFI code in GRUB2 since the 1.97 release in March 2010. In my humble opinion most of these changes were not for the good as far as GRUB2 on EFI is concerned. In particular video mode setting is significantly worse. Moreover. the developers need to update the GRUB2 documentation to incorporate these changes as at present the documentation is woefully out of sync with the 1.98 codebase.

As EFI-based computers become more common, the question arises as to what value GRUB and GURB2 actually provides for such computers. Since the majority of EFI-based computers come with their own EFI shell and customizable boot manager, I suspect that the answer to that question will be – no value at all.

2 comments to Boot Fedora 14 Using UEFI and GRUB2

  • gongwayne

    Hi,Murphy
    An error happened that error:cannot open ./moddep.lst, when I was compiling the grub2 following the steps above.
    could you help me to solve that problem?

    Thanks a lot!

    gongwayne

  • Hi Murphy, I managed to get grub2 latest source working perfectly with a few caveats I could not get png background to display and I cannot tell my Motherboard to use grub2 by default it keeps loading grub legacy by default which I used your guide to copy the efidisk image to USB drive and boot anaconda from there. I have no clue how to tell my UEFI to look for grub2 as I have minimal EFI shell knowledge I just use it to boot grub2 manually by loading the MSI EFI shell first. The boards is MSI P67-GD55.

    Cheers,
    Ash P