Introduction
In early 2025, a critical change in our supply chain forced an urgent firmware migration. Samsung announced the discontinuation of one of its popular eMMC chips used in several of our embedded products. The affected module was deeply integrated into our PX30-based SBC used in consumer and industrial devices.
As a firmware engineer, I was tasked with making our U-Boot bootloader compatible with a newly sourced eMMC chip from Foresee. This involved a deep dive into U-Boot’s MMC subsystem, understanding vendor-specific behaviors, and refactoring over 2700 lines of code. This post documents the full migration process, from assessment to deployment.
Background: Why eMMC Matters in Embedded Systems
eMMC (embedded MultiMediaCard) is a type of non-volatile storage used in many embedded systems. It offers a balance of performance, cost, and integration ease. For bootloaders like U-Boot, the eMMC chip is critical because it's often the first non-volatile storage accessed during boot.
Samsung's eMMC line, particularly the KLMAG1JETD, was used in many industrial and consumer products for its reliability and mature driver support. When that line shut down, replacement chips introduced minor electrical and protocol differences that broke compatibility with our existing U-Boot.
Step 1: Assessing the Hardware Differences
Our hardware team shortlisted three candidates:
Foresee NCEMBS99-32G
Kingston EMMC32G-M525
Longsys/AISINO eMMC-5.1 32GB variant
We ran read/write performance tests and compatibility checks on a Linux system using mmc-utils. Foresee’s model was selected based on availability, performance, and electrical stability.
Step 2: Understanding U-Boot’s eMMC Stack
U-Boot accesses eMMC via the MMC subsystem located in drivers/mmc/. It abstracts host controllers and devices using standard commands like CMD0, CMD1, CMD8, ACMD6, etc. However, quirks exist between vendors, especially in timing and initialization sequences.
The new chip failed to boot, hanging on:
mmc_send_op_cond: timeout waiting for OCR
Upon debugging, we found that the Foresee chip required more aggressive clock delay tuning and did not respond to CMD8 the same way Samsung’s did.
Step 3: Refactoring the Initialization Logic
We created a new quirk in mmc.c to differentiate Foresee chips using their CID manufacturer ID.
if (cid[0] == 0x70) { // Foresee
host->quirks |= MMC_QUIRK_NEED_CLOCK_DELAY;
}
We also modified mmc_set_ios() and mmc_send_op_cond() to increase the retry timeout and include Foresee-specific delay logic using udelay(500).
Step 4: Clock and I/O Tuning
The Foresee eMMC struggled with UHS timing modes during initial negotiation. We downgraded the timing to legacy DDR52 mode via:
mmc->timing = MMC_TIMING_LEGACY;
We also adjusted the host controller’s clock divider from 1:4 to 1:8 until stability was confirmed during multiple cold boots.
Step 5: Device Tree Bindings
Though U-Boot doesn’t always require full device tree support for MMC, we updated the board’s px30-u-boot.dtsi:
mmc@fe310000 {
clock-frequency = <100000000>;
disable-cmd23;
no-sd;
};
This ensures that downstream Linux kernel inherits the correct settings post-boot.
Step 6: Testing Strategy
We validated the changes with the following matrix:
Cold boot from power-off (30 cycles)
Warm reboot (50 cycles)
System update + reboot (5 test images)
Simulated power loss during write (using inline GPIO reset)
Performance benchmarks using bonnie++
We also flashed 10 boards for temperature testing in -10°C to 60°C to ensure no thermal instability.
Outcome and GitHub Repository
The modified U-Boot now supports both Samsung and Foresee eMMC seamlessly. These changes are shared on GitHub under a public migration branch.
Lessons Learned
Even with eMMC standards, vendor-specific quirks can break boot completely.
Reading and understanding the MMC spec helped pinpoint the root issue quickly.
Clock tuning and retry logic are vital when working with newer eMMC modules.
Always simulate real-world failure modes like partial writes and voltage dips.
This project reminded me that bootloader work, though often invisible, is foundational to system stability. Migrating to new hardware isn’t just plug-and-play—it requires deep system understanding, structured debugging, and methodical testing.
This post is written by Kevin Zhang, an engineer working on Rockchip-based SBCs and industrial HMI solutions.
You can find additional device tree examples and SBC-level configurations on this embedded hardware & TFT Display dts file config.
Top comments (0)