38

My system boots OK with this in my GRUB 2 config:

linux   /bzImage root=/dev/sda2 init=/usr/lib/systemd/systemd ro

But if I replace /dev/sda2 with the corresponding UUID:

linux   /bzImage root=UUID=666c2eee-193d-42db-a490-4c444342bd4e init=/usr/lib/systemd/systemd ro

then it fails during boot:

kernel panic - not syncing: VFS: unable to mount root fs on unknown-block(0,0)

The UUID appears to be correct:

# blkid
/dev/sda1: UUID="97ac3744-39de-4d6d-9a81-e3a3ea08a8bb" TYPE="ext2" 
/dev/sda2: UUID="666c2eee-193d-42db-a490-4c444342bd4e" TYPE="ext4" 

Why doesn't it work? Is it because I'm not using an initramfs?

This is x86_64 Gentoo Linux with kernel 3.10.7. I'm using a MBR partition table on sda and a GUID partition table on sdb.

6
  • unknown-block(0,0) looks like a GRUB device to me. my guess is that GRUB can't use that UUID for some reason.
    – strugee
    Oct 6, 2013 at 4:29
  • @strugee, I don't think GRUB attempts to interpret the kernel command line at all. (GRUB is loading the kernel from sda1. I didn't show that part of the config.)
    – cjm
    Oct 6, 2013 at 4:32
  • I'm inclined to agree. it's weird, though, that the device looks like a GRUB device instead of a UNIX device.
    – strugee
    Oct 6, 2013 at 4:34
  • @Gilles, the question isn't about GRUB. That just happens to be the bootloader I'm using. It's a Linux kernel question.
    – cjm
    Oct 7, 2013 at 19:31
  • This isn't a question about the kernel either - this is a question about init.
    – mikeserv
    Aug 21, 2014 at 22:48

3 Answers 3

36

Just to clarify UUIDs are the only reliable way for the kernel to identify hard drives. There are two types: UUID, which is stored in the filesystem and is not available to the kernel at boot-time, and PARTUUID, which is stored in the partition table and IS available at boot time. So you have to use

root=PARTUUID=SSSSSSSS-PP

as /dev/sd?? can change with devices plugged/unplugged.

Don't forget to capitalize the hexadecimal number SSSSSSSS-PP you get from blkid!

The more easy to use

root=LABEL=
root=UUID=

only work with an initramfs that fetches these identifiers.

So, if you use a non-empty initramfs, you can have all three! With an empty initramfs, you only have PARTUUID.

9
  • Mind to explain who is using the boot=-argument then? I just used this line for an Archlinuxarm installation that doesn't have initrd, and where I can't use boot=LABEL nor boot=UUID.
    – ineiti
    Aug 21, 2014 at 22:48
  • 1
    You're right - I corrected the boot to root, sorry! Hope it makes more sense now.
    – ineiti
    Aug 21, 2014 at 22:57
  • 1
    My understanding (after one day on the forums of archlinuxarm) is that there is no initrd (or initramfs, but kernel.org/doc/Documentation/kernel-parameters.txt calls it initrd) on Archlinuxarm. On Ubuntu and such I do give a pointer to initrd, but (as to my understanding) not on Archlinuxarm.
    – ineiti
    Aug 22, 2014 at 6:54
  • 1
    Archlinuxarm discussion about NO initrd: archlinuxarm.org/forum/viewtopic.php?f=23&t=6652
    – ineiti
    Aug 22, 2014 at 7:18
  • 2
    Try this link. And this one. And maybe this one. initramfs is not the initramfs image - which is usually a compressed archive containing a cpio archive that the kernel unpacks to / at boot. initramfs is a filesystem - it is always the first / mounted and from whence the kernel calls init. You can compile the contents into the kernel or unpack them at boot - those are the two options.
    – mikeserv
    Aug 22, 2014 at 7:33
22

The parameter you have to pass to boot from UUID is PARTUUID. So it should be root=PARTUUID=666c2eee-193d-42db-a490-4c444342bd4e.

