Thanks for the replies.
I understand that native UFS boot support is still very new, and that ext4 is currently the safest and expected path.
After some more testing, I managed to get a separate ext4 /boot + btrfs / layout working on my NanoPi M5 with the onboard 64GB UFS.
This is not a request for official support, and I do not want to imply that this is a recommended or fully tested solution. I am only sharing it as an experimental helper script for users who may want to test a similar layout.
============================================================
WORKING LAYOUT
==============
The layout I tested successfully is:
* /dev/sda1: ext4, mounted as /boot, LABEL=BOOT
* /dev/sda2: btrfs, mounted as /, LABEL=ROOT
* btrfs subvolume @ mounted as /
* btrfs subvolume @snapshots mounted as /.snapshots
The reason this works is that U-Boot only needs to read /boot from ext4. The Linux kernel and initramfs can then mount the root filesystem as btrfs.
============================================================
WHAT THE SCRIPT DOES
====================
The attached script does the following:
1. Checks that it is running as root.
2. Checks that the system is not currently running from UFS.
3. Checks that the expected UFS LUN devices exist.
4. Mounts an official Armbian NanoPi M5 image read-only through a loop device.
5. Creates a minimal safety backup.
6. Wipes and repartitions the UFS General LUN.
7. Creates an ext4 /boot partition starting at 32MiB.
8. Creates a btrfs root partition after /boot.
9. Creates btrfs subvolumes @ and @snapshots.
10. Sets @ as the default btrfs subvolume.
11. Copies the root filesystem from the Armbian image to the btrfs root.
12. Copies /boot from the Armbian image to the ext4 /boot partition.
13. Writes /etc/fstab.
14. Updates /boot/armbianEnv.txt with:
rootdev=LABEL=ROOT
rootfstype=btrfs
15. Ensures btrfs support is included in the target initramfs.
16. Regenerates /boot/boot.scr.
17. Uses the official write_uboot_platform_ufs() function from the image to write the UFS bootloader.
18. Performs some basic validation before finishing.
The script does not patch boot.cmd. Instead, it relies on:
* rootdev=LABEL=ROOT
* rootfstype=btrfs
* btrfs default subvolume set to @
This keeps the boot script closer to the official Armbian files.
============================================================
IMPORTANT NOTES
===============
This script is destructive.
It wipes the UFS General LUN.
It assumes the usual NanoPi M5 UFS mapping:
* /dev/sda = UFS General LUN
* /dev/sdb = UFS Boot LUN A
* /dev/sdc = UFS Boot LUN B
* /dev/sdd = vendor/config LUN
It was only tested on my NanoPi M5 with onboard 64GB UFS.
Please review the script carefully before running it.
I am attaching it only as an experimental helper for testing, not as an official solution.
============================================================
BASIC USAGE
===========
Boot from an SD card maintenance system first.
Make sure the Armbian image is already decompressed to .img.
Example:
sudo ./flash-nanopi-m5-ufs-btrfs.sh
--image /path/to/Armbian_26.5.1_Nanopi-m5_trixie_vendor_6.1.115_minimal.img
For a dry run:
sudo ./flash-nanopi-m5-ufs-btrfs.sh
--image /path/to/Armbian_26.5.1_Nanopi-m5_trixie_vendor_6.1.115_minimal.img
--dry-run
--yes-i-understand
The script requires typing:
YES_FLASH_UFS
before it performs the destructive flashing operation, unless --yes-i-understand is used.
============================================================
RESULT
======
With this layout, the system boots successfully from UFS on my NanoPi M5 with the BOOT switch set to UFS/SD.
After booting, I verified that:
* / is btrfs from LABEL=ROOT
* /boot is ext4 from LABEL=BOOT
* /.snapshots is a btrfs subvolume
* the system boots without requiring U-Boot to read btrfs directly
I hope this may help other users who want a btrfs root filesystem on UFS while keeping /boot on ext4.
flash-nanopi-m5-ufs-btrfs.sh