[Tutorial] Build, customize and use MediaTek open-source U-Boot and ATF

Indeed, I always use powerdown to cleanly power the board down and unplug the power. So I also will need to revert it.

shame they didn’t do like pi5 with a power down button

I wonder why real powerdown is not possible for r4 because it has a pmic (r3 does not).

But for me it is enough to simply halt and not reboot to safely switch off.

The bootrom burned into the MT7986 SoC will try multiple locations on the SPI-NAND flash to load bl2 in case the bl2 image located at the the previously attempted offset is corrupt.

Use 0x100000 instead of 0x80000 as partition size for bl2 on SPI-NAND, allowing for up to four redundant copies of bl2 (typically sized a bit less than 0x40000).

Fixes: 8e01fb15b8157 (“arm64: dts: mt7986: add Bananapi R3”) Signed-off-by: Daniel Golle

So what would be the locations the bootrom will look for bl2? Is it 0x0, 0x40000, 0x80000 and 0xc0000 ? With the word typically, that does not make it very sure, so I thought I can ask here.

Edit:

I’m guessing now that it will try to load starting at every next erase block of 0x20000 ?

Hi @hackpascal

i noticed i get a synchronous abort on r3 mini with 2025.07 uboot (last build with 2025.04 was working). had same with chainload, but tried ramboot here to have a clean bootup.

$ ./Downloads/BPI/r3mini/uartboot/mtk_uartboot -s /dev/ttyUSB4 --aarch64 --payload /media/data_ext/git/uboot/u-boot/bpi-r3mini_ram_bl2.bin --fip /media/data_ext/git/uboot/u-boot/bpi-r3mini_ram_fip.bin ; minicom -D /dev/ttyUSB4
mtk_uartboot - 0.1.1
Using serial port: /dev/ttyUSB4
Handshake...
hw code: 0x7986
hw sub code: 0x8a00
hw ver: 0xca01
sw ver: 0x1
Baud rate set to 460800
sending payload to 0x201000...
Checksum: 0x2792
Setting baudrate back to 115200
Jumping to 0x201000 in aarch64...
Waiting for BL2. Message below:
==================================
NOTICE:  BL2: v2.12.0(release):a385740dfd66-bpi-r3mini-ram
NOTICE:  BL2: Built : 13:36:30, Jul 22 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:  Starting UART download handshake ...
==================================
BL2 UART DL version: 0x10
Baudrate set to: 921600
FIP sent.
==================================
NOTICE:  Received FIP 0x548c5 @ 0x40400000 ...
==================================


Willkommen zu minicom 2.9

Optionen: I18n 
Port /dev/ttyUSB4, 13:38:08

DrĂźcken Sie CTRL-A  Z fĂźr Hilfe zu speziellen Tasten
�NOTICE:  BL31: v2.12.0(release):a385740dfd66-bpi-r3mini-ram
NOTICE:  BL31: Built : 13:36:33, Jul 22 2025


U-Boot 2025.07-bpi-00029-g9ea289987086-dirty (Jul 22 2025 - 13:34:54 +0200)

CPU:   MediaTek MT7986
Model: Bananapi BPi-R3 Mini
DRAM:  2 GiB
Core:  45 devices, 21 uclasses, devicetree: separate
MMC:   "Synchronous Abort" handler, esr 0x96000045, far 0xfe1def50
elr: 0000000041e2c5f0 lr : 0000000041e2c5ac (reloc)
elr: 00000000bff5a5f0 lr : 00000000bff5a5ac
x0 : 8000000000000000 x1 : 0000000000000120
x2 : 00000000ee1c0f50 x3 : 000000001001e000
x4 : 00000000bf7fff28 x5 : 000000000000001e
x6 : 000000000000083c x7 : 00000000bf7fcb70
x8 : 000000000000082c x9 : 00000000bf7fc79c
x10: 0000000000000003 x11: 00000000000007c8
x12: 0000000000000000 x13: 00000000bf7fcb70
x14: 00000000ffffffff x15: 00000000bf7fca98
x16: 00000000bff5a588 x17: 0000000000000000
x18: 00000000bf7ffe10 x19: 00000000bfab0880
x20: 00000000bf7fca88 x21: 00000000bf7fca60
x22: 00000000ffffffda x23: 00000000bffbb568
x24: 00000000bf7fca60 x25: 00000000bffd06a1
x26: 0000000000000000 x27: 0000000000000000
x28: 0000000000000000 x29: 00000000bf7fc980

