Possible to flash R3 ubuntu image into eMMC/NAND?

It may be wise to first use the prebuild bl2/U-Boot images from Frank, write them to emmc, together with rootfs and see if you can get something booting from emmc.

That is enough of a challenge to start with, when having no linux experience.

Once successful, replace the prebuild binaries with your own build binaries. But what does need to be changed?

Nand boot works so far…you have no kernel/rootfs there. That would require e.g. an ubifs which i try on r4 currently. But you get an uboot prompt where you can load kernel and initrd manual to access emmc.

Initrd

Kernel (bpi-r3.itb or extract it from tar.gz package):

Put both on usb stick,insert it and run these commands

run useusb
setenv fit bpi-r3.itb
setenv initrd rootfs_arm64.cpio.zst
run newboot

Mainly considering to build u-boot and kernel for MT7988 platform (R4 is suitable but I start with R3 first) + Realtek PHY + Realtek PCIe PHY.

Thank you. I’m confusing the board is booted from eMMC but not NAND?

BPI-R3> run useusb
USB is stopped. Please issue 'usb start' first.
starting USB...
xhci-mtk xhci@11200000: hcd: 0x0000000011200000, ippc: 0x0000000011203e00
xhci-mtk xhci@11200000: ports disabled mask: u3p-0x0, u2p-0x0
xhci-mtk xhci@11200000: u2p:2, u3p:1
Register 300010f NbrPorts 3
Starting the controller
USB XHCI 1.10
Bus xhci@11200000: 3 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
            System Volume Information/
  9518220   bpi-r3.itb
 16546559   rootfs_arm64.cpio.zst

2 file(s), 1 dir(s)

BPI-R3> setenv fit bpi-r3.itb
BPI-R3> setenv initrd rootfs_arm64.cpio.zst
BPI-R3> run newboot
initrd=rootfs_arm64.cpio.zst
16546559 bytes read in 1184 ms (13.3 MiB/s)
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x1 (boot0)
PARTITION_ACCESS: 0x0 (user)
emmc available
jedec_spi_nor spi_nor@0: unrecognized JEDEC id bytes: ff, ef, aa
Failed to initialize SPI flash at 0:0 (error -2)
NAND available
emmc nand
fit=bpi-r3.itb
9518220 bytes read in 681 ms (13.3 MiB/s)
## Loading kernel (any) from FIT Image at 46000000 ...
   Using 'conf-emmc' configuration
   Trying 'kernel-1' kernel subimage
     Description:  Linux Kernel 6.12.47-main
     Type:         Kernel Image
     Compression:  gzip compressed
     Data Start:   0x460000e8
     Data Size:    9464879 Bytes = 9 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x44000000
     Entry Point:  0x44000000
     Hash algo:    sha1
     Hash value:   54dc13ba29c71d3ff2cd0b8b9a2c7e8ec39fa0ad
   Verifying Hash Integrity ... sha1+ OK
## Loading fdt (any) from FIT Image at 46000000 ...
   Using 'conf-emmc' configuration
   Trying 'fdt-base' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x46906e14
     Data Size:    22925 Bytes = 22.4 KiB
     Architecture: AArch64
     Load Address: 0x47000000
     Hash algo:    sha1
     Hash value:   31d0436ec59f28999bb323729109fcc93f829906
   Verifying Hash Integrity ... sha1+ OK
   Loading fdt from 0x46906e14 to 0x47000000
   Loading Device Tree to 00000000be7f3000, end 00000000be7fbfff ... OK
Working FDT set to be7f3000
## Loading fdt (any) from FIT Image at 46000000 ...
   Trying 'fdt-ov-emmc' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x469124a4
     Data Size:    477 Bytes = 477 Bytes
     Architecture: Unknown Architecture
   Verifying Hash Integrity ... OK
## Loading fdt (any) from FIT Image at 46000000 ...
   Using 'nand' configuration
   Trying 'fdt-ov-nand' fdt subimage
     Description:  unavailable
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x469126b8
     Data Size:    909 Bytes = 909 Bytes
     Architecture: AArch64
   Verifying Hash Integrity ... OK
