You find yourself in an impossible situation. Impossible in that, it's never going to happen to you.
Until it happens.
You have a Chromebook that will not boot. You discover the internal eMMC is defunct. Cracking it open, you discover the inevitable truth; the eMMC is soldered on.
After removing the WP screw, you succeed in preparing a flash drive that includes MrChromebox's BIOS for the Chromebook and a few moments later, it reboots and splashes a welcoming running rabbit.
Your favorite Linux distro now boots from a USB drive and a SD-CARD. But, you now have a new problem.
The ex-Chromebook will not suspend because the internal eMMC can't be communicated with in full, and inhibits ACPI suspend.
What now?
You learn by trial and error that after a warm reboot from a successful initramfs prompt, the internal eMMC is temporarily out of the way, and suspend works.
You now face the challenge of how to make that eMMC disappear without physical intervention.
You fiddle around with the init ramfs and arrive at a solution. You realize you're no expert, but it suffices.
You make the business portion of this bundle communicate a shutdown to plymouth, which disrupts any cryptsetup (decrypt password prompts) and follow with a call to systemctl to start the shutdown.target. An older iteration tried using pkill ^plymouth and a reboot command, but after realizing calling binaries directly is a tad abrupt, you fall back on using modernized system administrator techniques.
You drop this in /usr/lib/systemd/system
And you drop this in /usr/lib/systemd
# 2022-02-06 This ASUS C300 chromebook landing in my possession
# has a defunct internal eMMC. On cold boot, the eMMC can be
# read from the BIOS and even reaches a GRUB menu, and after
# the eMMC is enumerated by the Linux driver, a subsequent
# reboot appears to take the eMMC offline for future warm
# state reboots. This helper attempts to detect if the eMMC
# is present and reboot at least once.
printMatch () {
echo "Looks like this list qualifies for a reboot:"
echo " $(dmesg | grep mmcblk.:)"
}
plymouthShutdown () {
plymouth change-mode --shutdown
}
for W in $(cat /proc/cmdline)
do
IFS="="
for X in ${W[@]}
do
if [ ! -z $Y ]; then
if [ -e "/dev/${X}" ]; then
printMatch
plyouthShutdown
systemctl start reboot.target
fi
unset Y
fi
if [ $X = "deadmmc" ]; then
Y=1
fi
done
done
# A crude way to determine if more than one mmc is detected.
# A fall-through in case the system is not configured with
# a kernel parameter.
# In the case of an ASUS C300 Chromebook with a defunct
# mmc, the kernel enumerates the internal eMMC as
# mmcblk1
if [ ! -z "$(ls /dev/mmcblk0)" ] && [ ! -z "$(ls /dev/mmcblk1)" ]; then
echo "Example: vmlinuz ... deadmmc=mmcblk1"
printMatch
plymouthShutdown
systemctl start reboot.target
fi
You create a directory 02deadmmcreboot under /usr/lib/dracut/modules.d. Nearly done, you drop this in /usr/lib/dracut/modules.d/02deadmmcreboot
No comments:
Post a Comment