GRUB BOOTLOADER

GRUB legacy versus GRUB 2

Now the big question, why one should you (not) use?

GRUB legacy

It is older and no longer developed, but works great and has proven its worth many times over. Editing the GRUB menu is a very simple thing and require little skill on the behalf of the user, save for making sure the right syntax is followed.

GRUB 2

GRUB 2 is beta software at the moment, although version 1.97 could easily become the official one. This makes it a less likely candidate for production systems.

Additionally, GRUB 2 is more difficult to work with, because a) it requires shell skill, which is not something everyone can do b) changes to the GRUB menu are more difficult to implement and require three separate steps rather than one as before c) the changes are not automatic and have to be "compiled" into the menu every time, similar to what LILO used to do.

GRUB 2 is currently supported by a very small number of distributions, thus you are less likely to receive support and find answers online, including official and unofficial circles. What more, there's a chance you will encounter problems when using GRUB 2 in a mixed environment.

GRUB 2 Tutorial

Before you dig in, I strongly advise you to read my original GRUB tutorial. This will help you understand this article better.

GRUB 2 introduces many new changes. GRUB 2 has better portability and modularity, supports non-ASCII characters, dynamic loading of modules, real memory management, and more.

All these are pretty much irrelevant for most users. What you need to know are the changes in the configuration files and the way GRUB 2 operates.

New layout

Old GRUB files were (and still are!) located under /boot/grub/, including the menu.lst file that was read during boot and which contents were displayed to the user in the form of the GRUB menu.

GRUB 2 places its files in three core locations:

/boot/grub/grub.cfg - This is the main configuration file that replaces menu.lst. Unlike menu.lst, this file cannot be edited by hand! I strongly advise against trying to tamper with this file, using chattr command or anything of the sort. Let it be.

/etc/grub.d/ - This new directory contains GRUB scripts. These scripts are building blocks from which the grub.cfg file is built. When the relevant GRUB command is executed, the scripts are read in a certain sequence and grub.cfg is created.

/etc/default/grub - This file contains the GRUB menu settings that are read by the GRUB scripts and written into grub.cfg. It is the customization part of the GRUB, similar to the old menu.lst, except the actual boot entries.

This means that if you want to change the GRUB menu, you will have to edit existing scripts or create new ones, then update the menu. This is more similar to LILO than GRUB legacy, which allow editing the menu on the fly.

Sample grub.cfg file

The file is located under /boot/grub/:

Boot grub

This is what the grub.cfg file looks like:

grub.cfg

It is not really interesting, because it's just a shell script. Most people will probably not want to read its contents or be able to fully understand them. This file is still worth a quick look any time you update the GRUB menu, to make sure the correct entries are included as you expected. But only if you're comfortable with scripts!

Sample /etc/grub.d/ directory

These are the contents of the directory on a fresh installation, in this case Kubuntu:

Directory

Let's review the scripts:

00_header is the script that loads GRUB settings from /etc/default/grub, including timeout, default boot entry, and others. We will talk more about these soon.

05_debian_theme defines the background, colors and themes. The name of this script is definitely going to change to when other distributions adopt GRUB 2.

10_linux loads the menu entries for the installed distribution.

20_memtest86+ loads the memtest utility.

30_os-prober is the script that will scan the hard disks for other operating systems and add them to the boot menu.

40_custom is a template that you can use to create additional entries to be added to the boot menu.

Have you noticed the numbering in the script names? Well, this is somewhat similar to the order of Start/Kill scripts used in different runlevels. The numbering defines precedence. This means that 10_linux will be executed before 20_memtest86+ and therefore placed higher in the boot menu order.

The scripts are not very interesting. Like the grub.cfg file, they are not intended to be edited, save for 40_custom. You need to very careful when working with these scripts.

We will soon see what they look like and learn how to use them.

Sample /etc/default/grub

The file is located under /etc/default:

Default dir

This directory contains many other files so do not assume it is just used for GRUB. The grub file is a text file that is parsed by the 00_header script. You can make your changes here, if you want. We will talk about these later, in the Customization section.

Grub

Now we know what the core files are. Let's see how we use them.