## Loading fdt (any) from FIT Image at 46000000 ...
   Using 'sata' configuration
   Trying 'fdt-ov-sata' fdt subimage
     Description:  unavailable
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x46912e50
     Data Size:    1000 Bytes = 1000 Bytes
     Architecture: AArch64
   Verifying Hash Integrity ... OK
   Booting using the fdt blob at 0xbe7f3000
Working FDT set to be7f3000
   Uncompressing Kernel Image to 44000000
   Loading Device Tree to 00000000be7ea000, end 00000000be7f2e77 ... OK
Working FDT set to be7ea000

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 6.12.47-bpi-r3-main (runner@runnervmf4ws1) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #8 SMP Sun Sep 14 17:02:40 UTC 2025
[    0.000000] Machine model: Bananapi BPI-R3
...
...
...
[   16.371762] mt7530-mdio mdio-bus:1f lan2: entered allmulticast mode
[   16.379486] mt7530-mdio mdio-bus:1f lan2: entered promiscuous mode
[   16.389533] mt7530-mdio mdio-bus:1f lan2: configuring for phy/gmii link mode

Waiting for br0 to get ready (MAXWAIT is 12 seconds).
OK
Starting crond: OK
ssh-keygen: generating new host keys: RSA ECDSA ED25519
Starting sshd: OK

Welcome to Buildroot
buildroot login: root
#
#
# pwd
/root
# ll
-sh: ll: not found
# ls -al
total 0
drwx------    2 root     root             0 Aug 29  2025 .
drwxr-xr-x   17 root     root             0 Jan  1 00:00 ..
#

Is the rootfs_arm64.cpio.zst considered as an initrd for constructing an empty rootfs?

And the bpi-r3.itb is Linux kernel including devicetree, firmware and images. Is my understanding correct?

You booted from nand as your bl2 info tells you

Initrd is a temporary rootfs (here buildroot/busybox based) to do something without a rootfs on the device itself.

The steps here are now:

  • Flash sdcard image to emmc userpartition (mmcblk0). You should see boot0 block too
  • You can also flash bl2 here to boot0,but this is better to be flashed via uboot as the partconfig maybe needs to set too…this imho can only be done from uboot or with mmcutils.
  • Replace fip with the emmc variant. Maybe sdmmc fip works too as main difference is the bl2.

My NAND rootfs is now empty, thus I can’t access any files/devices e.g. mmcblk0, mmcblk0boot0. What is purpose for booting NAND initrd like this?

Previously, I booted with NAND (Openwrt single image installed) and flashed bl2_emmc.img + mtk-bpi-r3-EMMC-WAN1-RJ45-20220720-single-image.img to the eMMC devices in rootfs. Then the eMMC works with Openwrt firmware.

The rootfs in initrd is independ of what you have on storage, so when you have system booting to uboot console you can start a mini linux system to do recovery or installing steps easier than through uboot. E.g. uncompressing files,editing text files,…

I finally recognize the initrd filesystem. Now I can access to eMMC device which has already been installed Openwrt firmware.

# ls -al /dev/mmc*
brw-rw----    1 root     disk      179,   0 Jan  1 00:00 /dev/mmcblk0
brw-rw----    1 root     disk      179,   8 Jan  1 00:00 /dev/mmcblk0boot0
brw-rw----    1 root     disk      179,  16 Jan  1 00:00 /dev/mmcblk0boot1
brw-rw----    1 root     disk      179,   1 Jan  1 00:00 /dev/mmcblk0p1
brw-rw----    1 root     disk      179,   2 Jan  1 00:00 /dev/mmcblk0p2
brw-rw----    1 root     disk      179,   3 Jan  1 00:00 /dev/mmcblk0p3
brw-rw----    1 root     disk      179,   4 Jan  1 00:00 /dev/mmcblk0p4
brw-rw----    1 root     disk      179,   5 Jan  1 00:00 /dev/mmcblk0p5
brw-rw----    1 root     disk      179,   6 Jan  1 00:00 /dev/mmcblk0p6
crw-------    1 root     root      244,   0 Jan  1 00:00 /dev/mmcblk0rpmb
#

