Banana PI R4 - Attempts to install created image from Frank-w on EMMC

I create an image from Frank-w (BPI-Router-Images):

Settings:

imgfile=bpi-r4_emmc.img.gz

skipkerneldownload=1

kernelfile=bpi-r4_6.12.32-main.tar.gz

Next:

./buildimg.sh bpi-r4 bookworm 6.12.32

I try to transfer it to EMMC:

echo 0 > /sys/block/mmcblk0boot0/force_ro

cd /mnt/sda1

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

gunzip -c bpi-r4_bookworm_6.12.32-main.img.gz | dd bs=512 conv=notrunc,fsync of=/dev/mmcblk0

dd if=bpi-r4_emmc_fip.bin of=/dev/mmcblk0p4

mmc bootpart enable 1 1 /dev/mmcblk0

at the same time, if I create an image from bpi-r4_sdmmc.img.gz and write it to the SD card - everything works.

How to transfer the image to EMMC correctly?

Looks right so far. I’m not sure about the mmc bootpart command as i always did this from uboot. You did this after booting initrd from nand? You cannot access emmc after booting from sdcard because both share the emmc controller,but it looks like emmc itself is available. It would be interesting how far boot process goes,so please show bootlog (debug uart).

After running this build from SD card, another problem occurred. The build damaged the NAND bootloader. I understand that this is a result of using a UBI device. So until I restore the bootloader, I have no way to make changes to the EMMC sector.

Previous EMMC boot log:

NOTICE: BL2: v2.12.0(release):d50bccad1-bpi-r4-emmc

NOTICE: BL2: Built : 08:35:20, Jun 17 2025
NOTICE: WDT: Cold boot
NOTICE: WDT: disabled
NOTICE: CPU: MT7988
NOTICE: EMI: Using DDR unknown settings
NOTICE: EMI: Detected DRAM size: 4096 MB
NOTICE: EMI: complex R/W mem test passed
NOTICE: LVTS: Enable thermal HW reset
ERROR: Failed to initialize GPT partitions
ERROR: FIP boot source initialization failed with -2
PANIC at PC : 0x0000000000205da4

Have not tried ubi yet,only added the options. Also do nothing with nand (no write access). Normal bl2 should load fip from fip gpt partition. Wonder about the gpt error. Maybe you have to use the sgdisk workaround to update the backup gpt.

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

i noticed, this check of the second table was removed at some point in ATF. But not sure if Exsoiner’s version has this check or not.

Backup table is never written by image because it is at the end of disk and image build process does not know how big the later disk is. It can only write the main gpt. The sgdisk uses the main gpt and writes the backup.

Why should atf change the gpt?

I guess I should make my statement more clear:

I meant this is removed in later versions:

But anyway, it only changed, so never mind my statement :wink:

They just moved it, still checking.

Edit:

But it will only use it, if the primary gpt is invalid.

I understand that there is no access from Linux, but there is access from the bl2 bootloader, or am I wrong?

This is what corrupts the NAND memory when executed:

[ 8.603751] mtdblock: MTD device ‘bl2’ is NAND, please consider using UBI block devices instead.
[ 8.604058] mtdblock: MTD device ‘ubi’ is NAND, please consider using UBI block devices instead.
[ 0.879017] spi-nand spi0.0: Winbond SPI NAND was found.
[ 0.884336] spi-nand spi0.0: 128 MiB, block size: 128 KiB, page size: 2048, OOB size: 64
[ 0.892643] 2 fixed-partitions partitions found on MTD device spi0.0
[ 0.899015] OF: Bad cell count for /soc/spi@11007000/spi_nand@0/partitions
[ 0.905889] OF: Bad cell count for /soc/spi@11007000/spi_nand@0/partitions
[ 0.913023] Creating 2 MTD partitions on “spi0.0”:
[ 0.917813] 0x000000000000-0x000000200000 : “bl2”
[ 0.924553] 0x000000200000-0x000008000000 : “ubi”
[ 1.013483] ubi0: attaching mtd1
[ 1.847318] ubi0: scanning is finished
[ 1.916460] ubi0: attached mtd1 (name “ubi”, size 126 MiB)

Log is from linux,so it creates the ubifs and this breaks my current spi format.