Basic usage

It's time to put our theoretical knowledge to some real action.

How GRUB 2 works?

GRUB 2 works like this:

/etc/default/grub contains customization; /etc/grub.d/ scripts contain GRUB menu information and operating system boot scripts. When the update-grub command is run, it reads the contents of the grub file and the grub.d scripts and creates the grub.cfg file.

That's all.

To change the grub.cfg file, you need to edit the grub file or the scripts under grub.d.

Scripts are meant to be executed. This means that they have the execute bit turned on. If you turn the execute bit off, they will not run.

This means that you can place as many files as you want into the grub.d directory, as long as they are not executable shell scripts that update-grub can read. If you want to use them, you will activate the executable bit, or vice versa, turn it off.

Let's examine the scripts.

For instance, 00_header and 05_debian_theme:

00_header

05_debian_theme

40_custom makes a little more sense, but it still does not tell us how we can customize the scripts. Don't worry, we will soon learn everything.

40_custom

Add new GRUB script

To add a new boot option, you will have to follow a basic syntax:

Create a new file that has a XX_ prefix in the name, where XX is a sequence of numbers. If you want the new entry to be placed above others, use lower numbers, if you want it to be placed below others, use higher numbers.

For example, 11_something will be placed after the default entries by the operating system, whereas 08_something will be placed before the 10_linux entries.

The next step is to write the actual content. Here's a sample:

#!/bin/sh -e
echo "Some string"
cat << EOF
menuentry "Something" {
set root=(hdX,Y)
-- boot parameters --
}
EOF

Let's examine the file ...

It's a shell script, as declared in the first line.

echo "Some string" is a string that you will see when running update-grub. If you do not want to see the echo command printed, you can redirect it to standard error or /dev/null:

echo "Some string" > &2

Example: echo "Adding openSUSE 11.2"

cat << EOF defines the start of the actual boot entry.

menuentry "Something" is the name that will show in the menu. Example: Linux.

set root=(hdX,Y) - we're back to old school, setting the root device.

Critical! GRUB 2 uses PARTITION notation that starts with 1 and not 0 like GRUB legacy! This is terribly important to remember!

In other words, devices are still numbered from 0, but partitions start with 1. For example, this means that sda1 is now (hd0,1) and NOT (hd0,0) as before!

-- boot parameters -- will really change from one OS to another. In Linux, you may want to use something like:

linux /boot/vmlinuz
initrd /boot/initrd.img

But in Windows, you would probably use:

chainloader (hdX,Y)+1

Therefore, a complete script example would look something like:

#!/bin/sh -e
echo "Adding my custom Linux to GRUB 2"
cat << EOF
menuentry "My custom Linux" {
set root=(hd0,5)
linux /boot/vmlinuz
initrd /boot/initrd.img
}
EOF

Or for Windows, something like:

#!/bin/sh -e
echo "Adding Windows 8 to GRUB 2 menu"
cat << EOF
menuentry "Windows 8" {
set root=(hd0,1)
chainloader (hd0,1)+1
}
EOF

EOF ends the GRUB entry.

Now we have a file ready. But we need to make it executable.

chmod +x XX_new_os_script

GRUB 2 commands

One more thing I'd like to emphasize here is the data contained in the cat << EOF section. As we've seen just now, the cat command defines the start of the code in the script that will be added to the GRUB menu literally and NOT interpreted by the shell. In other words, anything that goes between cat << EOF and EOF are GRUB commands.

We have used a number of different commands in this script. Some of these you may have seen before in GRUB legacy, some may appear new and strange.

Not to worry, there's a full list, including a comparison to GRUB legacy. Some of the commands have been replaced and others added. For more details, please check GRUB 2 command list.

Update GRUB

The new script is in place, but the GRUB menu (grub.cfg) has not been updated yet. We need to run the update-grub command to make it happen.

update-grub

Here's an example from a dual-boot configuration, which we will examine more deeply later on. I've added two Kubuntu entries and one Ubuntu entry to the Ubuntu GRUB menu. I have done this in order to get rid of the default 10_linux, which is ugly and uses generic kernel names in the titles, plus it calls both Ubuntu and Kubuntu the same.