May I have your commands to flash the pre-built (sdcard?) ubuntu image into eMMC?

Without sudo because in initrd you are already root. An of course mounting your stick with the image file before and right paths

And then replace fip (needed because you need the right dts in uboot for emmc).did not thought about that before,sorry.but make sure partitiontable is read before writing. Not sure if partprobe is available in my initrd.

dd if=bpi-r3_emmc_fip.bin of=/dev/mmcblk0p4 conv=notrunc,fsync

You can also write fip from uboot if there is no way to reload partitions…

Do not forget to flash bl2 to boot0 and set partconf in uboot.

For bl2+fip i have a macro in my uboot.qhich does all necessary steps.

MT7986> run useusb #to set device to usb and partition to 0:1 if you want to load uboot-files from there
MT7986> setenv bl2file 2023.04/bpi-r3_emmc_bl2.img                                                                                                                                          
MT7986> setenv fipfile 2023.04/bpi-r3_emmc_fip.bin                                                                                                                                          
MT7986> run wremmc

Thank you. It is used to flash bl2 and fip in u-boot:

BPI-R3> run useusb
USB is stopped. Please issue 'usb start' first.
starting USB...
xhci-mtk xhci@11200000: hcd: 0x0000000011200000, ippc: 0x0000000011203e00
xhci-mtk xhci@11200000: ports disabled mask: u3p-0x0, u2p-0x0
xhci-mtk xhci@11200000: u2p:2, u3p:1
Register 300010f NbrPorts 3
Starting the controller
USB XHCI 1.10
Bus xhci@11200000: 3 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
            System Volume Information/
  9518220   bpi-r3.itb
 16546559   rootfs_arm64.cpio.zst
   209616   bpi-r3_spim-nand_bl2.img
   279581   bpi-r3_spim-nand_fip.bin
   200793   bpi-r3_emmc_bl2.img
   280749   bpi-r3_emmc_fip.bin

6 file(s), 1 dir(s)

BPI-R3> setenv bl2file bpi-r3_emmc_bl2.img
BPI-R3> setenv fipfile bpi-r3_emmc_fip.bin
BPI-R3> run wremmc
bl2file=bpi-r3_emmc_bl2.img
200793 bytes read in 16 ms (12 MiB/s)
MMC erase: dev # 0, block # 0, count 1024 ... 1024 blocks erased: OK
MMC write: dev # 0, block # 0, count 1024 ... 1024 blocks written: OK
fipfile=bpi-r3_emmc_fip.bin
280749 bytes read in 20 ms (13.4 MiB/s)
MMC erase: dev # 0, block # 13312, count 4096 ... 4096 blocks erased: OK
MMC write: dev # 0, block # 13312, count 4096 ... 4096 blocks written: OK
BPI-R3>

It is switched to eMMC boot but got stuck before kernel:

F0: 102B 0000
FA: 1040 0000
FA: 1040 0000 [0200]
F9: 103F 0000
F3: 1006 0033 [0200]
F3: 4001 00E0 [0200]
F3: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 2400 0041 [0000]
G0: 1190 0000
EC: 0000 0000 [2000]
T0: 0000 021A [010F]
Jump to BL

NOTICE:  BL2: v2.12.0(release):a385740df-bpi-r3-emmc
NOTICE:  BL2: Built : 10:50:35, Aug 20 2025
NOTICE:  WDT: Cold boot
NOTICE:  WDT: disabled
NOTICE:  CPU: MT7986 (2000MHz)
NOTICE:  EMI: Using DDR4 settings
NOTICE:  EMI: Detected DRAM size: 2048MB
NOTICE:  EMI: complex R/W mem test passed
NOTICE:  BL2: Booting BL31
NOTICE:  BL31: v2.12.0(release):a385740df-bpi-r3-emmc
NOTICE:  BL31: Built : 10:50:38, Aug 20 2025


