[BPI-R64] New bootchain without U-Boot

With a few changes to ATF it is possible to load and start the linux kernel directly from ATF.

Start with http://github.com/mtk-openwrt/arm-trusted-firmware, the default mtksoc branch.

Apply these patches to ATF:

--- a/plat/mediatek/mt7622/bl2_plat_setup.c	2021-09-15 13:35:58.536925357 +0200
+++ b/plat/mediatek/mt7622/bl2_plat_setup.c	2021-09-15 14:00:52.439937687 +0200
@@ -72,7 +72,21 @@
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
 				      image_info_t, 0),
 		.image_info.image_base = BL33_BASE,
-		.image_info.image_max_size = 0x200000 /* 2MB */,
+		.image_info.image_max_size = 0x1000000 /* 16MB */,
+
+#ifdef PRELOADED_BL33_BASE
+		.next_handoff_image_id = NT_FW_CONFIG_ID,
+	},
+	/* Fill NT_FW_CONFIG related information */
+	{
+		.image_id = NT_FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+			VERSION_2, entry_point_info_t, NON_SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+			VERSION_2, image_info_t, 0),
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = BL32_LIMIT,
+#endif
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	}
@@ -126,6 +140,10 @@
 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
 };
 
+static const io_uuid_spec_t ntfwconf_uuid_spec = {
+	.uuid = UUID_NT_FW_CONFIG,
+};
+
 static const io_uuid_spec_t bl32_uuid_spec = {
 	.uuid = UUID_SECURE_PAYLOAD_BL32,
 };
@@ -183,6 +201,11 @@
 		(uintptr_t)&bl31_uuid_spec,
 		check_fip
 	},
+	[NT_FW_CONFIG_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&ntfwconf_uuid_spec,
+		check_fip
+	},
 	[BL32_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl32_uuid_spec,

We need to compile setting PRELOADED_BL33_BASE (use it as a switch to build with or without the changed code).

--- a/plat/mediatek/mt7622/bl31_plat_setup.c	2021-09-15 13:35:58.536925357 +0200
+++ b/plat/mediatek/mt7622/bl31_plat_setup.c	2021-09-15 13:54:41.122386656 +0200
@@ -99,6 +99,13 @@
 	bl33_ep_info.pc = BL33_BASE;
 	bl33_ep_info.spsr = plat_get_spsr_for_bl33_entry();
 	SET_SECURITY_STATE(bl33_ep_info.h.attr, NON_SECURE);
+
+#ifdef PRELOADED_BL33_BASE
+	bl33_ep_info.args.arg0 = (u_register_t)BL32_BASE;
+	bl33_ep_info.args.arg1 = 0U;
+	bl33_ep_info.args.arg2 = 0U;
+	bl33_ep_info.args.arg3 = 0U;
+#endif
 }
 
 /*******************************************************************************

Kernel .dts needs a fix:

--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts	2021-09-15 09:27:26.875953005 +0200
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts	2021-09-15 09:23:25.597138058 +0200
@@ -70,6 +70,7 @@
 	};
 
 	memory {
+		device_type = "memory";
 		reg = <0 0x40000000 0 0x40000000>;
 	};
 

And finally we need to edit the bootargs inside the dts, as U-Boot does not change this anymore for us:

		bootargs = "console=ttyS0,115200 rw rootwait root=PARTLABEL=root-bpir64-sdmmc";

Now build a fip image like this:

   atf/tools/fiptool/fiptool --verbose create fip.bin \
               --soc-fw bl31.bin \
                --nt-fw linux/arch/arm64/boot/Image \
         --nt-fw-config linux/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dtb

And that is about it…

All changes are also found in my buildscript, it is now set as default:

I guess the kernel (fip) needs to be flashed to a fixed position on card,right? That makes impossible to choose kernel/recovery option. And same position is written everytime…with a partition you write different sectors of card. I see no benefit for booting without uboot (except a fixed image that will not change).

All modern SD cards have an internal wear leveling algorithm, some more smart then others. The write to the same blocks end up on different places in flash. It is however fully transparent, internal in the SD card, never notice the difference.

It is called Flash Translation Layer and you can find for example: https://www.hugdiy.com/will-the-microsd-card-be-worn-does-it-have-firmware-in-it-how-is-it-structured-b-243

Anyway it is optional in the script for who likes it.

Just found out a pretty good reason:

I’ve got a couple of microsd cards, this one:

I’ve never been able to use them on the BPI-R64, because U-Boot refuses to load anything, although ATF loaded U-Boot fine

INFO:    BL2: Doing platform setup
INFO:    PMIC: MediaTek MT6380 E3
INFO:    EMI: DRAMC calibration done
INFO:    EMI: complex R/W mem test passed
INFO:    MediaTek MMC/SD Card Controller ver 20160506, eco 0
INFO:    Located GPT partition 'fip' at 0x100000, size 0xf00000
INFO:    BL2: Loading image id 3
INFO:    Loading image id=3 at address 0x43001000
INFO:    Image id=3 loaded: 0x43001000 - 0x4300c0dd
INFO:    BL2: Loading image id 5
INFO:    Loading image id=5 at address 0x41e00000
INFO:    Image id=5 loaded: 0x41e00000 - 0x41e7ddc0
NOTICE:  BL2: Booting BL31
INFO:    Entry point address = 0x43001000
INFO:    SPSR = 0x3cd
INFO:    Secondary bootloader is AArch64
NOTICE:  BL31: v2.4(release):d2c75b2-dirty
NOTICE:  BL31: Built : 20:47:53, Sep 17 2021
INFO:    ARM GICv2 driver initialized                   +-----------------------------+
INFO:    BL31: Initializing runtime services            |                             |
INFO:    BL31: Preparing for EL3 exit to normal world   |  Cannot open /dev/ttyUSB0!  |
INFO:    Entry point address = 0x41e00000               |                             |
INFO:    SPSR = 0x3c9                                   +-----------------------------+
serial_mtk [email protected]: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19

U-Boot 2021.10-rc3-dirty (Sep 17 2021 - 20:47:20 +0200)

CPU:   MediaTek MT7622
Model: mt7622-bpi-r64
DRAM:  1 GiB
WDT:   Started with servicing (60s timeout)
MMC:   [email protected]: 0, [email protected]: 1
Loading Environment from nowhere... OK
In:    [email protected]
Out:   [email protected]
Err:   [email protected]
unable to read ssr
unable to select a mode
mmc_init: -524, time 96
Couldn't find partition mmc 1:
Can't set block device
unable to read ssr
unable to select a mode
mmc_init: -524, time 170
Couldn't find partition mmc 1:
Can't set block device

Card unusable with U-Boot in the bootchain…

But now ATF is able to directly load the kernel, I can use the card without any problem :slight_smile:

So you skip uboot driver which seems to have a bug with your card and atf/linux driver seems to be fixed.

Maybe ask mtk mmc owner for this