While I was doing my daily search for interesting things to write about, I came across this page in the AOSP documentation that lists all the file systems supported by the kernel. I don’t remember what led me to that page (I just randomly click on things until I find something interesting), but I remember what stuck out to me: the line about exFAT being supported in kernel 5.10 and later. I remembered that several years back, proper exFAT support made its way to the mainline Linux kernel, so it was only a matter of time for support to arrive on all Android devices. Many people in the Android space (myself included) must have forgotten about this, though, since it takes a while for new Linux kernel features to trickle down to Android devices because of the way Android is architected (though things are getting better).
Fortunately, something like exFAT support is really easy to test, so all I had to do was find an Android device with Linux kernel 5.10 or later to test on. The Pixel 6 series fits the bill, and they’re the perfect devices to test on because no Google phone to date has had native support for exFAT. When I inserted an exFAT-formatted USB-C flash drive into a Pixel 6 Pro running the latest stable Android 12L build, however, it wasn’t recognized. I then inserted the same flash drive into another Pixel 6 Pro running the Android 13 beta, and voilà, it worked!
Naturally, I wondered why my exFAT-formatted flash drive was recognized on a Pixel 6 Pro running Android 13 but not Android 12L. Could it be the kernel? The kernel release on the Pixel 6 Pro running 12L is 5.10.81-android12-9 while on the Pixel 6 Pro running 13 it’s 5.10.107-android13-4. (If you’re wondering what each value in the kernel release string represents, this page explains it pretty well.) The kernel that comes with the Android 13 beta is slightly newer, but both kernels ship with the exFAT driver.
After a bit of digging, I discovered what the Android 13 beta had that the stable Android 12L build didn’t that allowed for native exFAT support. From what I can see, there’s no reason why the Pixel 6 series couldn’t have supported exFAT drives at launch, because there’s actually nothing special about Android 13 that enables support for them. In this week’s edition of Android Dessert Bites, I’ll talk briefly about the history of exFAT in Linux and explain how support for it is enabled in Android.
exFAT: From proprietary to open
exFAT, which stands for Extensible File Allocation Table, is the successor to the FAT32 file system. Compared to FAT32, exFAT has a higher file size limit (16 exabytes versus 4GB) and optimizations for flash memory devices like USB flash drives and SD cards. Since its introduction in 2006, the file system has been used by millions of devices. The SD Association even calls for all SDXC cards over 32GB in capacity to be formatted in exFAT.
Because exFAT is used in so many removable storage devices, it’s especially important that all platforms you’d plug those storage devices into support the file system. After all, removable storage devices are meant to be read and written to from multiple devices. The problem with supporting exFAT is that it’s a proprietary file system, developed and patented by Microsoft. In order to ship exFAT support in your device, you’d need to pay a licensing fee to Microsoft. Given the widespread use of exFAT in consumer storage devices, many Android OEMs bit the bullet and paid Microsoft so they could ship exFAT support in their phones and tablets.
Some OEMs like Samsung wrote their own exFAT drivers after paying the licensing fee, while others integrated solutions from Microsoft’s partners Paragon Software or Tuxera. Paragon Software even directly offers an app to end consumers that enables mounting exFAT drives without system integration, but the app requires an in-app purchase to unlock support for each supported file system. Either way, someone has to pay to support exFAT, whether that be the consumer or the OEM (which trickles down to the consumer anyway).
The situation changed in August of 2019, when Microsoft published the technical specification for exFAT and endorsed its addition to the Linux kernel. While Microsoft still holds patents on exFAT, its announcement means that the thousands of members of the free-to-join Open Invention Network — of which Microsoft is a part of — can freely use the technology in their Linux-based products as it’s covered under the OIN’s Linux System definition.
Immediately following Microsoft’s announcement, an old version of Samsung’s exFAT Linux driver that was in legal limbo for years was submitted to the staging area of Linux 5.4. Many kernel maintainers were unhappy with the code quality of the old driver, however, so several alternative implementations started to pop up, one of which was from Paragon Software. Eventually, though, the Linux kernel community settled on a newer exFAT driver developed by Samsung, the same one they’ve been shipping on their own products already. Samsung’s implementation of Microsoft’s exFAT officially landed in Linux 5.7.
Enabling exFAT in Pixel: An unnecessary wait?
With a Microsoft-endorsed exFAT driver finally available in the upstream Linux kernel, shipping exFAT support in Android became a lot less complicated for Google and OEMs. Since an Android Common Kernel fork of Linux kernel 5.7 doesn’t exist, the first ACK branch to include the new exFAT driver was based on Linux 5.10, hence the line mentioned at the beginning of the article about exFAT being supported in kernel 5.10 and later. CONFIG_EXFAT_FS has been set in GKI builds for over a year now, including kernels based on the android12-5.10 branch, which is why the kernel on my Pixel 6 Pro running Android 12L reports support for exFAT. However, there’s one missing piece of the puzzle to actually get Android to mount exFAT drives, and it involves vold.
Vold is short for “volume daemon”, and it’s the service that handles the mounting and unmounting of storage media. Vold actually added basic support for exFAT all the way back in early 2018, provided it detects that the kernel supports it and “helper binaries” are present. Those “helper binaries” are mkfs.exfat and fsck.exfat, tools that respectively build and check the consistency of exFAT file systems. They’re included as part of exfatprogs, a set of userspace utilities for creating, fixing, and debugging exFAT file systems. If those helper binaries aren’t detected, then the file system check will fail, and the volume won’t be mounted.
If you haven’t guessed by now, those helper binaries aren’t present in any stable Android 12L builds for the Pixel 6 Pro, but they are present in the Android 13 beta builds.
The Android Platform Manifest, which Google’s repo tool uses to find the various repositories in AOSP when checking out a specific branch, added external/exfatprogs to the default manifest in the AOSP master branch last year. This means that anyone checking out the AOSP master branch during their build process will have included the necessary helper binaries to pass vold’s file system check for exFAT. The default manifest in the android-12.1.0_r8 branch, however, does not pull external/exfatprogs, so those builds will lack the helper binaries. While Google has yet to push the Android 13 source code to AOSP, it’s possible that the platform manifests for the new Tiramisu branches will pull external/exfatprogs, which would explain why they’re now included in the current beta builds.
Danny Lin, the developer of ProtonAOSP, confirmed that exFAT is supported on his Pixel 6. ProtonAOSP is based on AOSP Android 12L and includes the aforementioned helper binaries, showing that Android 13 is not actually needed for exFAT to be supported on the Pixel 6 series. Furthermore, the helper binaries themselves aren’t actually necessary, as it’s possible to patch vold to remove the check and still be able to mount exFAT volumes. Custom kernel developers can take things a step further and even backport Samsung’s drivers to older versions, as demonstrated by developer Park Ju Hyung.
It won’t be long before every new Android device is capable of mounting exFAT volumes out of the box. Every Android 12 launch device will include the necessary kernel driver, but whether that device actually supports the file system depends on whether the helper binaries are included. If they don’t, then they’re very likely to gain support for it once they update to Android 13. The next step is NTFS, for which an in-kernel driver was added in Linux 5.15. We won’t see devices launching with that kernel version until later this year, though.
Thanks for reading this edition of Android Dessert Bites. You can find previous editions on the Esper blog.