newerkey notes
// Home Lab · 28 May 2026 · 4 min read
Home Cluster · part 1

From microSD to SSD Boot on Raspberry Pi 4

A four-hour debugging session: JMicron UAS incompatibility, a malformed cmdline.txt, and a UUID mismatch that would have bricked the boot.

raspberry-pi hardware linux debugging home-lab

The microSD card that shipped with my Raspberry Pi 4 was fine for getting started. Not fine for running a Kubernetes cluster. At 40 MB/s read speed it was already at its ceiling. An SSD was the obvious next move.

This is what happened when I tried to make that switch.


The Goal

Move the Pi off its microSD card and boot entirely from a 256GB Intenso SSD connected via USB. The SSD should be the primary boot device — the microSD removed after migration.

Total time expected: 30 minutes. Total time actual: four hours.


Problem 1: The SSD That Could Barely Read

After cloning the system to the SSD and plugging it in, I checked the read speed:

sudo hdparm -t /dev/sda
# Timing buffered disk reads: 3 MB in 23.48 seconds = 127 kB/s

127 kB/s. For a modern SSD.

The problem: the Intenso SSD uses a JMicron USB bridge controller that has known incompatibility with the Linux UAS (USB Attached SCSI) driver. UAS should be faster, but the JMicron controller misidentifies itself in a way that causes the driver to fall back to an extremely slow mode.

The fix is a kernel quirk that forces the device to use the usb-storage driver instead:

sudo nano /boot/firmware/cmdline.txt

Add to the end of the single line:

usb-storage.quirks=152d:0579:u

Where 152d:0579 is the USB vendor:product ID for the JMicron controller (confirmed via lsusb), and :u disables UAS for this device.

After reboot:

sudo hdparm -t /dev/sda
# Timing buffered disk reads: 910 MB in  3.00 seconds = 303.16 MB/s

303 MB/s. A 2,380× improvement.


Problem 2: A Typo in cmdline.txt That Caused a Grey Screen

During the first attempt to add the quirk, I made a typo — 152d:u instead of 152d:0579:u. The Pi booted to a grey screen and hung.

After recovering by editing cmdline.txt from another machine:

# Verify with cat -A — critical on cmdline.txt
cat -A /boot/firmware/cmdline.txt

The cat -A output shows control characters and end-of-line markers. This revealed a second problem: a trailing newline at the end of the file. On Raspberry Pi OS, cmdline.txt must be a single line with no trailing newline. A newline at the end breaks the bootloader’s parser entirely.

Fix: remove the trailing newline, verify with cat -A that the file ends in $ with no extra characters.

Verify configuration files with cat -A to detect hidden characters. End-of-line issues are invisible in a regular cat or text editor.


Problem 3: The UUID Mismatch That Would Have Bricked the Boot

After the clone and the quirk were both working, I was about to remove the microSD. I checked cmdline.txt one more time:

cat /boot/firmware/cmdline.txt

The root=PARTUUID= value still pointed to the original microSD’s root partition UUID. The rpi-clone tool had cloned the filesystem but hadn’t updated the partition UUID reference in cmdline.txt.

If I had removed the microSD at this point, the Pi would have failed to find its root partition and dropped to an emergency shell — or just hung.

Fix: get the SSD’s actual root partition UUID and update cmdline.txt:

# Find the SSD root partition UUID
sudo blkid /dev/sda2

# Edit cmdline.txt and replace the PARTUUID value
sudo nano /boot/firmware/cmdline.txt

After verifying the correct UUID was in place, the microSD could safely be removed.


The Full Working cmdline.txt

console=serial0,115200 console=tty1 root=PARTUUID=6692b3d6-02 rootfstype=ext4 fsck.repair=yes rootwait usb-storage.quirks=152d:0579:u cgroup_memory=1 cgroup_enable=memory cgroup_enable=cpuset

One line. No trailing newline. Verified with cat -A.


What the Pi Looks Like Now

  • Boot device: 256GB Intenso SSD
  • Read speed: 303 MB/s (up from 127 kB/s)
  • SSH: passwordless via Ed25519 keys
  • microSD: removed

Ready for Kubernetes.


What I Learned

When a tool isn’t working, sometimes the most productive thing is to abandon it. rpi-clone was supposed to handle the partition UUID — it didn’t. Knowing when to stop debugging a tool and do the step manually is a judgment call that saved another hour.

cat -A before you reboot. Any configuration file that controls boot behaviour should be verified for hidden characters before you commit. A trailing newline in cmdline.txt is invisible to the eye and catastrophic to the bootloader.

Validate assumptions about tool behaviour. rpi-clone completed with no errors. I assumed it was correct. It wasn’t. Verify the critical paths yourself.


Next: Installing K3s and the First Pod

raspberry-pi hardware linux debugging home-lab

// newerkey notes

Engineering notes on Linux, infrastructure, automation, and platform systems — written as I learn and build.

about these notes