But let's move slowly. Our first task is to add the new scripts. After we ascertain that they boot fine, we will get rid of the duplicates.

New scripts

Updating

After rebooting, we have this - I apologize for the uncomeliness:

New scripts in place

Once we are using the new scripts boot properly, we can then chmod -x the 10_linux and get rid of the generic 2.6.31-14 entries, keeping our menu nice and dandy.

Change script boot order by changing numbers

You can also change the numbers if you want. For instance, I changed the Kubuntu entries to 08 and 09, to make them boot first, before default entries and the custom Ubuntu script.

Reorder

Replacing default entries

This is something you may want to do, just as we have shown above. In order to make sure your new scripts boot correctly, you can refer to a working example of grub.cfg to make sure you use the right linux and initrd lines.

Here's an example of what I have:

Template

And accordingly, I've created the new script:

Copy

OS Prober

OS Prober can also help you. It will find additional entries on your hard disks and add them to the menu. You can use the added information to create your own scripts. Again, refer to the grub.cfg file, os-prober section, for more data:

OS prober

Reinstall GRUB

GRUB 2 can be installed even while you are booted in the OS. You do not need a live environment for that. Just execute the install-grub command against the device or the partition you desire.

grub-install

can be /dev/hda, /dev/sdb, /dev/sdc4, and so forth.

It is important that you pay attention to the output produced by the command. If you have external disks connected at the time you run the command, it will add these disks to the list of mapped devices. There should be no big harm in that, but if some entries are incorrect, remove them.

grub-install reports incorrect devices

Here's an example of that:

Install

You will need to open the /boot/grub/device.map file, delete the wrong entry, in our case the one pointing to /dev/sdb and rerun the grub-install command.

Install again

Mini summary

That's it for now. You have the tools you need to start working. Still, to make things clearer, I've prepared a short summary that concludes the introduction and basic usage sections. Here we go:

GRUB 2 has three main parts:

  1. /etc/default/grub - the file containing GRUB 2 menu settings.
  2. /etc/grub.d/ - the directory containing GRUB 2 menu creating scripts.
  3. /boot/grub/grub.cfg - the GRUB 2 configuration file, not editable.

update-grub command reads the /etc/grub.d directory and looks for executable scripts inside it. The scripts are read, in the order of their numbering, and written into the grub.cfg file, along with the menu settings read from the /etc/default/grub file.

Boot entries come from several sources - the default that comes with the distribution, other operating systems probed on the connected disks and custom scripts written by the user, following a strict syntax. The scripts are written as shell (sh).

You can add/remove entries by simply chmod-ing the scripts; no need to delete them. GRUB 2 can be reinstalled anytime you want, even while booted in the OS.

Good so far? Excellent. You see, it's rather simple.

Now, let's see a few real-life cases. Afterwards, we will customize GRUB 2 and learn how to recover from serious errors and misconfigurations.

Real life multi-boot cases

In this section, we will discuss several common multi-boot cases that the average user might encounter, including GRUB and GRUB 2 mix, Windows and Linux side by side, chainloading, and some others.

Some of the experiments were conducted on real physical systems, so some screenshots of boot menus come from actual photos, so they may look slightly twisted and less appealing that you would like, but this is in order to reassure you that working with GRUB 2 is as simple as any other administrative task. It just requires some patience and care.

Dual boot: two operating systems with GRUB 2

This is probably the simplest dual-boot configuration. Both operating systems use GRUB 2, so they can easily interact with one another. The two systems are Ubuntu 9.10 and Kubuntu 9.10, both formatted with Ext4.

Ubuntu was installed first, with GRUB 2 installed to the MBR of /dev/sda. Kubuntu was installed second, again to MBR, overwriting the previous instance. However, the OS probe script found and added Ubuntu successfully.

If you've read my Kubuntu tutorial, you will notice that Kubuntu entries are also labeled Ubuntu, which can be confusing if you have several, different Ubuntu entries on your machine.

In this section, we will:

  • Learn how to edit existing entries and make them more presentable.
  • Add new entries and reorder existing ones.

