raspian-ua-netinst: jessie won’t boot after rpi-update?

Update: Raspbian now includes support for the Raspberry Pi 2; the linux-image-rpi2-rpfv metapackage installs the raspbian kernel for Raspberry Pi 2, and automatically creates an initramfs during installation.

TL;DR I learn that the linux kernel has never supported LABEL= or UUID= root devices, it was being done by initramfs all along.

My Raspberry Pi 2 is on its way! :D

The plan is to use the microSD card from my old Model B, just drop in the new hardware. However, the Raspberry Pi 2 requires the latest firmware.

The current OS is raspian jessie, installed using raspian-ua-netinst. It’s just using the default kernel (linux-image-3.12-1-rpi), with the default firmware (raspberrypi-bootloader-nokernel), both installed using apt-get. However, this won’t suport the Raspberry Pi 2.

I need to install the latest firmware using rpi-update:

apt-get install rpi-update
rpi-update

All successful; no errors.

After rpi-update completes, the /boot folder now contains a second kernel, kernel7.img, which will be used by the Raspberry Pi 2. However, the Raspberry Pi 2 hasn’t arraived yet, so I keep using kernel.img for the current Raspberry Pi.

I update /boot/config.txt, set kernel=kernel.img and remove the initramfs entry (since rpi-update doesn’t make one).

All good, right? Time to reboot.

Nothing.

No disk activity on the root device (an external USB HDD, one of many attached to the system via a powered USB hub).

Hmm. I pop out the SD card and revert back to vmlinuz-3.12-1.rpi (and initramfs). Works fine. Hmm. I switch back to the new kernel.img. Won’t boot. Hmm.

I change root=UUID= to root=/dev/mmcblk0p2. Works fine. With the new kernel.

I change it back to root=/dev/sda1. It doesn’t boot, still no activity on the root device. However, there is some activity on one of the other USB devices. Progress!

I boot using /dev/sda1 again, but this time I remove all the other USB devices first. Success! It boots fine!

Ok, so root=/dev/sda1 works fine, but root=UUID= does not. I have a booting system, but I have to remove all USB devices every time I reboot. But what if I’m not onsite? Or what if there’s a power outage? I need to be able to reboot the box without physical access. So why doesn’t root=UUID= work?

Apparently, UUID and LABEL aren’t supported by the linux kernel. They never have, not on your kernel or mine.

But I’ve been using root=LABEL=/ for years!

The kernel doesn’t support it. The initramfs is what allows UUID and LABEL.

And that explains why the rpi-update kernel can’t find the root device: it doesn’t create an initramfs!

Easy fix

sudo update-initramfs -c -k 3.18.5+

And then set initramfs initrd.img-3.18.5+ in /boot/config.txt

The initramfs will need to be updated every time the kernel is updated. To be on the safe side, I’ve renamed kernel.img; if I forget to update-initramfs before rebooting, at least it’ll still boot.

Other options:

  • If you only have one external USB device, then root=/dev/sda1 will work fine—just make sure you unplug other USB storage before rebooting!
  • If you’re booting from a GPT disk, then you might be able to use root=PARTUUID= instead. (This is supported by the kernel—it’s needed for native UEFI boot).