[BPI-R4] frank-w BPI-R4 u-boot Build & Flash (NAND)

This post is a supplement to [BPI-R4] How to use frank-w u-boot to boot from Nvme on BPI-R4.
Because NAND u-boot does not support uEnv.txt.
If we want to modify u-boot menu, we need to recompile u-boot and flash it to NAND Flash.

Environmental Information:
Hardware: BananaPi R4 8GB RAM
eMMC: OpenWRT u-boot & OpenWRT
SD: frank-w u-boot & frank-w Debian
NAND(Target): frank-w u-boot
Nvme: Nvme SSD 128GB on M.2 KeyM slot
Compile Host: x86 Debian 12

Partition:
SD Partition:
/dev/sda5 vfat BPI-BOOT
/dev/sda6 ext4 BPI-ROOT

Nvme Partition:
/dev/nvmen1p0 vfat
/dev/nvmen1p1 ext4

After the u-boot is compiled, it will generate u-boot.bin.
But BPI-R4 requires two files, bl2.img and fip.bin, so we need to convert u-boot.bin into bl2.img and fip.bin.

We need to download 2 packages of code to compile frank-w u-boot.
First, download 2025-01-bpi Release u-boot Source Code.
Second, git u-boot branch mtk-atf-2025.

u-boot Source Code:
u-boot-CI-BUILD-2025-01-bpi-2025.01-2025-04-26_0808

mtk-atf-2025:
u-boot

We divide the process into 2 stages, the first stage is to Compile u-boot, and the second stage is to Flash NAND Flash.

There are two goals for compiling u-boot.
The first goal is to set up compilation for BPI-R4, NAND and 8Gb RAM.
The second goal is to adjust the boot menu, specify the default boot number as Nvme and specify the Kernel Name.

Compile u-boot:

  1. Modify build.conf for BPI-R4, NAND and 8Gb RAM
board=bpi-r4
device=spi-nand
extraflags=DDR4_4BG_MODE=1

  1. Modify uEnv_r4.txt for Nvme boot
    bootmenu_default=3 => Base 0, option 4 set number to 3
    askbootnvme=run usenvme; if test “$device” = “nvme”; then setenv fit ${fit};run newboot;fi

  1. Build u-boot
bash ./build.sh importconfig
bash ./build.sh build
bash ./build.sh rename

  1. Copy u-boot image to mtk-atf-2025
    cp u-boot-r4_2025.01–arm64-spi-nand.bin …/u-boot/u-boot.bin.xz => Here is .bin.xz

  2. Modify build.conf in mtk-atf-2025

board=bpi-r4
device=spi-nand
extraflags=DDR4_4BG_MODE=1

image

  1. Convert u-boot.bin to bl2.img and fip.bin
    bash ./build.sh build

  2. Copy bl2.img and fip.bin to SD
    The two files bl2.img and fip.bin will be generated in build/mt7988/release/.
    We put bl2.img and fip.bin to SD vfat Partition, /dev/sda5/.

Flash NAND Flash:
We plug a USB SD card reader into the BPI-R4 USB and use the USB SD card reader as the file source.

  1. Switch to eMMC Boot and boot into u-boot menu

  1. Enable USB
    usb start

  1. Flash u-boot from USB Partition 5
mtd erase spi-nand0
load usb 0:5 $loadaddr bl2.img
mtd write spi-nand0 $loadaddr 0x0 0x100000
load usb 0:5 $loadaddr fip.bin
mtd write spi-nand0 $loadaddr 0x580000 0x200000

image

  1. Switch boot from NAND
    Check RAM Size

EMI: DDR4 4BG mode
EMI: Detected DRAM size: 8192 MB

Check bootmenu

  1. Reset and use NAND to boot into Nvme

2 Likes

Thank you very much for help in testing and writing tutorals.

Small additions: You do not have to copy u-boot bin. Just switch branch. Build.sh does all,see .github/workflows/build.yml

you can use “./build.sh rename” to get the right binaries in source root dir with better name. This is how ci pipeline gets the names and can generate multiple binaries without overwriting.

Thank you for your reply.:smile:
I refer to your version and your contribution.
These modifications give BPI-R4 a lot of flexibility and make it more stable.

Btw i have some helper scripts in builtin env for flashing nand and emmc which are not really documented.

For emmc it is documented for r3 which is basicly same

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

They base on useusb which sets variables for further commands (also newboot for booting fit from it).

run useusb

After that you can set filenames for bl2 and fip as vars.

MT7986> setenv bl2file 2023.04/bpi-r3_emmc_bl2.img                                                                                                                                          
MT7986> setenv fipfile 2023.04/bpi-r3_emmc_fip.bin                                                                                                                                          

And then wrote them

MT7986> run wremmc

or

run wrspimnand

So users have no need to know the offsets and complete write command.