Skip to content
All writing
Note Technical

The USB Flash That Died Every Two Seconds (and the Power-Button Trap)

A bootloader flash that failed at a suspiciously consistent interval, the misdiagnosis that chased the cable, and the power-management timer that was actually killing it.


fastboot devices showed the phone. I’d kick off a flash. About two seconds in, the transfer would just stop. The device dropped off the bus. Re-plug, retry, same thing. Two seconds, gone.

So I did what everyone does. I blamed the cable. Swapped it. Then I blamed the port, moved to a different one. Then I blamed fastboot itself, then briefly the moon. None of that was it, and chasing it was a waste of an afternoon, because I was debugging the wrong layer entirely.

The kernel log was telling the real story the whole time — the fastboot interface enumerating cleanly and then vanishing a beat later:

usb 1-1: new high-speed USB device number 38 using xhci_hcd
usb 1-1: New USB device found, idVendor=18d1, idProduct=4ee0   # fastboot mode
usb 1-1: USB disconnect, device number 38                      # ...gone ~2s later

The culprit was my laptop’s xHCI USB controller doing autosuspend. Linux power management aggressively drops a USB device into a low-power state the moment it decides the link is idle. A bootloader flash has bursty traffic with brief quiet gaps, and the kernel read those gaps as “nobody’s using this, power it down.” Mid-flash. On the boot partition. The single worst moment for the link to disappear.

The fix, once I’d stopped suspecting the hardware:

# check what's enabled (2 = suspend after 2 seconds idle — there's your timer)
$ cat /sys/module/usbcore/parameters/autosuspend
2

# disable it for the session
$ echo -1 | sudo tee /sys/module/usbcore/parameters/autosuspend
-1

There it was, sitting in plain text: 2. The exact interval my flash kept dying at. That number wasn’t a coincidence about the cable or the protocol — it was a configured timer doing precisely what it was told. Set it to -1 (or usbcore.autosuspend=-1 on the kernel command line if you want it to stick) and the controller stopped helpfully sabotaging me. The flash ran clean to completion.

Here’s the lesson I keep relearning, and the reason this is worth writing down at all: when a transfer dies at a suspiciously consistent time interval, stop debugging the protocol and start debugging the power state. Consistent timing is a clock somewhere, and a clock you didn’t set is almost always power management or a watchdog. A flaky cable fails randomly. A flaky port fails when you wiggle it. A timer fails on a schedule, and a schedule is a tell.

While I’m naming dumb obstacles, here’s the second one from the same session, because it rhymes. The bootloader screen on a Pixel is navigated with the volume keys, and the power button is “select.” The default highlighted option is Start, which boots normally into Android.

So my reflexive flow was: get the phone into the bootloader, glance at the screen, press power to “wake it up / confirm I’m here”… and immediately select Start, dropping straight out of fastboot and back into Android. Then I’d plug in, see no fastboot device, and get confused about why the phone kept leaving the bootloader on its own. It wasn’t leaving on its own. I was telling it to leave, every single time, with twenty years of “press power to do something” muscle memory.

The fix was discipline, not code: get it into the bootloader, then hands off the device entirely. Drive everything from the laptop, with no window to fat-finger the wrong button:

# wait for the device to enumerate, then flash the instant it does —
# no human in the loop to press the wrong button
until fastboot devices | grep -q fastboot; do sleep 0.2; done
fastboot flash boot magisk_patched.img

Two obstacles, zero of them about cryptography or Android internals. One was the host OS being too clever about power. One was me being a primate with a thumb. Most of the friction in this kind of work is exactly that shape — environmental, dumb, and completely opaque until you name it.

This was the prelude to a longer exercise: rooting that phone to pentest my own app.

Share LinkedInXBlueskyReddit