I don't want grub to "search" for anything. I know where my root file system is, and it will always be there (/dev/sda1), and I don't want grub to go looking at all the connected drives to find some other root (it seems to always finds the wrong one).

I have been able to disable UUID use in the kernel-loading line with:


in /etc/default/grub, but the resulting /boot/grub/grub.cfg still has lines like:

search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  3f8c2b36-5d8f-40ac-9b63-7d1445805925

and I don't want those. I don't want it to search at all. I further turned off "os-probing" with:


which keeps it from finding backup copies of my system on other attached disks, but I don't want ANY instance of the search command in grub, let alone with UUIDs that I already told it not to use.

I hate grub. I just want my machine to boot with root=/dev/sda1, without probing all over my system, without looking for UUIDs that might not be there, without anything. Like it used to boot in 1999, with LILO.

I would actually use LILO or syslinux or something if it weren't for the fact that Ubuntu uses grub, and therefore if I want to be able to keep up with their kernel updates, I'm pretty much forced to use it. I just want it to be the simplest configuration humanly possible (which I know is still going to result in a 200-line grub.cfg, but oh well).


That's how grub-mkconfig works: it automatically creates GRUB menu entries for every kernel it discovers. However, if you know what you want and what you are doing, you don't need to use Simple configuration at all, as you can write your grub.cfg directly.

grub-mkconfig does have some limitations. While adding extra custom menu entries to the end of the list can be done by editing /etc/grub.d/40_custom or creating /boot/grub/custom.cfg, changing the order of menu entries or changing their titles may require making complex changes to shell scripts stored in /etc/grub.d/. This may be improved in the future. In the meantime, those who feel that it would be easier to write grub.cfg directly are encouraged to do so (see Booting, and Shell-like scripting), and to disable any system provided by their distribution to automatically run grub-mkconfig.

There, you could have only a single menu entry (disabling the menu) with as simple settings as you wish. You can tell that you want to boot this kernel from here and that's it.

A single menuentry { } can be like 5 lines, not 200.

Keep in mind:

  • Test your custom menu entry first by adding it to custom entries.
  • If you disable grub-mkconfig from your system you'll need to update your grub.cfg manually whenever you want to update your kernel.
| improve this answer | |

The information that your root filesystem is /dev/sda1 is actually completely useless for GRUB, other than as part of a kernel boot parameter string root=/dev/sda1 which is passed to the Linux kernel as-is.

What GRUB needs to know is which identifier it needs to use for the disk in the system firmware calls when loading its own configuration file, any GRUB modules that are not embedded in GRUB core image, the kernel, and the initramfs file.

In a classic BIOS-based system, the fundamental form of this identifier is hexadecimal byte: 0x80 refers to the first disk detected by the BIOS, 0x81 to the second, etc. GRUB maps these to its own identifiers: (hd0) is 0x80, (hd1) is 0x81 and so on.

In an UEFI system, you might be able to run an UEFI shell and use its map command to see the UEFI partition identifiers in the order firmware detects them: the first partition with a UEFI-recognizable filesystem will be fs0:, the second fs1: and so on. Whole disks and raw partition access is via identifiers like blk0:. These (or their machine-readable UEFI API equivalents) are what an UEFI version of GRUB must use to identify the disk or partition it wants to load something from. GRUB mostly uses its own filesystem drivers, so it maps the blkN: identifiers of the firmware to (hdN).

The search command

search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1

means that according to the best information available to the grub-mkconfig command (which can be just a best guess, particularly with BIOS-based systems) the partition that contains the files needed by subsequent commands will most likely be (hd0,msdos1) at boot time, assuming the hardware configuration won't change after writing the configuration file.

--set=root tells you that the purpose of this search command is to set GRUB's root variable to point to whatever partition is the result of this search.

So if you know that the files needed by whatever comes after this search command are on the first partition of a disk that will always be detected as the first disk by the firmware, then you can replace this search command with:

set root=(hd0,msdos1)

Note: setting GRUB's root variable has nothing at all to do with the root filesystem for the Linux kernel. Its only purpose is to define the root path (including the disk/partition) for any subsequent GRUB commands that refer to files on disk using path names.

With a classic BIOS-style boot process, the only thing you can be reasonably sure about is that whatever disk has been selected as bootable in the BIOS settings (and the BIOS is currently trying to boot from, if there are multiple disks listed in the boot order) will be accessible as BIOS disk 0x80... and so for GRUB, it will be (hd0).

And, by the way, Debian and Ubuntu "use GRUB" only in the sense that it is the default bootloader. If you wish, you can rip out GRUB and replace it with your favorite bootloader. The only requirement is that you write your own scripts for updating its configuration in the appropriate directories under /etc/kernel/: for GRUB, these scripts are /etc/kernel/postinst.d/zz-update-grub and /etc/kernel/postrm.d/zz-update-grub. These are the only connection between the package management system and GRUB configuration.

Any time a new kernel package is installed or removed, all the scripts in the respective directory will be executed: if you place a script that runs lilo in the postinst.d and preinst.d directories, you can use LILO just about as seamlessly with Ubuntu's updates as GRUB is used by default.

In 2012, I had a system with an early UEFI implementation that had a firmware bug that caused problems for GRUB at that time; I found out that rEFInd could avoid that bug, so I used this to replace Debian's GRUB with rEFInd. Even though the firmware has since then been updated to a fixed version, and GRUB has gained many workarounds for UEFI bugs, I've kept the simple scripts I wrote back then in place as a backup bootloader; the scripts have worked for 8 years.

Modern versions of Debian actually package rEFInd and include similar scripts right in the package. So may other bootloader packages included in the distribution: if there's a package for LILO or Syslinux in Ubuntu, you might try installing it and see if the package includes kernel postinstall/postrm scripts for it. If it does, you might find that it "just works."

If you are in the habit of cloning disks or filesystems, you might want to consider changing the UUIDs of the new clones if they are going to be presented to the computer together with the originals. This question has plenty of advice for that.

In an enterprise environment with SAN-level snapshots with LVM, you must re-uniquify the clones immediately after creating them or else you will be in a world of hurt if the clone and the original are ever presented to the same system (been there, fixed the mess, vgimportclone is your friend). In any other type of environment, it might still be a good idea.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy