When I brought U-Boot up on a Keenetic KN-1012, an MT7981 consumer
router, its stock loader started nothing I offered it but an arm64
kernel image, so U-Boot has to be chainloaded as one and needs that
image header in front of it. U-Boot links at 0x41e00000 there and the
header carries a text_offset of 0x80000, the value the board was brought
up with, which puts the base that offset is measured from at 0x41d80000;
an offset base equal to TEXT_BASE gives a zero offset.

Neither LINUX_KERNEL_IMAGE_HEADER nor LNX_KRNL_IMG_TEXT_OFFSET_BASE has
a prompt, so no defconfig reaches either. Prompting one of them in
arch/arm/Kconfig would change a symbol every arm64 platform shares for
the sake of one board, and giving the offset base a default of TEXT_BASE
there would hand every platform that selects the header and forgets its
own value a silent zero offset. A board that needs the header is
expected to select it and supply the value itself, so both the prompt
and the value stay inside the platform that wants them.

MediaTek has nowhere else to put them. Three of the eight platforms
carrying the offset base today do it from a board Kconfig; MediaTek has
no board Kconfig at all, and a SoC target is no substitute:
TARGET_MT7981, MT7986 and MT7987 carry three defconfigs each and
TARGET_MT7988 two, so a value written under one of them is one value for
every board on that SoC, with nowhere left to override it. The defconfig
is the only per-board file Kconfig reads on MediaTek, so that is where
the value has to be reachable from: a platform bool that selects the
header, and the offset base redeclared under it with a prompt and
default TEXT_BASE, a default only a board that turns the bool on can
reach and whose help text says it gives a zero offset. No board here
sets them: the one this comes from is supported out of tree and is not
on its way in.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <[email protected]>
---
The obvious shape, a prompt on the generic symbols across the arch, was
v1's 1/2. Tom Rini declined it:

  "This isn't a prompted option as boards that need it are expected to
  select it and provide the correct value."
  https://lore.kernel.org/u-boot/20260921155055.GZ858934@bill-the-cat/

After I described the board, he replied:

  "Then yes, a v2 where you just enable this for the platform that needs
  it should be fine, and please make sure to CC all of the mediatek
  maintainers, thanks."
  https://lore.kernel.org/u-boot/20260922151920.GH858934@bill-the-cat/

No MediaTek board in the tree uses the header, so there is nothing here to
just enable it for: the one that does is out of tree, and MediaTek has no
board Kconfig a select could live in. What this v2 adds instead is a
prompted bool inside mach-mediatek, with the offset base prompt only
visible while that bool is on. Tom, is a prompted bool local to MediaTek
acceptable for this, or would you rather it did not go in?

How it was checked. Built on mt7981_rfb_defconfig, which carries the same
TEXT_BASE of 0x41e00000 as the board, reading magic at 0x38 and
text_offset at 0x08 back out of u-boot.bin:

  header on, offset base 0x41d80000  magic ARM\x64, text_offset 0x80000
  header on, offset base default     magic ARM\x64, text_offset 0x0
  stock mt7981_rfb_defconfig         no magic, no header

Left off, the knob changes nothing a board would notice:
mt7981_rfb_defconfig configured on 9e002445cd and on this patch differ by
one line, the comment Kconfig writes for an unset bool that has a prompt,
and by no CONFIG_ value at all. The prompt does not reach past MediaTek
either: apple_m1_defconfig, rock5b-rk3588_defconfig and
p3450-0000_defconfig configure to byte-identical .config files on both
trees, keeping their offset base values of 0x0, 0x800000 and 0x80000000.

savedefconfig on the 0x41d80000 build returns
CONFIG_MTK_KERNEL_IMAGE_HEADER=y and
CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE=0x41d80000, so the defconfig carries
the tree's own name for the value rather than a MediaTek alias. Dropping
the redeclaration and turning the header on anyway reproduces what it is
there to avoid: u-boot.lds:66: undefined symbol
`CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE'.

The offset base is a subtrahend, not a load address: it only sets the
header's text_offset field. Both this board and the mt7981_rfb_defconfig
measured above set CONFIG_POSITION_INDEPENDENT, so U-Boot runs wherever
the loader places it. Not tried: booting the board with text_offset 0. The
board was brought up with 0x80000 and boots with it. My earlier mail said
0x80000 is where the stock loader expects the image; I had not verified
that, and the value is only the one the board was brought up with:
https://lore.kernel.org/u-boot/[email protected]/

Changes in v2:
- Dropped 1/2, which prompted the generic LINUX_KERNEL_IMAGE_HEADER and
  LNX_KRNL_IMG_TEXT_OFFSET_BASE across the arch. Nothing outside
  mach-mediatek changes any more.
- 2/2 grew a platform bool that selects the header, and redeclares
  LNX_KRNL_IMG_TEXT_OFFSET_BASE under it with default TEXT_BASE and a
  prompt, so the value reaches it from a defconfig. Eight platforms
  already redeclare that symbol, five of them with default TEXT_BASE
  (mmp, rockchip, apple, exynos-mobile, vexpress64); none of the eight
  prompts it, and the prompt here is gated on the platform bool.
- Cc: the three ARM MEDIATEK maintainers v1 missed, plus Macpaul Lin.

v1: https://lore.kernel.org/u-boot/[email protected]/

 arch/arm/mach-mediatek/Kconfig | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index e572cfe857..e48fe88529 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -173,6 +173,23 @@ config MTK_MEM_MAP_MMIO_SIZE
        help
          Target-specific MMIO region size in mem_map.
 
+config MTK_KERNEL_IMAGE_HEADER
+       bool "Prepend an arm64 Linux kernel image header"
+       select LINUX_KERNEL_IMAGE_HEADER
+       help
+         Build U-Boot with the arm64 Linux kernel image header in front of
+         it, so that a vendor bootloader that only starts a Linux kernel
+         image starts U-Boot as its payload.
+
+config LNX_KRNL_IMG_TEXT_OFFSET_BASE
+       hex "Address the image header's text offset is measured from"
+       depends on MTK_KERNEL_IMAGE_HEADER
+       default TEXT_BASE
+       help
+         The header's text_offset field is CONFIG_TEXT_BASE minus this value.
+         Set it so that the difference is the text offset the vendor
+         bootloader expects; the default gives a zero offset.
+
 endif
 
 config SYS_BOARD

base-commit: 9e002445cd0d47d3965312f12e97a18e1ed8bd53
-- 
2.53.0

Reply via email to