The documentation explains why it's coming back with unknown-block(0,0):

kernel-parameters.txt:

    root=       [KNL] Root filesystem
            See name_to_dev_t comment in init/do_mounts.c.

init/do_mounts.c:

/*
 *  Convert a name into device number.  We accept the following variants:
 *
 *  1) device number in hexadecimal represents itself
 *  2) /dev/nfs represents Root_NFS (0xff)
 *  3) /dev/<disk_name> represents the device number of disk
 *  4) /dev/<disk_name><decimal> represents the device number
 *         of partition - device number of disk plus the partition number
 *  5) /dev/<disk_name>p<decimal> - same as the above, that form is
 *     used when disk name of partitioned disk ends on a digit.
 *  6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the
 *     unique id of a partition if the partition table provides it.
 *     The UUID may be either an EFI/GPT UUID, or refer to an MSDOS
 *     partition using the format SSSSSSSS-PP, where SSSSSSSS is a zero-
 *     filled hex representation of the 32-bit "NT disk signature", and PP
 *     is a zero-filled hex representation of the 1-based partition number.
 *  7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
 *     a partition with a known unique id.
 *
 *  If name doesn't have fall into the categories above, we return (0,0).
 *  block_class is used to check if something is a disk name. If the disk
 *  name contains slashes, the device name has them replaced with
 *  bangs.
 */

The last bit at the end says that if it can't understand the value, it returns (0,0), hence your error.

5
  • 8
    So I guess that the real answer is that the kernel does not support root=UUID, only root=PARTUUID. If you want to use a filesystem UUID, I guess you need an initramfs that can handle mounting filesystems by UUID.
    – cjm
    Oct 6, 2013 at 5:48
  • 1
    @cjm my grub boots quite happily with root=UUID.
    – terdon
    Oct 6, 2013 at 14:30
  • 3
    @terdon, I'll bet you have an initramfs or initrd. (It could be linked into your kernel instead of being a separate file.)
    – cjm
    Oct 6, 2013 at 14:59
  • 2
    Since 4.20, there's also support for PARTLABEL <github.com/torvalds/linux/blob/v4.20/init/do_mounts.c>, which I think is really convenient. Perhaps update the answer.
    – equaeghe
    Jan 20, 2021 at 11:13
  • PARTLABEL= only works for GPT partition tables (MBR doesn't support labels on partitions themselves).
    – Tom Hale
    Feb 23, 2022 at 7:00
5

This is a 5 year old thread. But still it is imho not fully answered. There's a little example missing. Here it is:

In this example:

/dev/sda3 = /
/dev/sda2 = swap

...using a GPT partition. With MBR (dos partition) the PARTUUID's are shorter but the procedure is the same...

get the PARTUUID's with blkid:

blkid -s PARTUUID -o value /dev/sda3 # root
77fd7830-faa2-4e99-a48b-337ad9eded28
blkid -s PARTUUID -o value /dev/sda2 # swap
5b63167a-6fd2-4e72-948c-90832372956c

/boot/grub/grub.cfg:

search --no-floppy --part-uuid --set=root 77fd7830-faa2-4e99-a48b-337ad9eded28

menuentry "GNU/Linux, KERNEL 4.12.7-lfs-8.1" {
  linux /boot/vmlinuz-4.12.7-lfs-8.1 root=PARTUUID=77fd7830-faa2-4e99-a48b-337ad9eded28 net.ifnames=0 ipv6.disable=1 ro rootwait rootfstype=ext4
}

/etc/fstab/:

PARTUUID=77fd7830-faa2-4e99-a48b-337ad9eded28 / ext4 noatime,nodiratime,errors=remount-ro 0 1
PARTUUID=5b63167a-6fd2-4e72-948c-90832372956c swap swap pri=1 0 0

This is known to WORK with lfs8.1 (kernel 4.12.7) But i think it should work with most other kernels too (olders and newers...)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .