Boot Debian from NVMe

Good morning

Received a NVME SSD this morning to test with my new R4 board…

Haven’t found any useful information (at least for me ;o) how to proceed to get Debian directly from NVMe.

Boot from SD and flash “u-boot-r4_2025.04-bpi-arm64-spi-nand.bin” over to NAND?

You cannot boot directly from nvme,you have to boot from mmc or spi first.

My uboot binaries have nvme support and then you can try to do manually booting linux kernel and rootfs from nvme before setting it as default.

i boot from emmc first (because i can change uboot environment there easier) and then from nvme

frank@bpi-r3-nvme:~$ mount | grep -v '/sys\|tmpfs'
/dev/nvme0n1p2 on / type ext4 (rw,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
/dev/nvme0n1p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
/dev/mapper/vg--nvme-data on /mnt/data type ext4 (rw,relatime)
/dev/mapper/vg--nvme-var on /var type ext4 (rw,relatime)
/dev/mmcblk0p5 on /mnt/emmc1 type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
frank@bpi-r3-nvme:~$ cat /mnt/emmc1/uEnv.txt 
bootnvme=run usenvme; if test "$device" = "nvme"; then run loadenv; printenv; run newboot;fi
bootmenu_3=4. Boot kernel from NVME.=run bootnvme
bootmenu_default=3
frank@bpi-r3-nvme:~$ cat /boot/uEnv.txt 
root=/dev/nvme0n1p2 rootwait
fit=6.12.x-main.itb

so emmc-env is modified by the emmc uEnv.txt pointing to nvme and then the uEnv.txt from nvme is read to set kernel and root partition

You can use my archlinux tool to get u-boot on nand and have a linux-based rescue initrd.

Once installed, you can boot from and and use debootstrap to install debian on nvme. But you would still need a kernel.

Also it is possible ti use my tool

bpir-build

and choose to install Ubuntu. It installs ubuntu and a few of my tools + linux-kernel, maintained through archlinux packages though. It may not be what you want, but this is possible.

These options are quite new, so expect to run into bugs.

Good morning (o;

Got finally some time now to play around with NVMe after a hard working week doing BGP4 test setups (o;

Used the SD image to go into uboot and modified the env settings there with:

nvme_boot=0:5 nvme_root=/dev/nvme0n1p6

As I wrote the same image to the NVMe via dd. Interestingly it still loaded the /boot partition from SD but the rootfs from NVMe:

root@bpi-r4:~# lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
mtdblock0    31:0    0     2M  1 disk 
mtdblock1    31:1    0   126M  0 disk 
mmcblk0     179:0    0  14.8G  0 disk 
├─mmcblk0p1 179:1    0     4M  0 part 
├─mmcblk0p2 179:2    0   512K  0 part 
├─mmcblk0p3 179:3    0     2M  0 part 
├─mmcblk0p4 179:4    0     2M  0 part 
├─mmcblk0p5 179:5    0   100M  0 part /boot
└─mmcblk0p6 179:6    0  14.7G  0 part 
nvme0n1     259:0    0 238.5G  0 disk 
├─nvme0n1p1 259:1    0     4M  0 part 
├─nvme0n1p2 259:2    0   512K  0 part 
├─nvme0n1p3 259:3    0     2M  0 part 
├─nvme0n1p4 259:4    0     2M  0 part 
├─nvme0n1p5 259:5    0   100M  0 part 
└─nvme0n1p6 259:6    0 238.4G  0 part /

I thought it would take all from NVMe so I could flash the MMC with whatever uboot image it is required…

Mounted filesystems are in /etc/fstab,check with mount command before that you change the right file (possibly booting with nvme rootfs and then it is mounting the mmc one rw).

Dd is not needed…just copy from mmc to nvme is enough and then update fstab on nvme.

Very confusing to me all this (o;

Browsing through all your dozens of uboot images at github… Which file is actually needed for flashing over to mtdblock0?

dd if=u-boot-r4_2025.04-bpi-arm64-spi-nand.bin of=/dev/mtdblock0 ?

I have no nand-image yet because i have not found a way to create a ubi(fs) in an image and to create a flashable image in correct size.

Currently some steps need to be done in uboot and others in linux

https://wiki.fw-web.de/doku.php?id=en:bpi-r4:uboot#ubi

bl2 must be readonly in linux,but creating ubifs is easier in linux.

Followed your guide to flash:

bpi-r4_spim-nand_bl2.img
bpi-r4_spim-nand_fip.bin
BPI-R4> mtd erase spi-nand0
Erasing 0x00000000 ... 0x07ffffff (1024 eraseblock(s))
BPI-R4> load usb 0:1 $loadaddr bpi-r4_spim-nand_bl2.img
254821 bytes read in 12 ms (20.3 MiB/s)
BPI-R4> mtd write spi-nand0 $loadaddr 0x0 0x100000
Writing 1048576 byte(s) (512 page(s)) at offset 0x00000000
BPI-R4> load usb 0:1 $loadaddr bpi-r4_spim-nand_fip.bin
370673 bytes read in 19 ms (18.6 MiB/s)
BPI-R4> mtd write spi-nand0 $loadaddr 0x580000 0x200000
Writing 2097152 byte(s) (1024 page(s)) at offset 0x00580000

Now NVMe isn’t recognized anymore…

What is the output of

run usenvme

In uboot console after booting from nand?

Nand is the most complex setup…why not using mmc as boot device? There you can use uenv.txt to configure uboot (i try to do the same in ubifs,but setup is more difficult than only flashing an image).

The default bootmenu entry is always mmc and needs to be changed (via mmc uenv.txt) to use nvme bootentry.

The output is:

BPI-R4> run usenvme
** Bad device specification nvme 0 **
Couldn't find partition nvme 0:1
nvme partition not found

Ao far I haven’t found any description how to get u-boot onto eMMC.

Thats really strange…have not changed anything for nvme except adding the menuentry by default

For emmc it is basicly same as r3

https://wiki.fw-web.de/doku.php?id=en:bpi-r3:uboot#writing_emmc

Easiest way is to start from nand (after flashed from sdcard like you did) and booting a kernel+initrd from usb. Then flash emmc bl2 to boot0 and sdmmc image to userpart.

Good morning (o;

Where do I find this rootfs.cpio.zst? The google drive link there isn’t valid anymore.

Or can I just use the initrd.gz image from official Debian?

Debians initrd is the installer.

I hope this link works

https://drive.google.com/drive/mobile/folders/1WLWAR1FC-rF4n2SgFecBlU1ym_XKqAR_/15Y5Y3NAOwg_IMmN3k6hdb7pAQj9oTVTl/1_UtkNl0S44_Xy46NAEn1KoFDSOkQwAsb

Okay…booting up went fine (o;

Do I have to do the sgdisk stuff as mentioned on your page? And if…what is ${LDEV}?

I see following partitions on mmcblk0:

brw-rw----    1 root     disk      179,   0 Jul 12 06:46 /dev/mmcblk0
brw-rw----    1 root     disk      179,   8 Jul 12 06:46 /dev/mmcblk0boot0
brw-rw----    1 root     disk      179,  16 Jul 12 06:46 /dev/mmcblk0boot1
crw-------    1 root     root      244,   0 Jul 12 06:46 /dev/mmcblk0rpmb

So just do a:

dd if=bpi-r4_emmc_bl2.img of=/dev/mmcblk0boot0
dd if=bpi-r4_sdmmc.img of=/dev/mmcblk0rpmb

the sgdisk fix is because image can only contain main GPT at beginning the disk but not the backup GPT at the end of disk (because image creation process cannot know target disk size and 16GB+ image is not a good idea).

the uboot sdmmc.img has no kernel and rootfs, here you have to use the full image ceated by my bpi-router-images repo (these images have kernelversion and userspace name like bookworm in filename). the uboot-file is only a base image with the bootchain which is taken by images repo to add kernel and userspace.

second the image has to be flashed to /dev/mmcblk0 which is the emmc user-part (not sure what the rpmb partition is - not used till now).

Hmm…but actually I want to load kernel and rootfs from NVMe via MMC…from NAND SPI it didn’t work and always took /boot from SD…

The 8GB MMC is just way too small and slow for my needs.

you can define a uEnv.txt on the emmc BPI-Boot partition to point to nvme (see above):

first 2 lines should not be needed only setting the bootmenu default or maybe setting the nvme-vars

Hmm…somehow the

gunzip -c bpi-r4_bookworm_6.12.23-main.img.gz | dd of=/dev/mmcblk0

didn’t work…can’t boot from MMC…just gives me a system halt… I can boot though via NAND SPI and then choose MMC which in turn loads the rootfs from NVMe and /boot from MMC:

root@bpi-r4:~# lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
mtdblock0     31:0    0     2M  1 disk 
mtdblock1     31:1    0   126M  0 disk 
mmcblk0      179:0    0   7.3G  0 disk 
├─mmcblk0p1  179:1    0     4M  0 part 
├─mmcblk0p2  179:2    0   512K  0 part 
├─mmcblk0p3  179:3    0     2M  0 part 
├─mmcblk0p4  179:4    0     2M  0 part 
├─mmcblk0p5  179:5    0   100M  0 part /boot
└─mmcblk0p6  179:6    0   6.4G  0 part 
mmcblk0boot0 179:8    0     4M  1 disk 
mmcblk0boot1 179:16   0     4M  1 disk 
nvme0n1      259:0    0 238.5G  0 disk 
├─nvme0n1p1  259:1    0     4M  0 part 
├─nvme0n1p2  259:2    0   512K  0 part 
├─nvme0n1p3  259:3    0     2M  0 part 
├─nvme0n1p4  259:4    0     2M  0 part 
├─nvme0n1p5  259:5    0   100M  0 part 
└─nvme0n1p6  259:6    0 238.4G  0 part /

drives me nuts though I could live with that setup if I remember all steps I’ve done (o;

Anyway…gotta prepare the pizza dough now :wink:

Where do you get this? Do you see uboot?

If not i guess partconf is not set right,so boot nand till uboot and do this in uboot console:

mmc partconf 0 1 1 0

As i said,if /boot is from mmc you have to adjust /etc/fstab on nvme if you sure rootfs is loaded from nvme (look in bootlog for bootargs and then mount command).

There are of course many ways to achieve booting Debian from NVME.

It’s really what you’d prefer, Frank’s method also has advantages compared to the below.

Personally I would like to use extlinux.conf booting up linux from NAND. I’ve described a different bootchain here that does that:

https://forum.banana-pi.org/t/bpi-r3-bpi-r3-mini-bpi-r4-nand-distro-boot-linux-recovery/23758?u=ericwoud

After booting up from nand there are several ways to install Debian, but also, the tool bpir-build has an Ubuntu option to get Ubuntu on NVME.

The advantage here is that there is no need to work with U-Boot commands, there is always a linux (initrd) available. From there it is quite easy to install any distro.

I’ve tested this on R3, in my R4 I do not have an nvme installed yet. U-Boot should be able to use it on R4 also.

Edit:

Confirmed, boots on R4 also.