Grub 2, what's the deal?

Grub got a rewrite recently and inherently became a lot more powerful. However you may be wondering where the old menu.lst file has run off to. menu.lst (on debian at least) has been replaced by a series of scripts which build a grub.cfg (grub 2 config file) for you. Things you probably care about:

How do I change kernel options?

Simply edit /etc/default/grub then run update-grub

How do I add other OSs

Generally installing os-prober will solve this problem.

aptitude install os-prober

you should see it spit out some info about adding your other OSs

I want to add a new boot section to grub manually

Simply edit /etc/grub.d/40_custom and add the new section. This will be copied to /boot/grub/grub.cfg when you run update-grub next.

I need to reinstall grub in my master boot record

Boot off a liveCD, and chroot(8) into your main root partition.

Remember that grub numbering starts at 0: /dev/hda1 becomes (hd0,0), etc. However, note that GRUB’s disk ordering is determined by the BIOS, while the Linux kernel’s ordering is not. For instance, on an Asus Eee 701, if you change the BIOS boot order to put the SD-card slot ahead of the internal SSD, GRUB will swap their names around so the internal SSD becomes “hd1” and the SD-card becomes “hd0”. However, the kernel will still call them “sda” and “sdb” respectively.

Run 'grub'. Issue root (hdx,x) if you know where your /boot directory is, or use find /boot/grub/stage1 to find it if you don't. Then issue setup (hdx) to install GRUB in the master boot record of drive hdx, or setup (hdx,x) to setup inside a partition.

Alternatively on many modern distros you can use grub-install(8) to do this e.g.

grub-install /dev/hda

I get "The file /boot/grub/stage1 not read correctly" when running grub-install

Even if you can see the file /boot/grub/stage1 on your filesystem, this error message means that grub can't find it when it is running. Grub consults your /etc/fstab and /etc/mtab files to determine which partition/drive the '/boot' directory is actually on, so check those files are correct. (See the next section for more details about this.)

There are also lots of other obscure reasons why it can't be found, and unfortunately the GRUB developers don't believe in giving users better error messages. In my case, I got this because I was trying to install an MBR to boot of a drive that had linux installed on a partition that used to have windows xp. In this case, the partition type was set to "NTFS" despite containing an ext3 partition. Using cfdisk to change the partition type to be "83 (linux)" meant that when I next ran grub-update, it worked.

I get "Error 15" on boot even after reinstalling GRUB from a rescue CD

This one had us stumped for a while, until I noticed that the boot order in BIOS was CDROM -> IDE-1 -> Floppy. The correct device should have been IDE-0. IDE-1 is the Primary SLAVE drive which in this case happened to exist, and also happened to have an old copy of GRUB on the MBR. Sometimes the problem isn't where you expect it to be!

I get a grub> prompt on boot

This means GRUB can't find your config file. You can still boot into the system by issuing appropriate commands.

Eg., if I have a system which has a single disk, partitioned with /dev/hda1 as /boot and /dev/hda5 as /root, and I have a Kernel called vmlinuz in /boot, I can do:

root (hd0,0)
kernel /vmlinuz root=/dev/hda5 ro

and it'll boot quite happily -- this time. Note that I set the GRUB root to (hd0,0), which corresponds to /dev/hda1, and so the path to the kernel is relative to the top of /dev/hda1 (which is /boot when mounted correctly). Also note that the GRUB shell features tab completion on filenames, so you can do kernel /[tab] and get a list of possible values. You can also use this to work out which FileSystems are which, as GRUB will understand most Linux FileSystems you're likely to have.

However, the real problem is that GRUB can't find your config file. First, check that you have one - it should be in /boot/grub/menu.lst by default, but some distributions put it at /boot/grub/grub.conf. If the latter is the case, make a symlink between the two and reboot to test: ln -s /boot/grub/grub.conf /boot/grub/menu.lst

If that still doesn't work, it's possible that GRUB is looking in the wrong place for your config. If you installed GRUB using something like grub-install --root-device/boot '(hd0)'= it will install to /boot/grub/ etc, however if your /boot is on a separate partition (as I described in the example above) then it's fairly likely that GRUB is looking in /boot/boot/grub/ for menu.lst -- and not finding it.

Easiest fix (it stops this happening again in the future, so perhaps the best fix?) is to symlink /boot into /boot by doing ln -s /boot /boot/. You should now be able to cd into /boot/boot/grub and it'll have your menu.lst there.

Adding a new kernel to grub

If you're building your own kernels or doing KernelDevelopment then you need to manually edit the files for grub(8) or on many distros you can run update-grub(8). One thing to note is that if you rearrange hard drives you need to edit the menu.lst file to tell it which drive is which and the kernel options before running update-grub(8). The lines needed have a hash symbol in front of them which makes them look like a comment only, but they are not a comment at all!!

Using a different kernel for the next reboot only

  savedefault --default=N --once
  (where N is the number of the kernel you want to boot once)

Reboot your machine. It will boot using kernel "N".

grub-reboot N will do essentially the same thing and prompt to reboot the machine

Using GRUB with a serial console

In the GRUB config file (normally /boot/grub/menu.lst) add these lines to the top to enable the serial console in addition to the regular console:

  serial --unit=0 --speed=9600
  terminal --timeout=10 serial console

GRUB will now display on the serial console as well as locally. It will wait for a keypress for 10 seconds to determine which input is being used, before timing out and carrying on the boot process. If a key is pressed then the regular menu will be displayed and you can select a kernel as usual.

The first line configures the serial link with the following options (defaults to 9600, 8n1 from what I can gather):

  • --unit=X which serial port to use. 0 = ttyS0, 1 = ttyS1 etc
  • --speed=X the rate in bps the serial link should run at
  • --word=X number of data bits
  • --parity=X parity to use, where X is one of 'no', 'even', 'odd'
  • --stop=X number of stop bits to use

The second line specifies which devices should be used for input/output. You can set it up so that it only displays locally, only on the serial console, or on both.

  • --timeout=X the number of seconds GRUB should wait for a keypress before continuing
  • serial if this option is present, the serial console will be used
  • console if this option is present, the local console will be used

If both serial and console are present, then grub will use whichever method accepts a keypress first

Making your kernel do serial too!

If you have GRUB setup to use a serial console then you probably want to compile your kernel with serial console support and append the following options to your boot line, so your kernel messages appear on your serial console too. If you don't do this you'll have a big empty screen between grub loading the kernel and your getty loading, when you think that your kernel has hung!


So a full kernel boot line might look like kernel /boot/vmlinuz ro root=/dev/hda1 console=tty0 console=ttyS0,19200n8

GRUB resources on the web