This will give us the initial clues into how GRUB 2 works and what users have to do to make it work. After that, we will examine bootloading GRUB 2 ready systems from the legacy GRUB and vice versa. And then, we will add Windows, too.

We have seen snippets of this testcase earlier. We have our default entries, which do not look well and want them replaced.

So we refer to grub.cfg file, examine the syntax used by 10_linux and we copy the relevant bits of data into our new scripts, called 08_9_10_kubuntu and 09_9_10_kubuntu_recovery. Just like we did earlier.

Entry 1

Recovery entry

After that, we need to chmod +x the scripts and update the GRUB. Very simple.

New update

New scripts

After rebooting and verifying that everything works, we can get rid of the 10_linux, having replaced its entries with the custom scripts.

Job done, very easy!

Dual boot: two operating systems with GRUB legacy & GRUB 2 mix

This is a very interesting case. Let's say you have two operating systems, like Ubuntu 9.10, which uses the new GRUB 2 and boots from Ext4, and a more classic distro like openSUSE 11.2, which does use Ext4, but still boots the old GRUB.

We will learn how to:

  • Boot Ubuntu from the context of the openSUSE GRUB.
  • Boot openSUSE from the context of the Ubuntu GRUB.
  • Edit entries in both systems to make things work.

Let's do it.

Decision: which one is default?

This is something you need to decide. You have two bootloader options and you need to choose the default one.

If you're asking me, at the time being, you should use GRUB legacy as your default bootloader, because it is production quality and has known, established support channels. Running GRUB 2 will place you in a minority.

Therefore, if you are going to use GRUB legacy for booting, then you should:

  • Install GRUB into the MBR when installing the distribution that ships it, like openSUSE in our example. Pay attention to these details when installing the distro!
  • Install GRUB 2 into the root partition where the distribution using it is installed, in this case Ubuntu. Pay attention to these details when installing the distro.

Otherwise, if you plan on using GRUB 2 as your default, you need to do things the other way around.

Bootloader choice

Default selection

Bootloader options

If you are not really sure, review the partition table.

fdisk

In our example, Ubuntu was installed first, with root under /dev/sda6 and home under /dev/sda7. openSUSE was installed next, to /dev/sda1. Since we want to use the GRUB legacy bootloader, then:

  • Ubuntu bootloader needs to be installed to /dev/sda6.
  • openSUSE bootloader needs to be installed to MBR (/dev/sda).

Now that this is done, let's boot and see what happens.

After you install openSUSE, you will notice that the lovely green GRUB menu contains only openSUSE entries. The reason is, GRUB legacy does not know how to handle the GRUB 2 layout directly and therefore cannot find and append entries to the menu. You will have to do this manually.

Boot into openSUSE and open the menu.lst file in a text editor. Back it up first!

We do not really know yet how to work with GRUB 2 entries from within GRUB legacy. So we will assume that it's the same thing like Windows. We will chainload the other operating system, passing the command to the other bootloader.

Will this work? I do not know, but let's try! We're using our GRUB experience and trying to adapt to the new situation.

Chainload

For those who cannot see what's in the image, we are adding the following entry to the menu.lst file:

title Ubuntu 9.10 Karmic Koala
root (hd0,5)
chainloader (hd0,5)+1

After booting, you will see the menu (once again, excuse the ugliness):

GRUB menu

If you try to boot the Karmic Koala entry, you will hit this unwholesome GRUB error 13:

Unsupported format

This kind of error is common for Linux users trying to boot Windows and Mac partitions. For Windows, the solution is to try to remap the partitions, hide partitions or make them active, which usually solves the problem.

Mac-wise, the problem is similar to what we are facing here. GRUB legacy that comes with openSUSE does not handle well the Ubuntu partitions + GRUB 2 mechanism. We will need a different method to get things done.

For more information, check GRUB error messages.

Booting Ubuntu (with GRUB 2) from openSUSE the right way

Here's what you need to do to make things work. Go back to openSUSE and open the menu.lst file again. We need to make it look like this:

GRUB correct entry

For those who cannot see what's in the image, we are adding the following entry to the menu.lst file:

title Ubuntu 9.10 Karmic Koala
root (hd0,5)
kernel /boot/grub/core.img
savedefault
boot

You may be wondering what we did here. The answer is, core.img file is a small kernel image that allows you to boot the right drivers and properly identify and initialize the real kernel. You can think of this file as a sort of a transitional initrd.img.

After rebooting, you will have the GRUB 2 menu. Select the desired entry and boot.

Once inside Ubuntu, you can do a little trick if you want, that is, rerun the update-grub script. It will now pick up the installed openSUSE as well and add it to the menu. You will then have a recursive GRUB menu that calls the other that calls the other ...

This is not necessary, but can be fun and exercises the power of knowledge and control.

Mixed environment

Another interesting case is Mandriva 2010 and Ubuntu 9.10 dual boot. When installing Mandriva, you have the option to manually edit the GRUB bootloader menu even before the first boot. The truth is, many distributions let you configure the boot menu to some degree. If you know what you need, you can save time by setting up the menu entries during the installation.

Here's what editing the GRUB menu following Mandriva installation looks like:

Add Ubuntu

Basically, we have done the exact same thing we did with openSUSE. For more details, please take a look at the review above.

Dual boot: Windows 7 and Ubuntu

This will probably interest quite a few users. In general, it's the same as before. However, to spice things up a little, I have also added another element of interest here, that of the GRUB to GRUB 2 upgrade.

Test case: a machine dual booting Windows 7 and Ubuntu Jaunty, as shown in my new dual boot guide. Jaunty uses GRUB legacy, but it can be upgraded to GRUB 2, which is what we're going to do.

So, we will first go through the upgrade procedure, paying attention to important details and then, we will make sure our Ubuntu and Windows installations boot fine.

Upgrade from GRUB legacy to GRUB 2

The first thing is to install the GRUB 2 package:

sudo apt-get install grub2

Watch the terminal. You will soon have to answer a few prompts.

Chainload first

The first thing you will have to decide upon is whether to install GRUB2 into MBR right away or test first by installing to the root partition where Ubuntu is installed and chainloading from GRUB legacy. We have done this earlier, by calling on the core.img file, so we know how to do this.

For the sake of elegance, we won't skip this step.

Chainload first

Chainload

The next step is to verify the command-line parameters. Most people won't need to make any change here.

Options

GRUB 2 is now installed:

Done

Before we reboot, make sure the grub.cfg has been built correctly and that it contains the right entries, pointing to the right devices and partitions. Use fdisk if you need to verify that everything is in order.

Ubuntu entry:

Linux entry

Windows entry:

Windows entry

It's time to reboot and test. Your GRUB menu should be changed now and include a Chainload entry for GRUB 2 at the top of the menu.

Chainload into GRUB 2

Possible errors

You may encounter GRUB Error 11 or GRUB Error 15 when you try to boot into GRUB 2.

Error

For instance, GRUB Error 11 means the wrong root device is selected or that you're booting devices by ID rather than numbers, in which case you will have to change one of the strings to make it work.

To remedy the issue, you will have to highlight the Chainload entry, press e to edit, then change the root line to reflect your real selection. Don't forget you're working with GRUB legacy still, so partitions are numbered from 0.

In the worst case, cycle through root (hdX,Y) until you nail the right one. Change the root entry, hit Enter, press b to boot.

Alternatively, if your GRUB uses strange, long string called device IDs rather than numbers, you will have to replace the string root with uuid and then you should be able to boot your kernel just fine. HowtoForge has a great example, with screenshots.

Eventually, you should see the GRUB 2 menu:

GRUB 2 menu

As you can see, we have Ubuntu entries and we have Vista loader (Windows 7) entries. All seems well. Now, boot both Ubuntu and Windows 7 to make sure everything works properly.

Once you're satisfied, boot into Ubuntu and complete the migration process. You can now write GRUB 2 into MBR and make it the default bootloader.

sudo upgrade-from-grub-legacy

Complete migration

Pay attention to the device mapping and change accordingly. But that's it. We're done. We have now learned both how to upgrade GRUB, handle some boot errors and successfully boot a dual boot configuration including Windows and Linux.

Additional test case scenarios

Triple boot

From here on, it's damn easy. Use whatever you want.

If you're running GRUB legacy as your bootloader, then you will use Windows entries like we did in the original article, plus an entry with /boot/grub/core.img for GRUB 2 entries.

And if you're using GRUB 2, then use OS Prober to find other operating systems. And if you don't like the titles, create custom entries based on the existing selection.

The world is your banana, now.

Customize GRUB menu

Let's say we want to edit the GRUB 2 menu a little, including the default selection, the timeout and other options.

Edit /etc/default/grub

This file contains a few interesting options you may want to change, including the default selected entry, the default timeout and additional options.

/etc/default/grub

GRUB_DEFAULT=0 specifies the default entry. It counts from 0, like any geeky menu. Change to anything you like. If you set the entry to GRUB_DEFAULT=saved, it will boot the last selected option from the previous boot.

GRUB_TIMEOUT="10" specifies the default timeout. Change to anything you want. Very small values are not recommended. Setting to -1 will make GRUB wait indefinitely until you manually select an entry and hit Enter.

There are many other options, as you can see, I will not go through all of them. It's important that you remember that they exist and where they can be found. Do not blindly make changes. Consult the official documentation and always backup the file before tampering.

One more thing that may interest you is the removal of recovery entries.

Remove recovery entries from the menu

The last line in the /etc/default/grub file allows you to disable the recovery mod menu entries. Simply uncomment the line and update GRUB:

GRUB_DISABLE_LINUX_RECOVERY="true"

Remove memtest from the menu

If you do not want to have the memtest entries included, simply chmod -x the 20_memtest script. It will no longer be executable and won't be read into the grub.cfg file the next time you update GRUB.

sudo chmod -x 20_memtest86+

Change titles in menu entries

Instead of using the replacement tweaks I've suggested earlier, by recreating the default Linux entries and removing (chmod-ing -x) the 10_linux script, you can edit the actual script to behave differently and report information in a more human format.

This is some really geeky stuff, take at look at Ubuntu install title tweaks.

Change theme (boot image)

You may want to use a beautiful image during boot rather than the boring blue one. No worries, this can be easily done, by editing the 05_debian_theme script.

The first thing is to find a number of images you want. Pay attention to image detail, as you want to achieve the right contrast between the entries and the background, so you can still read the menu. I will show you my own example - learn from it.

Next, you need a directory to store the images. By default, GRUB 2 takes images from/usr/share/images/desktop-base. This can be a good location - or if you want your own, create one. For instance, /usr/share/images/grub, just as shown on Ubuntu blog.

Copy your images there, mind the extension. By default, GRUB 2 works with .png and .tga files. You can also use .jpg images if you want.

The next step is to edit the 05_debian_theme script and change the relevant entry to point to your own:

Add new image

What I did was comment out the original for loop that reads the image(s) and created my own. If you're not really comfortable doing this, then you should probably postpone any theme tweaking until a later date.

My file is located here: /usr/share/images/grub/dark.png.

Once the file has been changed, run update-grub to update the grub.cfg file. If you've done everything correctly, you should see Found Debian background message in the terminal.

Found new image

Please note that the GRUB menu will not use background images unless these are enabled. To do that, you will have to change the line use_bg=false in theme script and change it to use_bg=true.

Reboot and test:

New theme

As you can see, my choice of background image was bad! You cannot see the text! Therefore, choose carefully what kind of background image you want to use. A theme with a few soft gradients seems like the best idea.

For more details, take a look at the official Wiki documentation.

Comments


  1. Really Appreciable Article, Honestly Said The Thing Actually I liked The most is the step-by-step explanation of everything needed to be known for a blogger or webmaster to comment, I am going show this to my other blogger friends too.
    sumo-pro-crack
    ultraedit-crack
    memtest86-pro-crack
    topaz-gigapixel-ai-crack

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete

Post a Comment

Popular posts from this blog

List Of MSI Motherboard with type of Processor Slot

How to resize and extend centos 7 disk manually