Hi, I believe I already did in other threads. But to make it simple:
To fix ZFS ROOTFS boot, you have to prepare initrd. Reading Canonical’s wiki, it was quite easy to do. I already posted about it.
But before you’ll do anything else - just prepare the initramfs image, and extract it. do:
cd /usr/src/initramfs_extracted
mkdir dev; cd dev
mknod -m 622 console c 5 1
mknod -m 622 tty0 c 4 0
Depending on your base OS (in my case, Ubuntu 24.04.1), copy bellow files from x86_64 system over to your extracted initramfs dir, using same paths:
/etc/init.d/zfs-import
/etc/init.d/zfs-load-key
/etc/init.d/zfs-mount
/etc/init.d/zfs-share
/etc/init.d/zfs-zed
Only then run cpio to create new initramfs.file
Then, you need to rebuild the kernel with ZFS (CONFIG_ZFS=y), and tell the kernel where to look for your initramfs image:
CONFIG_INITRAMFS_SOURCE="../initramfs.cpio"
(modify the path to suit your location)
Resulting uImage will be around 49MB.
If you’ll try to boot it now, nothing will happen - it will simply boot, the boot itself will be longer by ~15s.
But then you can create your zpools. Generic Ubuntu Howto could be used on how to prepare rpool zpool (we won’t need bpool since the host boots off of EMMC’s first partition to retain compatibility).
Prepare your rootfs ZFS (chroot, debootstrap…be my guest - just note: you do not need bootfs). Once done, boot your system by calling bellow in uBoot terminal:
setenv partition 0:1
setenv bootenv uEnv.txt
run loadbootenv
setenv bootargs board=bpi-r2 earlyprintk console=tty1 fbcon=map:0 console=ttyS0,115200 vmalloc=768M debug=7 initcall_debug=0 root=zfs="rpool/ROOT/ubuntu_h1wz1w" init_on_alloc=0
fatload mmc 0:1 ${loadaddr} ${bpi}/${board}/${service}/${kernel}; bootm
Don’t forget to change host UUID, in my case it is ‘h1wz1w’. It should boot. Now, to make sure you can boot always with ZFS, you’d need to change uEnv.txt:
#
## uEnv.txt
#
bpi=bananapi
board=bpi-r2
chip=mt7623n
service=linux
#
kernel=uImage-5.15.173-bpi-r2-main
#
kaddr=0x84000000
rdaddr=0x86000000
#
initsata=pci enum;scsi scan
console=earlyprintk console=tty1 fbcon=map:0 console=ttyS0,115200
bootopts=vmalloc=768M debug=7 initcall_debug=0 ipv6.disable=1 video=HDMI-A-1:1280x1024D fsck.mode=force fsck.repair=yes init_on_alloc=0
abootargs=setenv bootargs board=${board} console=${console} root=ZFS=rpool/ROOT/ubuntu_h1wz1w service=${service} ${bootopts}
ahello=echo Banana Pi ${board} chip: $chip Service: $service
aboot=if fatload $device $partition $rdaddr ${bpi}/berryboot.img; then bootm $kaddr $rdaddr ; else bootm $kaddr; fi
aload_kernel=fatload $device $partition $kaddr ${bpi}/${board}/${service}/${kernel}
uenvcmd=run ahello abootargs aload_kernel aboot
## END
Oh, and I did it all natively on the box itself. While I can cross-compile the kernel and it boots the same as the one I built on the machine, everything else is easier on the board, rather than on the PC. Initramfs for x86_64 wouldn’t work on your arm.
Should you want more nuanced boot menu, you can also use this uEnv-r2.txt, put it to uBoot source directory, and rebuild:
Just don’t forget to update it with the details of your zpool UUIDs before rebuilding. Also, I do use longer filenames for uImage kernel files.
New uBoot can be flashed by:
dd if=./u-boot.bin of=/dev/mmcblk1 bs=1k seek=320
from uBoot source dir.
For those who would like to try, I do have patch for uBoot to enable ZFS bootfs zpool as well. But I haven’t tried it myself, although I verified that uBoot can read binary files and execute them from ZFS dataset, so it should work. But I’d like to keep EMMC as a blank copy of my live system, and should disaster happen, I will boot to EMMC only, in order to fix ZFS issues, should something like that ever happen.