37

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

33

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
  • 1
    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
20

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
  • 7
    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
  • 1
    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 at 7:00
4

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...)

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.