U-Boot 2025.07-bpi-geacd36c56c9c-dirty (Aug 20 2025 - 10:50:10 +0000)

CPU:   MediaTek MT7986
Model: BananaPi BPi-R3
DRAM:  2 GiB
Core:  48 devices, 22 uclasses, devicetree: separate
MMC:   mmc@11230000: 0
Loading Environment from MMC... Reading from MMC(0)... *** Warning - bad CRC, using default environment

In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
=> board_late_init...
Net:   MediaTek MT7531

Warning: ethernet@15100000 (eth0) using random MAC address - 2a:ec:14:33:d0:03
eth0: ethernet@15100000
Hit any key to stop autoboot:  0


  *** U-Boot Boot Menu ***

      1. Enter kernel-name to boot from SD/EMMC.
      2. Boot kernel from TFTP.
      3. Boot from SD/EMMC.
      4. Boot kernel from NVME.
      Exit


  Press UP/DOWN to move, ENTER to select, ESC to quit


## Error: "initrd" not defined
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x1 (boot0)
PARTITION_ACCESS: 0x0 (user)
emmc available
jedec_spi_nor spi_nor@0: unrecognized JEDEC id bytes: ff, ef, aa
Failed to initialize SPI flash at 0:0 (error -2)
NAND available
emmc nand
fit=bpi-r3.itb
Can't set block device
BPI-R3>

How to make eMMC/NAND always be booted kernel successfully?

Have you flashed the sdcard image before to emmc from initrd? It does look like partitions are not there…

At least bl2 and fip install was successful…but if you flash image to userpart you have to do the fip part again (or both with my macro).

I have yet flashed the sdcard image to mmcblk0.

Could you provide the image along with commands? So I can follow in progress.

Thats strange that this Error comes up

Can't set block device

Can you bootup kernel + initrd from usb again (you can do from emmc too) and show your partitions recognized by linux?

What is the command to print out partitions you would like to see?

cat /proc/partitions or ls -l /dev/mmcblk0*

Boot from initrd:

# ls -al /dev/mmc*
brw-rw----    1 root     disk      179,   0 Jan  1 00:00 /dev/mmcblk0
brw-rw----    1 root     disk      179,   8 Jan  1 00:00 /dev/mmcblk0boot0
brw-rw----    1 root     disk      179,  16 Jan  1 00:00 /dev/mmcblk0boot1
brw-rw----    1 root     disk      179,   1 Jan  1 00:00 /dev/mmcblk0p1
brw-rw----    1 root     disk      179,   2 Jan  1 00:00 /dev/mmcblk0p2
brw-rw----    1 root     disk      179,   3 Jan  1 00:00 /dev/mmcblk0p3
brw-rw----    1 root     disk      179,   4 Jan  1 00:00 /dev/mmcblk0p4
brw-rw----    1 root     disk      179,   5 Jan  1 00:00 /dev/mmcblk0p5
brw-rw----    1 root     disk      179,   6 Jan  1 00:00 /dev/mmcblk0p6
crw-------    1 root     root      244,   0 Jan  1 00:00 /dev/mmcblk0rpmb
#

I have flashed bl2 and fip with your pre-built emmc images.

One more output:

# cat /proc/partitions
major minor  #blocks  name

  31        0     125440 mtdblock0
  31        1       2048 mtdblock1
  31        2       2560 mtdblock2
  31        3       1024 mtdblock3
 179        0    7634944 mmcblk0
 179        1         17 mmcblk0p1
 179        2        512 mmcblk0p2
 179        3       2048 mmcblk0p3
 179        4       2048 mmcblk0p4
 179        5      32768 mmcblk0p5
 179        6     262144 mmcblk0p6
 179        8       4096 mmcblk0boot0
 179       16       4096 mmcblk0boot1
   8        0  121467904 sda
   8        1  121466880 sda1
#

