Porting Linux’s EXT4 to U-Boot: Introducing ext4l

In the world of bootloaders, balance is everything. We need enough functionality to load an OS, but we must keep the footprint small and the code maintainable. For years, U-Boot has relied on a custom implementation of the EXT4 filesystem. However, as the EXT4 format evolves with features like metadata checksums and fast commits, keeping a custom implementation in sync with the Linux kernel becomes a monumental task.
Today, we are excited to share a major milestone in U-Boot’s filesystem support: the introduction of ext4l.
What is ext4l?
The ext4l driver (the ‘l’ stands for Linux) is a direct port of the Linux kernel’s EXT4 driver (from v6.18) into U-Boot. Instead of rewriting the logic, we have imported the actual kernel source files—including super.c, inode.c, mballoc.c, and the jbd2 journaling layer—and provided a thin compatibility shim to make them “feel at home” in U-Boot.
Why This Approach?
- Feature Parity: By using the real kernel code, we gain immediate support for modern EXT4 features like extents, flex_bg, and CRC32C metadata verification.
- Maintainability: When the Linux kernel community fixes a bug or adds an optimization, we can pull those changes into U-Boot with minimal friction.
- Reliability: We are leveraging code that has been battle-tested on millions of production servers and devices.
The Engineering Journey: Stubs and Shims
Porting kernel code to a bootloader is no small feat. The Linux kernel assumes a rich environment of threads, complex memory management, and a full VFS (Virtual File System) layer. U-Boot, by comparison, is largely single-threaded and simplified.
To bridge this gap, we developed a sophisticated compatibility layer:
ext4_uboot.h&stub.c: These files provide the “glue.” They map kernel structures likestruct super_blockandstruct inodeto U-Boot’s block I/O layer.- Dummy Shrinkers & Mutexes: Since U-Boot doesn’t have the same memory pressure or concurrency requirements, we implemented “no-op” or dummy versions of kernel infrastructure like the memory shrinker and various locking primitives.
- Buffer Cache: We added a
buffer_headI/O infrastructure to support caching, which significantly improves read performance during the boot process.
Key Milestones in the Patch Series
The journey to a successful mount was achieved through a systematic build-up of the filesystem stack:
| Component | Description |
| The Foundation | Importing core files from Linux 6.18 (inode.c, extents.c, super.c). |
| JBD2 Support | Porting the Journaling Block Device layer to ensure compatibility with journaled filesystems. |
| The Glue | Implementing sb_getblk, sb_bread, and brelse to connect the kernel code to U-Boot’s disk drivers. |
| The Fixes | Resolving critical issues in rbtree implementations and implementing the Castagnoli CRC32C algorithm for checksums. |
| Success | The final commit ee3d2214 enables successful read-only mounting, allowing U-Boot to see the root dentry and traverse the filesystem. |
Current Status
As of the latest commits, ext4l is capable of:
- Mounting EXT4 filesystems in read-only mode.
- Verifying metadata via CRC32C.
- Using the extent status cache for efficient file lookups.
- Toggling debug output via
CONFIG_EXT4L_DEBUG.
While the long-term goal is to support write operations (the mballoc and transaction code is already building), we are prioritizing rock-solid read support for the current release.
How to Try It
You can enable the new driver in your board configuration by selecting:
CONFIG_FS_EXT4L=y
This will replace the legacy EXT4 implementation with the Linux-ported version. We encourage developers to test this on various hardware and provide feedback on the mailing list.
A special thanks to Claude Opus 4.5 for co-developing these patches and assisting with the extensive stubbing required to bring this to life.