Code: 9ac22000 d5033fbf b9401822 f9400663 (b8226860) 
Resetting CPU ...

resetting ...

this was a binary where i disabled the airoha driver, so it seems not related. it looks like it is while enumerating MMC, but i see no diffenrence in mtk-sd.c,pinctrl and clock driver (except “remove CONFIG_MT8512”) between 2025.4 and 2025.7. My changes on top should be basicly same, only replaced the old openwrt driver with the one lucien posted to Mailinglist (which i have disabled on second try).

edit: got it fixed with this patch: clk: mediatek: add dummy clk enable/disable ops for apmixedsys clocks ¡ frank-w/u-boot@067b812 ¡ GitHub

How can we access the secure boot functionality of ARM Trusted Firmware as mentioned e.g. here?

“MediaTek’s official U-Boot includes features not generally used by the community, such as dual-FIP, dual-boot, secure-boot, and image verification… and so on.”

Is there a guide to set that up?

We don’t release secure related documents to public …

I see, thanks for the answer. I would assume the required agreements with Mediatek aren’t easily entered into by the average individual consumer?

That’s disappointing, both on the part of BananaPi who advertises this board as an open platform, but also Mediatek. If your implementation is solid, publishing the information required to use it should not make it any less secure. I hope that can be reconsidered in the future.

Raspberry Pi uses proprietary Broadcom SOCs and they at least document the registers needed to burn keys into OTP memory and enable secure boot fully.

Hello,

I try to understand boot process of the bpir4, I checked in mtk-atk src, I found how the bl2 find the bl31 (gpt ‘fip’ label). But I can’t find how bl2 is located.

Best regards,

Bl2 is located by bootrom.it is built into SoC and we have no source for it.

Ah, OK, I thought that bl1, which is part of mtk-atf, was burned in the SoC and provided for information purposes. But in reality, what we call bl2 corresponds to bl1 + bl2 ?

Appreciated the pointer. Now I’m using this:

:smiley:

1 Like

Last year when I tried SinoVoip’s image on BPI-R4, lspci will show output of x86-like host bridge

0004:00:00.0 0002: 14c3:7981 (prog-if 80)
	Subsystem: 7622:14c3
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 117
	Region 0: Memory at 18000000 (64-bit, non-prefetchable) [size=16M]
	Region 2: Memory at <unassigned> (32-bit, non-prefetchable) [size=16]
	Region 3: Memory at <unassigned> (32-bit, non-prefetchable) [size=16]
	Region 4: Memory at <unassigned> (32-bit, non-prefetchable) [size=16]
	Region 5: Memory at <unassigned> (32-bit, non-prefetchable) [size=16]
	Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+

With stock OpenWrt, lspci showed nothing. In both tests, no PCIe boards were installed on BPI-R4.

I believe it’s still true today. What could possibly make such a difference?

The device is MediaTek “wireless baseband system”. Seems to be leftover when copying dtsi from mt7981 in the very early stage of Linux development for MT7988.

[    0.267163] rbus 18000000.wbsys: PCI host bridge to bus 0004:00
[    0.273162] pci_bus 0004:00: root bus resource [mem 0x18000000-0x18ffffff]
[    0.280127] pci_bus 0004:00: root bus resource [bus 00-ff]
[    0.285678] pci_bus 0004:00: scanning bus
[    0.289744] pci 0004:00:00.0: [14c3:7981] type 00 class 0x000280
[    0.295835] pci 0004:00:00.0: reg 0x10: [mem 0x18000000-0x1800000f 64bit]
[    0.302708] pci 0004:00:00.0: reg 0x18: [mem 0x00000000-0x0000000f]
[    0.309052] pci 0004:00:00.0: reg 0x1c: [mem 0x00000000-0x0000000f]
[    0.315395] pci 0004:00:00.0: reg 0x20: [mem 0x00000000-0x0000000f]
[    0.321741] pci 0004:00:00.0: reg 0x24: [mem 0x00000000-0x0000000f]
[    0.329079] pci_bus 0004:00: fixups for bus
[    0.333315] pci_bus 0004:00: bus scan returning with max=00

The device is defined here in DTS:

Interestingly I think this piece of silicon actually exists in MT7988A but is left unused (?). Hence, perhaps removed in subsequent revision of the DTS.

I think my question is off topic. Not related to preboot environment and this thread.