Perhaps it would be better to remove the ubi.mtd= from the kernel command line and use the userspace tool `ubiattach’ to attach the ubi-device, only when needed.

But perhapse attaching ubi is still safe, but the corruption is started when the ubifs is mounted on a ubi-volume on the ubi-device…

1 Like

This is clear. I did not build the kernel, I used the ready one from your BPI-Router-Linux repository. In this case, the question is, how to disable the use of UBI? Rebuild the kernel myself by disabling the options related to UBI?

If i would find time i would change nand to ubi too like openwrt does. Was not aware that linux recreates ubi and so breaks nand.

Basicly ubi only starts after bl2,so fip gets overridden as it should be inside ubi. So you have to flash bl2 with ubi support and (somehow) get fip into the ubifs.

Need to look how this can be done and then change my image creation code.

Disabling ubi in kernel can be done by either disabling ubi options or changing devicetree dropping the ubi partition.

ubiformat -y /dev/mtd0
ubiattach -p /dev/mtd0
ubimkvol /dev/ubi0 -n 0 -N fip  -s 1MiB   -t static
ubiupdatevol /dev/ubi0_0 fip.bin

In a nutshell.

But check the devicenumbers for correctness :wink:

Creating an ubifs, for U-Boot loading kernel files , is a bit harder… I’ll post a new post for an example usage I’ve been working on.

1 Like

You mean inside uboot? Maybe creating from linux (sdcard) and only loading in uboot is easier.

Would be great if you post such thread. Also looked for a way to load fit and initrd from spi nand/nor. Ubi would be a generic way without fixed offsets.

Thats what I mean, and that is why I needed to have R3 (and probably R4) writing to nand from linux fixed. See:

Thanks to everyone for the answers. Thinking about boot recovery options, I settled on booting from an NVME drive + bootloader in NAND memory. Everything worked out, it works fine. I decided not to use the option of assembling a kernel without UBI support. There are many dependencies that will most likely affect performance. Instead, I created a UBI disk where I distributed FIP BPI-R4.

Here’s what happened:

[ 0.885080] spi-nand spi0.0: 128 MiB, block size: 128 KiB, page size: 2048, OOB size: 64
[ 0.893948] 2 fixed-partitions partitions found on MTD device spi0.0
[ 0.900322] OF: Bad cell count for /soc/spi@11007000/spi_nand@0/partitions
[ 0.907200] OF: Bad cell count for /soc/spi@11007000/spi_nand@0/partitions
[ 0.914314] Creating 2 MTD partitions on “spi0.0”:
[ 0.919103] 0x000000000000-0x000000200000 : “bl2”
[ 0.925829] 0x000000200000-0x000008000000 : “ubi”
[ 1.015500] ubi0: attaching mtd1
[ 1.848435] ubi0: scanning is finished
[ 1.916216] ubi0: attached mtd1 (name “ubi”, size 126 MiB)
[ 1.921705] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[ 1.928577] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[ 1.935353] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[ 1.942305] ubi0: good PEBs: 1008, bad PEBs: 0, corrupted PEBs: 0
[ 1.948389] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
[ 1.955598] ubi0: max/mean erase counter: 3/1, WL threshold: 4096, image sequence number: 1135262330
[ 1.964718] ubi0: available PEBs: 950, total reserved PEBs: 58, PEBs reserved for bad PEB handling: 20
[ 1.974020] ubi0: background thread “ubi_bgt0d” started, PID 863

Steps to create a bootloader:

  1. BL2:

usb start
mtd erase spi-nand0
fatload usb 0:1 $loadaddr bpi-r4_spim-nand_bl2.img
mtd write spi-nand0 $loadaddr 0x0 0x40375

  1. linux:

ubidetach -d 0
ubiformat /dev/mtd1
ubiattach -p /dev/mtd1
ubimkvol /dev/ubi0 -N fip -s 4MiB -t static
ubiupdatevol /dev/ubi0_0 /mnt/bpi-r4_spim-nand_fip.bin

You also need to rebuild the frank-w u-boot repository with UBI support. The output of the build should be the following files: bpi-r4_spim-nand_bl2.bin, bpi-r4_spim-nand_fip.bin

You should not erase full nand before replacing bl2 as it will kill your ubi too.

I’ve wrote steps here for linux part

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

And here for uboot (both sections are linked against each other):

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

My pipeline already creates ubi images (ubi in filename).

Good news, I’ll definitely look at the assembly details.

What are the ubootenv and ubootenv2 sections used for?

ubi list
0: fip
1: ubootenv
2: ubootenv2
3: rootfs

It is prepared for storing uboot environment (if you want to store own variables) and for redundant uboot environment. But i do not use it…used same structure like eric to keep ot compatible. Afaik openwrt does so too.

It would be a good alternative to build a version of ubi with nvme booting by default. Otherwise you’ll have to rebuild the package yourself anyway.