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.
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:
- /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.
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.
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 gcry_rijndael.mod part_msdos.mod affs.mod gcry_rmd160.mod part_sun.mod afs_be.mod gcry_seed.mod parttool.lst afs.mod gcry_serpent.mod parttool.mod aout.mod gcry_sha1.mod password.mod ata.mod gcry_sha256.mod password_pbkdf2.mod ata_pthru.mod gcry_sha512.mod pbkdf2.mod at_keyboard.mod gcry_tiger.mod pci.mod befs_be.mod gcry_twofish.mod play.mod befs.mod gcry_whirlpool.mod png.mod biosdisk.mod gettext.mod probe.mod bitmap.mod gfxmenu.mod pxeboot.img bitmap_scale.mod gfxterm.mod pxecmd.mod blocklist.mod gptsync.mod pxe.mod boot.img grubenv raid5rec.mod boot.mod gzio.mod raid6rec.mod bsd.mod halt.mod raid.mod bufio.mod handler.lst read.mod cat.mod handler.mod reboot.mod cdboot.img hashsum.mod reiserfs.mod chain.mod hdparm.mod relocator.mod charset.mod hello.mod scsi.mod cmp.mod help.mod search_fs_file.mod command.lst hexdump.mod search_fs_uuid.mod configfile.mod hfs.mod search_label.mod core.img hfsplus.mod search.mod cpio.mod iso9660.mod serial.mod cpuid.mod jfs.mod setjmp.mod crc.mod jpeg.mod setpci.mod crypto.lst kernel.img sfs.mod crypto.mod keystatus.mod sh.mod datehook.mod linux16.mod sleep.mod date.mod linux.mod tar.mod datetime.mod lnxboot.img terminal.lst device.map loadenv.mod terminal.mod diskboot.img locale terminfo.mod dm_nv.mod loopback.mod test.mod drivemap.mod lsmmap.mod tga.mod echo.mod ls.mod trig.mod efiemu32.o lspci.mod true.mod efiemu64.o lvm.mod udf.mod efiemu.mod mdraid.mod ufs1.mod elf.mod memdisk.mod ufs2.mod example_functional_test.mod memrw.mod uhci.mod ext2.mod minicmd.mod usb_keyboard.mod extcmd.mod minix.mod usb.mod fat.mod mmap.mod usbms.mod font.mod moddep.lst usbtest.mod fshelp.mod msdospart.mod vbeinfo.mod fs.lst multiboot2.mod vbe.mod functional_test.mod multiboot.mod vbetest.mod gcry_arcfour.mod normal.mod vga.mod gcry_blowfish.mod ntfscomp.mod vga_text.mod gcry_camellia.mod ntfs.mod video_fb.mod gcry_cast5.mod ohci.mod video.lst gcry_crc.mod part_acorn.mod video.mod gcry_des.mod part_amiga.mod videotest.mod gcry_md4.mod part_apple.mod xfs.mod gcry_md5.mod part_gpt.mod xnu.mod gcry_rfc2268.mod partmap.lst xnu_uuid.mod
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_mod-commands_colortest.o und-colortest.lst CLEAN_MODULE_TARGETS += clean-module-colortest.mod.1 clean-module-colortest.mod-symbol.1: 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-colortest.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-colortest.o mod-colortest.o $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_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 colortest/' > $@ 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_DEPENDENCIES) $(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.lst 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_DEPENDENCIES) gencmdlist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh colortest > $@ || (rm -f $@; exit 1) fs-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) genfslist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh colortest > $@ || (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 colortest > $@ || (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 colortest > $@ || (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_DEPENDENCIES) genvideolist.sh set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genvideolist.sh colortest > $@ || (rm -f $@; exit 1) colortest_mod_CFLAGS = $(COMMON_CFLAGS) colortest_mod_LDFLAGS = $(COMMON_LDFLAGS)
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?
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 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:
root=(hd0,1) timeout=10 default=0 set color_normal=yellow/black set color_highlight=blue/yellow 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 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 }
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.
Couldn’t agree more with you comments regarding hide/unhide.
My solution was to toggle the bits in the MBR
myself and not try to deal with what appears
to me as something straight out of Micro$oft.
I wonder if this is a symptom of the
commercialization of Ubuntu?
Very poor programming decision.
e.