rpi-update ate my SD card
Preamble
Some time ago, I'd re-configured the Raspberry Pi to use a USB stick
as the root directory, by changing the default kernel boot
parameters in /boot/cmdline.txt to this:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 \
console=tty1 root=/dev/sda2 rootfstype=ext4 elevator=deadline rootwait
The vital addition is root=/dev/sda2. The rationale is to
reduce the usage of the SD card, which has a reputation for dying a
lot faster than a USB stick.
Where did my modules go?
I noticed an issue shortly after I'd performed an apt-get update
&& apt-get upgrade of the Raspberry Pi. The little script I
had to take pictures using USB camera, a Logitech C270, failed to
work, complaining that no /dev/video0 existed. And it was
right. Hmm, what had the upgrade done? The USB camera was detected
by the module uvcvideo. Except that, according to
lsmod, there were no modules loaded at at all. uname
-a showed me I was running a 3.6.11 kernel, yet in
/lib/modules I only had modules for 3.6.25. How did this
happen?
After some research, I belatedly realised than the kernel image and
associated modules for Raspbian was actually updated by a process
called rpi-update, not via apt-get. However, this
doesn't explain how I ended up with a mismatch; had I run
rpi-udpate when /dev/sda2 was not mounted and
forgotten? Well, it is possible. Anyway, should be a simple fix
then. I ran rpi-update, which appeared to work without
problem. On reboot however, I could not ssh to the pi. The
console messages showed me:
PANIC: VFS: Unable to mount root fs on unknown-block(179,2)
I pulled the SD card and mounted it on the Debian system.
fdisk showed this:
[mark@amber:~] sudo fdisk /dev/sdf Command (m for help): p Disk /dev/sdf: 4025 MB, 4025483264 bytes 4 heads, 16 sectors/track, 122848 cylinders, total 7862272 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x0007b745 Device Boot Start End Blocks Id System /dev/sdf1 2048 2490234 1244093+ e W95 FAT16 (LBA) /dev/sdf2 2490368 7796735 2653184 85 Linux extended /dev/sdf3 7796736 7862271 32768 83 Linux /dev/sdf5 2498560 2621439 61440 c W95 FAT32 (LBA) /dev/sdf6 2629632 7796735 2583552 83 Linux
Now that didn't look right. We now have this setup:
/dev/sdf1 (aka /dev/mmcblk0p1) boot/recovery partition /dev/sdf3 (aka /dev/mmcblk0p3) settings partition (related to noobs?) /dev/sdf5 (aka /dev/mmcblk0p5) boot partition (unused) /dev/sdf6 (aka /dev/mmcblk0p6) root partition
When booted, /dev/mmcblk0p1 is mounted as /boot on
the runnning system.
I had a spare pi SD card; it looked like this:
Disk /dev/sdf: 15.9 GB, 15931539456 bytes 64 heads, 32 sectors/track, 15193 cylinders, total 31116288 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x0002c262 Device Boot Start End Blocks Id System /dev/sdf1 8192 122879 57344 c W95 FAT32 (LBA) /dev/sdf2 122880 31116287 15496704 83 Linux
More digging around. The standard layout of the SD card has the
first partition (mmcblk0p1) as the boot partition (kernel
images etc), while mmcblk0p2 is the root filesystem.
Except that, the kernel should be using /dev/sda2 as the
root fs. OK, the first partition did indeed contain all the
standard boot images, but no cmdline.txt. Ah, then the
kernel must be falling back to the default root partition of
/dev/mmcblk0p2, which clearly was not going to be happy
with a Linux extended partition. I copied cmdline.txt (with
the root redirection to /dev/sda2) from /dev/sdf5
to /dev/sdf1 and re-inserted the SD card back into the PI
and booted.
Successful boot!
Addendum
From this
post on the Raspberry Pi site it appears you can drop a file
called autoboot.txt in the first partition, which then
tells the boot process to use a different partition as the boot
partition. The contents should look like:
boot_partition=5
And this does indeed seem to work.