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

I’ve solve this issue.

This is caused by invalid value of ‘num of sectors’ of the MBR:

VERBOSE: MBR header entry has an invalid number of sectors
VERBOSE: Failed to access image id=28 (-22)
ERROR:   Failed to parse partition with image id = 28
ERROR:   Partition 'fip' not found
ERROR:   FIP boot source initialization failed with -2

Introduced by refactor(partition): get GPT header location from MBR · ARM-software/arm-trusted-firmware@fce8a70 · GitHub

The ‘num of sectors’ is intended to be the total number of blocks of the eMMC user data area.
However the actual number of blocks varies between emmc chips.
That is, all GPT header generated by tool offline can’t know the number of blocks, and that’s why the value is invalid (Filled with ffffffff).

Of course you can recreate the MBR/GPT online using parted. But to make it always work, I have to patch the ATF to tell it the actual ‘num of sectors’ before parsing MBR.

I’ll update the source code later

1 Like

Thx but it does not explain why sdmmc gpt works. But i have seen that the json from python tool now misses the “gpt” partition started from sector 0. Without bl2 partition i have different numbering of boot and rootfs so currently best way is to use sdmmc partition table. This also makes sdcard image compatibe with emmc :slight_smile: And i do not create gpt with python tool but sgdisk (so i guess not filled with 0xff),but still offline.

I also try to reproduce the mmc init error (read issue) in uboot but have not got it yesterday…have only increased my bootdelay before reading uenv.txt from boot partition and was not able to trigger it yet in ~ 10 cold starts + ~20 reboots (sometimes after linux loaded)

This article is very useful. I was wonder if it is possible to make mt7981/mt7986 support DDR3 1024MiB by modifying the ATF?

mt7981 supports 1024MiB DDR3. no modification needed.

As for mt7986 it’s not verified.

Thank you for your response. I have checked the dram-configs.mk in ATF, and it shows that when using DDR3, AVAIL_DRAM_SIZE only has two options: 256 and 512. Additionally, in the old 20220606 ATF and U-boot source code we are using, DDR3 also has two options: 256 and 512, and there is an ‘auto’ option in menuconfig.

old 20220606 ATF and U-boot:

atf-20220606-637ba581b uboot-mtk-20220606

The Qihoo 360T7 router (mt7981 DDR3 256MiB) was able to automatically recognize 512MiB after an memory upgrade, but when we soldered a 1GiB Micron D9STQ chip, it works, but only recognizes 512MiB. We have used the ‘auto’ option to compile and replace BL2 and FIP, but it had no effect. Therefore, we suspect that modifying ATF is necessary to support 1GiB memory for DDR3.

We also tried soldering an D9STQ on the NetCore N60 router(mt7986a DDR3 256MiB), it works, but only recognizes 512MiB.

BTW, the U-Boot link at the beginning of the article has an extra character ‘\’, preventing it from being accessed directly by clicking.

1 Like

don’t use menuconfig. use command line only. as long as you don’t pass DRAM_SIZE_LIMIT= to make, real ddr size will be used.

oh. I realized you’re using DDR3. only DDR4 supports 1GiB.

Okay. We found that the DDR4 of the mt7981 only supports 1GiB, we test in the CMCC RAX3000M eMMC router. Is that correct?

correct. maximum 1GiB for DDR4

I get it. Thank you so much.

Hello, hackpascal. I have a question that I would like to ask you. Can the Uboot of mt7981 or mt7986 support driving external 2.5G phy chips? I have a MT7986 SOC device on hand. But the downside is that it only has one RTL8221B 2.5G Ethernet port. I have seen similar products on the market, most of which come with a 1000M Ethernet port or an MT7531 switching chip. You can drive these other Ethernet ports within Uboot instead of 2.5G Ethernet ports. Looking forward to your reply! This has been bothering me for a long time.

imho it should work on mt7986 mac, if uboot has driver for the external phy…basicly r3mini is very similar and there it works…not very stable, but this should be the driver of airoha phy.

no idea if it works on mt7531…

U-Boot is currently still missing support for those 2.5G RealTek PHYs – adding that should not be hard given that you can mostly copy & paste from the Linux driver and don’t require perfect performance in U-Boot (so using rate-adapter mode of the PHY for lower speeds and always using 2500Base-X interface mode is acceptable for U-Boot imho). Boils down to setup “2500Base-X with rate-adapter” mode and polling link status.

Hi all. I am trying to replicate OpenWRT’s UBI partition layout for the spim-nand on the BPI-R4. I am using the uboot and mtk-atf from https://github.com/frank-w/u-boot/tree/{2024-04-bpi,mtk-atf}, with some relevant patches from openwrt/package/boot/uboot-mediatek/patches at main · openwrt/openwrt · GitHub.

Based on OP’s instructions I tried:

make PLAT="mt7988" BOOT_DEVICE="spim-nand" BL33=../u-boot/u-boot.bin.xz USE_MKIMAGE= 1 DRAM_USE_COMB=1 UBI=1 all fip

Unfortunately though BL2 cannot find the fip image. Appreciate any help.

NAND boot:

