Grub2 - quickly adding a Windows system

How to quickly add Windows to the GRUB 2 menu? See how the os-prober tool works: it automatically finds systems and updates the bootloader configuration.

grub2 os-prober windows

I was prompted to write this text by problems during my last system installation, or rather a problem with the so-called bootloader. Since I started using Linux, I mostly used the good old LILO (LInux LOader), which is very simple to configure but is already a bit outdated. What captivated me was the fact that Grub 2 can boot an ISO image directly from a hard drive. Since I only had sporadic contact with the previous version of grub, I didn't experience the shock during configuration that some users accustomed to grub v1 experienced (including the lack of the /boot/grub/menu.lst file in favor of /boot/grub/grub.cfg).

Differences between Grub1 and Grub2:

  • In the predecessor, configuration was done via the /boot/grub/menu.lst file, which just needed to be modified accordingly. In Grub 2 there's a new structure of configuration files and directories. The main configuration file is now /etc/grub/grub.cfg. Grub's creators don't recommend "manually" editing this file - grub.cfg is generated by appropriate scripts located in /etc/grub.d/, but more on that later.
  • IMPORTANT: The way partitions are numbered changes.
  • 
               grub1:     grub2:
    
    /dev/sda1  (hd0,0)   (hd0,1)
    /dev/sda2  (hd0,1)   (hd0,2)
    /dev/sda3  (hd0,2)   (hd0,3)
    
    /dev/sdb1  (hd1,0)   (hd1,1)
    /dev/sdb2  (hd1,1)   (hd1,2)
    /dev/sdb3  (hd1,2)   (hd1,3)
    	

    Unlike the previous Grub, partition numbering starts at 1 instead of 0. Drive numbering remains unchanged, i.e. starting from 0.

The structure of Grub 2's configuration files and directories can be divided into:

  • /boot/grub/grub.cfg - the main configuration file generated by scripts
  • /etc/grub.d/ - directory with scripts that generate (contents may vary depending on the distribution; I'll list the ones relevant to us) the above-mentioned grub.cfg file:

  • 05_debian_theme: sets the background, text colors, graphical theme
    10_hurd: locates hurd kernels
    10_linux: locates the Linux kernel
    20_memtest86+: memory test
    30_os-prober: searches every partition for operating systems (Linux and others) and integrates them into the boot menu
    40_custom: template for creating custom menu entries for other operating systems
  • /etc/default/grub - grub configuration excluding the list of systems in the menu (including timeout, order of systems in the menu)

  • GRUB_DEFAULT=N: order, which system should run first (counting from zero).
    GRUB_TIMEOUT=N: system selection time (in seconds).
    GRUB_CMDLINE_LINUX_DEFAULTM: parameters passed to the system kernel at startup

Adding a Windows system:

Adding another system can be done in two ways: adding the appropriate entry to the /etc/grub.d/40_custom file, or creating your own script in the /etc/grub.d/ directory. Honestly, I don't see much of a difference between the two methods. I chose to create my own scripts, following the rule of one file - one entry in the grub menu.

The configuration below is carried out in the following situation (you can check yours by issuing the command fdisk -l):


disk no. 1:
   Device Boot      Id  System
/dev/sda1            7  HPFS/NTFS
/dev/sda2            f  W95 Ext'd (LBA)
/dev/sda5            83 Linux
disk no. 2:
   Device Boot      Id  System
/dev/sdb1   *        c  W95 FAT32 (LBA) #windows xp partition
/dev/sdb2            f  W95 Ext'd (LBA)
/dev/sdb5            7  HPFS/NTFS

  • Modifying the /etc/grub.d/40_custom file:
  • 
    #!/bin/sh
    exec tail -n +3 $0
    # This file provides an easy way to add custom menu entries.  Simply type the
    # menu entries you want to add after this comment.  Be careful not to change
    # the 'exec tail' line above.
    menuentry "Windows XP" {
    set root=(hd1,1)
    drivemap -s (hd0) (hd1) ##IMPORTANT: if windows is on a different partition than grub
    chainloader +1
    }
    
  • After saving the file, we run the command update-grub2 which generates the main configuration file /boot/grub/grub.cfg
  • Creating your own script:
  • In the /etc/grub.d/ directory we create a script whose name should start with a number that determines the order of appearance in the menu. Regardless of the distribution, in grub the file generating the entry for Linux systems has the form /etc/grub.d/10_linux, so if we want Windows to be first, we should create e.g. touch /etc/grub.d/09_WinXP
  • 
    #!/bin/sh -e
    echo "Added Windows XP" >&2	#message shown when running update-grub2
    cat << EOF
    menuentry "Windows XP" {	#menu entry
        set root=(hd1,1)		#set disk and partition
        drivemap -s (hd0) (hd1)	#IMPORTANT: if windows is on a different partition than grub
        chainloader +1		
    }
    EOF
    
  • ...and of course update-grub2

grub2 - automatically adding Windows

If someone isn't a big fan of digging through configuration files, a program called os-prober comes to the rescue. The os-prober application scans all disks to find additional systems, adding them to the grub menu. Using it is downright trivial - it comes down to installing and running it.


aptitude install os-prober #installation for Debian-based systems
os-prober
update-grub2

grub2 - booting an ISO image from an HDD

Below I'll show how to boot an ISO image located on a disk from within GRUB. This can be either a LiveCD or other programs, e.g. Acronis True Image. In this case, the os-prober application isn't able to help us - we have to create the appropriate entry ourselves in /etc/grub.d/. It should be noted that the configuration given below is a specific example for the Slax LiveCD system.

  • we create the file etc/grub.d/44_liveCD_slack
  • 
    #!/bin/sh -e
    echo "Adding Slax LiveCD" >&2
    cat << EOF
    menuentry "slax LiveCD"  {
    loopback  loop /root/iso/slax-6.1.2.iso
    linux       (loop)/boot/vmlinuz from=/root/iso/slax-6.1.2.iso ramdisk_size=6666 root=/dev/ram0 rw autoexec=startx
    initrd      (loop)/boot/initrd.gz
    }
    EOF
    
  • of course update-grub2