Cause
In version 23, the mkinitcpio resolve_device() function is called only once. When at execution time the drive labels are not yet read, blkid
can't lookup the kernel drive (/dev/...
) name for the requested label.
Solution
By adding the "without-udev" hook, as listed below, the resolve_device function is left untouched. Though standard available mkinitcpio functionality to override the mount_handler add a run_hook is used to poll until blkid
returns a value, or (a timeout of) 10 seconds has passed. Thus the "udev" hook can be removed from mkinitcpio config.
Notes
- This solution was created with the help of falconindy.
- There was an error message in the early boot phase involving fsck. To remove that message the without-udev hook has been rewritten to use a
run_hook
instead of a mount_handler
. The newer code is even shorter.
$ cat /usr/lib/initcpio/hooks/without-udev
#!/bin/ash
# Minimal initramfs files are created without udev.
# This hooks provides a polling disk mount replacement for udev.
# Udev hook can be removed, resulting in smaller initramfs files.
run_hook () {
local dev timeout sleepval device=$root
# if udev is running then exit
[ "$udevd_running" -eq 1 ] && return
# try for (timeout * sleepval =) 10 seconds to handle slow (USB) devices
timeout=1000
sleepval=0.01
case $device in
# label to resolve, when resolved the kernel block device also exists
UUID=*|LABEL=*|PARTUUID=*|PARTLABEL=*)
while [ $timeout -gt 0 ]; do
timeout=$((timeout - 1))
dev=$(blkid -lt "$device" -o device)
[ -n "$dev" ] && timeout=0 || sleep $sleepval
done
;;
# kernel named block device, poll for existence
/dev/*)
while [ $timeout -gt 0 ]; do
timeout=$((timeout -1))
if [ -b "$device" ]; then
dev=$device
timeout=0
else
sleep $sleepval
fi
done
;;
esac
}
# vim:set syntax=sh:
$ cat /usr/lib/initcpio/install/without-udev
#!/bin/bash
build() {
add_runscript
}
help() {
cat <<HELPEOF
This hook provides support for booting without the "udev" hook,
including support for UUID, LABEL, PARTUUID, PARTLABEL.
HELPEOF
}
# vim: set ft=sh ts=4 sw=4 et:
On giving this another look, it seems you have a mismatch between PARTUUID=... and UUID=... and that's what's causing this problem.
You mentioned bootloader is configured with:
options root=PARTUUID=2251a5a4-6c18-425c-9264-df971d297b09 rw
But when you manage to boot it, you actually find this UUID under /dev/disk/by-uuid
:
kodi@BB-8:~$ ls -al /dev/disk/by-uuid/
lrwxrwxrwx 1 root root 15 Jul 26 11:10 2251a5a4-6c18-425c-9264-df971d297b09 -> ../../mmcblk0p2
Furthermore, that's even listed in /proc/cmdline
of the successful boot (I'm assuming it's the one with SuperGrub USB):
/proc/cmdline
output
BOOT_IMAGE=/boot/vmlinuz-4.19.0-5-amd64 root=UUID=2251a5a4-6c18-425c-9264-df971d297b09 ro
The two UUIDs are different. PARTUUID= is the UUID that will be found in the GPT partition table (that's why it's called "PART", because it's a property of the partition, recorded in the partition table), while UUID= is a UUID recorded in the filesystem (ext4, or xfs, or whichever filesystem you formatted the partition with) and Linux is able to read those while scanning the disks.
So, it looks like you need to fix your boot options to use UUID= instead of PARTUUID=, since the UUID you have is a filesystem UUID and not a partition UUID.
Edit file /boot/efi/loader/entries/debian.conf
and replace the last line with:
options root=UUID=2251a5a4-6c18-425c-9264-df971d297b09 rw
That should fix your issue!
Make sure your /etc/fstab
in the system also matches the correct tag.
You can also use the blkid
command to inspect the UUIDs present in your partitions and filesystems. This might help you confirm that you have the correct kind of UUID.
For instance, using blkid -o export
should display something like:
$ sudo blkid -o export
DEVNAME=/dev/mmcblk0p1
SEC_TYPE=msdos
LABEL=boot
UUID=9A8B-7C6D
TYPE=vfat
PARTUUID=abcd1234-01
DEVNAME=/dev/mmcblk0p2
UUID=2251a5a4-6c18-425c-9264-df971d297b09
TYPE=ext4
PARTUUID=abcd1234-01
...
That should help you see all UUIDs with a tag that is recognized by Linux.
Best Answer
Your empty output from
cat /proc/modules
indicates you have no kernel modules loaded, so something has gone wrong with either initrd file generation when installing your current kernel, or with hardware detection as the kernel starts up.You might try running
modprobe ahci
to try and force loading the standard AHCI SATA driver, but I'd expect it to just tell you that the moduleahci
was not found.If you have other kernel versions available in your GRUB boot menu, now would be a good time to try them. If the GRUB boot menu has "Advanced options for " item, select it: it should bring up a sub-menu of all kernel versions you have installed. Typically there are two boot menu items for each kernel version: one normal boot and another for booting into recovery mode. If there is a kernel version older than 5.3.0-53 available, try the normal (non-recovery mode) option for it.
If the system now boots up normally, it confirms that there was a problem with creating the initrd file during the installation of the latest kernel update. But that should be fairly easy to fix: first run
sudo apt-get clean
to clean up the package manager's cache: anything in that cache can just be downloaded again if necessary, and over time the cache can sometimes grow very large, so cleaning it up is a good first step.Then run
df -h
and make sure that any of the filesystems on your system disks is not 100% full. Finally runsudo update-initramfs -k 5.3.0-53-generic -u
to re-build the initramfs file for the kernel version 5.3.0-53. If that command completes without any error messages, you should now be able to boot normally with the latest kernel version you have.