GRUB2 Poor Design Decisions GRUB2 Poor Design Decisions Finnbarr P. Murphy (fpm@fpmurphy.com) The more I use GRUB2 the more I have come to realize that some of the design decisions relating to GRUB2 must have been made by the same committee that designed the camel and the dodo. ● se ● /etc/default/grub This configuration file contains the GRUB2 menu settings that are read by the /etc/grub.d/ GRUB scripts and written to /boot/grub/grub.cfg. It is intended to be the main customization file for GRUB2 for most people, similar to /boot/grub/menu.lst in GRUB Legacy. /etc/grub.d/ This new directory contains GRUB2 scripts. These scripts are building blocks from which the grub.cfg file is built. When the update-grub is invoked, the scripts are read in a certain sequence and /boot/grub/grub.cfg is created. /boot/grub/grub.cfg This is the file that replaces GRUB Legacy’s /boot/grub/menu.lst. lu ● on ly In GRUB Legacy, you simply edited /boot/grub/menu.lst to customize GRUB. Not so in GRUB2! Obviously somebody had way too much time on their hands and decided that a simple method which had stood the test of time – direct editing of the GRUB configuration file – should be replaced with some far more complex for no good or discernible reason. Thus GRUB2 places its configuration files in three separate locations: pe rs o nn a The documented method in GRUB2 to change a boot option or add another menu item is to edit the /etc/default/grub configuration file, run the update-grub command which uses the scripts in /etc/grub.d/ to create a new /boot/grub/grub.cfg file. A whole cadre of developers has sprung up to develop GUI editors for GRUB2 configuration. Numerous technical articles has been written on GRUB2 but users seem to be more confused than ever on how to configure GRUB2. My recommendation is to simply directly edit /boot/grub.cfg and abandon all the other files and tools which, in the end, simply write a new /boot/grub/grub.cfg. Fo r Turning to the /boot/grub directory. In GRUB Legacy this directory contained only a small number of files. Not so with GRUB2. This directory now contains numerous files. If you use grub-install it copies all sort files to /boot/grub. For example here is a list of the files that were installed in this directory when I built GRUB2 v1.98 and used grub-install to install it: acpi.mod affs.mod afs_be.mod afs.mod aout.mod ata.mod ata_pthru.mod at_keyboard.mod befs_be.mod befs.mod biosdisk.mod bitmap.mod bitmap_scale.mod blocklist.mod boot.img boot.mod bsd.mod bufio.mod cat.mod cdboot.img 09-29-2016 gcry_rijndael.mod gcry_rmd160.mod gcry_seed.mod gcry_serpent.mod gcry_sha1.mod gcry_sha256.mod gcry_sha512.mod gcry_tiger.mod gcry_twofish.mod gcry_whirlpool.mod gettext.mod gfxmenu.mod gfxterm.mod gptsync.mod grubenv gzio.mod halt.mod handler.lst handler.mod hashsum.mod part_msdos.mod part_sun.mod parttool.lst parttool.mod password.mod password_pbkdf2.mod pbkdf2.mod pci.mod play.mod png.mod probe.mod pxeboot.img pxecmd.mod pxe.mod raid5rec.mod raid6rec.mod raid.mod read.mod reboot.mod reiserfs.mod Copyright 2004-2016 Finnbarr P. Murphy. All rights reserved. 1/6 lu se on relocator.mod scsi.mod search_fs_file.mod search_fs_uuid.mod search_label.mod search.mod serial.mod setjmp.mod setpci.mod sfs.mod sh.mod sleep.mod tar.mod terminal.lst terminal.mod terminfo.mod test.mod tga.mod trig.mod true.mod udf.mod ufs1.mod ufs2.mod uhci.mod usb_keyboard.mod usb.mod usbms.mod usbtest.mod vbeinfo.mod vbe.mod vbetest.mod vga.mod vga_text.mod video_fb.mod video.lst video.mod videotest.mod xfs.mod xnu.mod xnu_uuid.mod nn a hdparm.mod hello.mod help.mod hexdump.mod hfs.mod hfsplus.mod iso9660.mod jfs.mod jpeg.mod kernel.img keystatus.mod linux16.mod linux.mod lnxboot.img loadenv.mod locale loopback.mod lsmmap.mod ls.mod lspci.mod lvm.mod mdraid.mod memdisk.mod memrw.mod minicmd.mod minix.mod mmap.mod moddep.lst msdospart.mod multiboot2.mod multiboot.mod normal.mod ntfscomp.mod ntfs.mod ohci.mod part_acorn.mod part_amiga.mod part_apple.mod part_gpt.mod partmap.lst pe rs o chain.mod charset.mod cmp.mod command.lst configfile.mod core.img cpio.mod cpuid.mod crc.mod crypto.lst crypto.mod datehook.mod date.mod datetime.mod device.map diskboot.img dm_nv.mod drivemap.mod echo.mod efiemu32.o efiemu64.o efiemu.mod elf.mod example_functional_test.mod ext2.mod extcmd.mod fat.mod font.mod fshelp.mod fs.lst functional_test.mod gcry_arcfour.mod gcry_blowfish.mod gcry_camellia.mod gcry_cast5.mod gcry_crc.mod gcry_des.mod gcry_md4.mod gcry_md5.mod gcry_rfc2268.mod ly GRUB2 Poor Design Decisions Fo r I am on an Intel X64 platform. Why are modules for handling Amiga (part_amiga.mod) or Apple ( part_apple.mod) partitions installed on my system? Why do I need the demonstration module hello.mod? I am never going to use them. The installation script grub-install needs to have some intelligence added to it so that modules which are incompatible with your platform are not installed. In addition, it would be nice if the modules could be placed in a subdirectory of /boot/grub in order to reduce the number of files in /boot/grub. The GRUB2 variable prefix allow you to place a prefix in front of the grub subdirectory but does not allow you to place the modules in another directory or a subdirectory. The build system is needlessly complicated. If I want to create a new command, say colortest, I can place a single file colortest.c in the ../common source subdirectory (which contains to source code for most commands, one per source file) , but then I have to add the following lines to ../conf/common.mk: # For colortest.mod. pkglib_MODULES += colortest.mod colortest_mod_SOURCES = commands/colortest.c clean-module-colortest.mod.1: rm -f colortest.mod mod-colortest.o mod-colortest.c pre-colortest.o colortest_modcommands_colortest.o und-colortest.lst CLEAN_MODULE_TARGETS += clean-module-colortest.mod.1 clean-module-colortest.mod-symbol.1: 09-29-2016 Copyright 2004-2016 Finnbarr P. Murphy. All rights reserved. 2/6 GRUB2 Poor Design Decisions Fo r pe rs o nn a lu se on ly rm -f def-colortest.lst CLEAN_MODULE_TARGETS += clean-module-colortest.mod-symbol.1 DEFSYMFILES += def-colortest.lst mostlyclean-module-colortest.mod.1: rm -f colortest_mod-commands_colortest.d MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-colortest.mod.1 UNDSYMFILES += und-colortest.lst ifneq ($(TARGET_APPLE_CC),1) colortest.mod: pre-colortest.o mod-colortest.o $(TARGET_OBJ2ELF) -rm -f $@ $(TARGET_CC) $(colortest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-colort est.o mod-colortest.o if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1) ; fi $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _ grub_mod_fini -R .note -R .comment $@ else colortest.mod: pre-colortest.o mod-colortest.o $(TARGET_OBJ2ELF) -rm -f $@ -rm -f $@.bin $(TARGET_CC) $(colortest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-co lortest.o mod-colortest.o $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mo d_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@ -rm -f $@.bin endif pre-colortest.o: $(colortest_mod_DEPENDENCIES) colortest_mod-commands_colortest.o -rm -f $@ $(TARGET_CC) $(colortest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ colortest_ mod-commands_colortest.o mod-colortest.o: mod-colortest.c $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -c -o $@ $< mod-colortest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh sh $(srcdir)/genmodsrc.sh 'colortest' $< > $@ || (rm -f $@; exit 1) ifneq ($(TARGET_APPLE_CC),1) def-colortest.lst: pre-colortest.o $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 colortest/' > $@ else def-colortest.lst: pre-colortest.o $(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]' | sed 's/^\([^ ]*\).*/\1 color test/' > $@ endif und-colortest.lst: pre-colortest.o echo 'colortest' > $@ $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ colortest_mod-commands_colortest.o: commands/colortest.c $(commands/colortest.c_DEPENDENCI ES) $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -MD -c -o $@ $< -include colortest_mod-commands_colortest.d clean-module-colortest_mod-commands_colortest-extra.1: rm -f cmd-colortest_mod-commands_colortest.lst fs-colortest_mod-commands_colortest. lst partmap-colortest_mod-commands_colortest.lst handler-colortest_mod-commands_colortest. lst parttool-colortest_mod-commands_colortest.lst video-colortest_mod-commands_colortest.l st terminal-colortest_mod-commands_colortest.lst CLEAN_MODULE_TARGETS += clean-module-colortest_mod-commands_colortest-extra.1 COMMANDFILES += cmd-colortest_mod-commands_colortest.lst FSFILES += fs-colortest_mod-commands_colortest.lst PARTTOOLFILES += parttool-colortest_mod-commands_colortest.lst PARTMAPFILES += partmap-colortest_mod-commands_colortest.lst HANDLERFILES += handler-colortest_mod-commands_colortest.lst TERMINALFILES += terminal-colortest_mod-commands_colortest.lst VIDEOFILES += video-colortest_mod-commands_colortest.lst cmd-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPE NDENCIES) gencmdlist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh color 09-29-2016 Copyright 2004-2016 Finnbarr P. Murphy. All rights reserved. 3/6 GRUB2 Poor Design Decisions nn a lu se on ly test > $@ || (rm -f $@; exit 1) fs-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPEN DENCIES) genfslist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh colort est > $@ || (rm -f $@; exit 1) parttool-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c _DEPENDENCIES) genparttoollist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genparttoollist.sh colortest > $@ || (rm -f $@; exit 1) partmap-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_ DEPENDENCIES) genpartmaplist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh c olortest > $@ || (rm -f $@; exit 1) handler-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_ DEPENDENCIES) genhandlerlist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genhandlerlist.sh c olortest > $@ || (rm -f $@; exit 1) terminal-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c _DEPENDENCIES) genterminallist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genterminallist.sh colortest > $@ || (rm -f $@; exit 1) video-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DE PENDENCIES) genvideolist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genvideolist.sh col ortest > $@ || (rm -f $@; exit 1) colortest_mod_CFLAGS = $(COMMON_CFLAGS) colortest_mod_LDFLAGS = $(COMMON_LDFLAGS) pe rs o Most of the above is cookie cutter build code. I simply took the relevant lines for another module and changed the module name to colortest. It should be possible to eliminate most of the above with a more intelligent build environment. In some build environments I have encountered over the years it can be as simple as adding the name of the module to a list of modules which are to be built. Why complicate things when there are well proven simple ways to achieve the same end? Fo r The introduction of support for graphic screens in GRUB2 has introduced subtle problems with color support. Colors work as expected if you use the following configuration: root=(hd0,1) timeout=10 default=0 if loadfont /grub/font/unicode.pf2 then set gfxmode="1024x768x32" set gfxpayload=keep insmod gfxterm insmod vbe terminal_output gfxterm terminal gfxterm insmod tga use_bg=true background_image /grub/image/f13rockets.tga fi set color_normal=yellow/black set color_highlight=blue/yellow 09-29-2016 Copyright 2004-2016 Finnbarr P. Murphy. All rights reserved. 4/6 GRUB2 Poor Design Decisions set menu_color_normal=yellow/black set menu_color_highlight=white/light-gray menuentry "Fedora 13" { linux /vmlinuz-2.6.33.5-124.fc13.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.33.5-124.fc13.x86_64.img } but revert to using gray/black in command mode when you move the set color_normal and set color_highlight lines to before the graphics card setting, i.e: ly root=(hd0,1) on timeout=10 default=0 nn a lu if loadfont /grub/font/unicode.pf2 then set gfxmode="1024x768x32" set gfxpayload=keep insmod gfxterm insmod vbe terminal_output gfxterm terminal gfxterm insmod tga use_bg=true background_image /grub/image/f13rockets.tga fi se set color_normal=yellow/black set color_highlight=blue/yellow pe rs o set menu_color_normal=yellow/black set menu_color_highlight=white/light-gray Fo r menuentry "Fedora 13" { linux /vmlinuz-2.6.33.5-124.fc13.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.33.5-124.fc13.x86_64.img } It took me a while to understand what was going on when I first encountered this issue. The default color in command mode was gray/black even though the set command showed that the color settings were correct. Finally, for no good reason the development sources have a dependency on Ruby. See autogen.sh, genmk.rb, configure.ac and configure. Why? Probably because the original version of GRUB2 was written by a Japanese programmer. Requiring Ruby for GRUB2 development is a needless complication of a relatively simple process. Any dependency on Ruby should be removed. Contrary to what you may be thinking, I actually like GRUB2. It is a huge improvement over GRUB Legacy. All my GNU/Linux systems now use it and I am an active developer of GRUB2 modules. I just think that the main developers of GRUB2 have managed to seriously complicate a relatively simple piece of software from a user’s perspective. However from a developer’s perspective, except for certain functionality such as EFI support, the source code is well structured and partitioned and there is good built-in support for extensions. 09-29-2016 Copyright 2004-2016 Finnbarr P. Murphy. All rights reserved. 5/6 Fo r pe rs o nn a lu se on ly GRUB2 Poor Design Decisions 09-29-2016 Copyright 2004-2016 Finnbarr P. Murphy. All rights reserved. 6/6