F0: 102B 0000
FA: 1042 0000
FA: 1042 0000 [0200]
F9: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 0600 0041 [0000]
G0: 1190 0000
EC: 0000 0000 [1000]
MK: 0000 0000 [0000]
T0: 0000 019D [0101]
Jump to BL

NOTICE:  BL2: v2.9(release):4e064f88b83 spim-nand
NOTICE:  BL2: Built : 17:50:18, Jun  6 2024
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:  SPI_NAND parses attributes from parameter page.
NOTICE:  SPI_NAND Detected ID 0xef
NOTICE:  Page size 2048, Block size 131072, size 134217728
ERROR:   BL2: Failed to load image id 3 (-2)

MTD layout, SD boot:

spi-nand: spi_nand spi_nand@0: Winbond SPI NAND was found.
spi-nand: spi_nand spi_nand@0: 128 MiB, block size: 128 KiB, page size: 2048, OOB size: 64
List of MTD devices:
* spi-nand0
  - device: spi_nand@0
  - parent: spi@1100a000
  - driver: spi_nand
  - path: /spi@1100a000/spi_nand@0
  - type: NAND flash
  - block size: 0x20000 bytes
  - min I/O: 0x800 bytes
  - OOB size: 64 bytes
  - OOB available: 24 bytes
  - 0x000000000000-0x000008000000 : "spi-nand0"
          - 0x000000000000-0x000000200000 : "bl2"
          - 0x000000200000-0x000008000000 : "ubi"

UBI layout, SD boot:

BPI-R4>  ubi part ubi
ubi0: attaching mtd2
ubi0: scanning is finished
ubi0: attached mtd2 (name "ubi", size 126 MiB)
ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
ubi0: good PEBs: 1008, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 3, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 0
ubi0: available PEBs: 949, total reserved PEBs: 59, PEBs reserved for bad PEB handling: 20
BPI-R4> ubi list
0: fip
1: ubootenv
2: ubootenv2

This looks like TF-A bl2 is built without support for loading bl3 from UBI, despite you correctly passing it the UBI=1 build argument. Which TF-A tree are you building from? Excuse my ignorance, you wrote it clearly. And there is a clear answer: you have to use TF-A from https://github.com/mtk-openwrt/arm-trusted-firmware

My mtk-atf branch is also based from mtk atf repo,but older state where the ubi patches are not in as i have not used this before, so it uses fixed offset for fip. If you flash fip there it should boot uboot correctly

I have done some more testing and I can confirm that both mtk-atf repos ( frank-w’s and mtk-openwrt’s) work if UBI=0, by placing the fip at the default value of 0x580000.

@dangowrt The new repo from mtk-openwrt does not work for me when compiling with UBI=1. It seems to be building an invalid bl2 (see below). Do I need to change anything else to get a valid bl2 when compiling with UBI=1? Perhaps in the uBoot config, or the ATF make commandline?

F0: 102B 0000
FA: 1042 0000
FA: 1042 0000 [0200]
F9: 0000 0000
V0: 7027 6006 [0001]
00: 1017 0000
F9: 0000 0000
V0: 7027 6006 [0001]
01: 102A 0001
02: 1017 0000
BP: 0200 00C0 [0001]
EC: 0000 0000 [1000]
MK: 0000 0000 [0000]
T0: 0000 029E [0101]
System halt!

I don’t know what you are missing, but I can confirm that ATF bl2 built from mtk-openwrt tree definitely works fine, you can download the resulting bl2 here to give it a shot: https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/openwrt-mediatek-filogic-bananapi_bpi-r4-snand-preloader.bin

Thanks hackpascal!

I was able to build latest version of U-boot with latest version for AT-F with patch for PCIe 3.0 from here: https://forum.banana-pi.org/t/bpi-r4-failed-attempt-add-nvme-support-on-uboot/ and I’m able to see the NVME in U-boot. Now I’m working to a script to automate the images build for different scenarios:

  • MMC/eMMC - Firmware + U-boot + Booting + Root FS on MMC/eMMC
  • MMC/eMMC + NVME - Firmware + U-boot on MMC/eMMC and Booting + Root FS on MMC/eMMC on NVME
  • FLASH + NVME - Firmware + U-boot on SPI Flash and Booting + Root FS on MMC/eMMC on NVME

But I have a question to all of you. The original SPI Flash U-Boot has these commands:

mtkautoboot- Display MediaTek bootmenu
mtkboardboot- Boot MTK firmware
mtkload   - MTK image loading utility
mtkupgrade- MTK firmware/bootloader upgrading utility

Where are these commands present? There is a custom U-boot that has these commands? I have no clue where I can add these commands. Anybody has any idea?

These are commands from sdk,not upstreamed in u-boot…why do you need these commands? There is a bootmenu,so you do not need mtk specific implementation.load is maybe combination of load+bootm/go. mtkboardboot sounds similar and upgrade will only work with sdk image…openwrt has different structure and has its own upgrade mechanism.

So why do you need these commands? If you really miss any feature from it it should be added to mainline commands in a generic way.

Thanks for clarifications.

I’ve checked the U-boot OpenWRT source and I found all these commands in boards/mediatek/common.

Anyway there are not portable to newer versions of U-boot mainly because ubi.c moved a lot of functions to static, functions used by one of the helpers.

As you says and also as I’ve noticed I don’t need them.