Looks good so far Can you mount mmcblk0p5/p6 from initrd?

5 should include the bpi-r3.itb

What is the command to do so?

The mmc kernel and rootfs are now Openwrt images which I flashed at the very beginning with single-image.

BPI-R3> mmc part

Partition Map for mmc device 0  --   Partition Type: EFI

Part    Start LBA       End LBA         Name
        Attributes
        Type GUID
        Partition GUID
  1     0x00000000      0x00000021      "gpt"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
                (linux)
        guid:   df7a38f6-9df4-11ec-a1e0-1c1b0d6d28f5
  2     0x00002000      0x000023ff      "u-boot-env"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
                (linux)
        guid:   19a4763a-6b19-4a4b-a0c4-8cc34f4c2ab9
  3     0x00002400      0x000033ff      "factory"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
                (linux)
        guid:   8142c1b2-1697-41d9-b1bf-a88d76c7213f
  4     0x00003400      0x000043ff      "fip"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
                (linux)
        guid:   18de6587-4f17-4e08-a6c9-d9d3d424f4c5
  5     0x00004400      0x000143ff      "kernel"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
                (linux)
        guid:   971f7556-ef1a-44cd-8b28-0cf8100b9c7e
  6     0x00014400      0x000943ff      "rootfs"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
                (linux)
        guid:   309a3e76-270b-41b2-b5d5-ed8154e7542b
BPI-R3>


# hexdump -C /dev/mmcblk0p5 | head
00000000  d0 0d fe ed 00 39 11 64  00 00 00 38 00 39 0d 78  |.....9.d...8.9.x|
00000010  00 00 00 28 00 00 00 11  00 00 00 10 00 00 00 00  |...(............|
00000020  00 00 00 6c 00 39 0d 40  00 00 00 00 00 00 00 00  |...l.9.@........|
00000030  00 00 00 00 00 00 00 00  00 00 00 01 00 00 00 00  |................|
00000040  00 00 00 03 00 00 00 04  00 00 00 5c 62 5a bd b6  |...........\bZ..|
00000050  00 00 00 03 00 00 00 29  00 00 00 00 41 52 4d 36  |.......)....ARM6|
00000060  34 20 4f 70 65 6e 57 72  74 20 46 49 54 20 28 46  |4 OpenWrt FIT (F|
00000070  6c 61 74 74 65 6e 65 64  20 49 6d 61 67 65 20 54  |lattened Image T|
00000080  72 65 65 29 00 00 00 00  00 00 00 03 00 00 00 04  |ree)............|
00000090  00 00 00 0c 00 00 00 01  00 00 00 01 69 6d 61 67  |............imag|
#
# hexdump -C /dev/mmcblk0p6 | head
00000000  68 73 71 73 5e 0e 00 00  b6 bd 5a 62 00 00 04 00  |hsqs^.....Zb....|
00000010  81 00 00 00 04 00 12 00  c0 04 01 00 04 00 00 00  |................|
00000020  f5 04 9e 66 00 00 00 00  9c c5 9d 01 00 00 00 00  |...f............|
00000030  94 c5 9d 01 00 00 00 00  ff ff ff ff ff ff ff ff  |................|
00000040  6e bf 9c 01 00 00 00 00  b6 27 9d 01 00 00 00 00  |n........'......|
00000050  8e b6 9d 01 00 00 00 00  6e c5 9d 01 00 00 00 00  |........n.......|
00000060  0c 80 00 00 04 00 14 00  09 00 90 00 40 00 fd 37  |[email protected]|
00000070  7a 58 5a 00 00 01 69 22  de 36 03 c0 99 a7 07 80  |zXZ...i".6......|
00000080  80 10 21 01 0c 00 38 f9  e3 59 e2 2f 7a ef fe 6c  |..!...8..Y./z..l|
00000090  00 3f 91 45 84 60 10 82  f6 2d ff 8e e8 af 20 6c  |.?.E.`...-.... l|
#

If you overwrite emmc with openwrt then it useless searching for problem in ubuntu which is no more there.