Skip to content

ambarella: s3l: Amcrest IP4M-1026E, with the board DTB appended to the uImage - #178

Merged
openipc-ai merged 3 commits into
OpenIPC:ambarella-s3lfrom
DeathCamel58:s3l-uimage-dtb
Nov 7, 2026
Merged

openipc-ai merged 3 commits into
OpenIPC:ambarella-s3lfrom
DeathCamel58:s3l-uimage-dtb

Conversation

@DeathCamel58

Copy link
Copy Markdown

Problem

The Amcrest IP4M-1026E (Dahua IPC-HFW1430SN) boots through Dahua's U-Boot, which passes ATAGs and never a device tree, so the board DTB has to travel with the kernel (CONFIG_ARM_APPENDED_DTB). Buildroot's appended-uImage option can do that, but it names the result uImage.<dtb>, and the firmware's repack step only picks up uImage.

Change

ambarella: s3l: append a board DTB to the uImage. This follows the Anyka kernel: CONFIG_AMBARELLA_OPENIPC_DTB names the board's DTB (without .dtb), and the uImage target then wraps the zImage plus that DTB (zImage-dtb), still called uImage. It's empty by default, which leaves the uImage the plain zImage, so boards whose boot loader passes a DTB are unchanged.

ambarella: s3l: Amcrest IP4M-1026E device tree (ambarella-s3l-ip4m1026e.dts):

  • memory as the stock firmware splits it: 118 MiB for Linux, the rest for the DSP (the dtsi's 126 MiB would overlap it);
  • SPI-NOR on, NAND off (they share pins);
  • the VIN placeholder on i2c0 that sensor modules rename, and the OV4689 reset on GPIO 107, active low;
  • IR receiver, I2S and sdmmc0 off, since the board has none: their pins are the reset button (GPIO 34) and a status-LED output (GPIO 60);
  • the bit-banged MDIO off, as it would share the MAC's pins.

Testing

On the IP4M-1026E:

  • With CONFIG_AMBARELLA_OPENIPC_DTB="ambarella-s3l-ip4m1026e", the uImage is exactly the zImage plus the board DTB. It boots from TFTP (with an initramfs) and from SPI-NOR, flashed through the Dahua U-Boot.
  • Booted that way, the OV4689, SPI-NOR, Ethernet and IAV come up, and the camera streams H.264.
  • With the option empty, the uImage is exactly the plain zImage.

The board's OpenIPC profile (OpenIPC/builder, to follow) sets the option and uses this DTS. For a settings overlay on flash it also needs overlayfs (#177).

Boot loaders like the Dahua one on the Amcrest IP4M-1026E pass ATAGs,
never a device tree, so the board DTB has to travel with the kernel
(CONFIG_ARM_APPENDED_DTB). Buildroot's appended-uImage option names the
result uImage.<dtb>, which the firmware's repack step doesn't pick up.

As on the Anyka kernel: CONFIG_AMBARELLA_OPENIPC_DTB names the board's
DTB, and the uImage target then wraps zImage plus that DTB, still called
uImage. Left empty (the default), the uImage stays the plain zImage, so
boards whose boot loader passes a DTB are unchanged.

Tested for the IP4M-1026E: with the DTB set, the uImage carries zImage
plus the board DTB, netboots with an initramfs, and the flash build
repacks it; with the option empty, the uImage carries the plain zImage.
Amcrest IP4M-1026E (Dahua IPC-HFW1430SN): S3L, OV4689 over MIPI, 32 MiB
SPI-NOR, RTL8201F over RMII. Its Dahua U-Boot boots with ATAGs, so this
is the DTB a board build appends to the uImage
(CONFIG_AMBARELLA_OPENIPC_DTB="ambarella-s3l-ip4m1026e").

- Memory as the stock firmware splits it: 118 MiB for Linux above the
  boot area, the rest for the DSP (the dtsi's 126 MiB would overlap it).
- SPI-NOR on, NAND off (shared pins).
- The VIN placeholder on i2c0 the sensor modules rename, and the sensor
  reset on GPIO 107, active low.
- IR receiver, I2S and sdmmc0 off: the board has none, and their pins
  are the reset button (GPIO 34) and a status LED output (GPIO 60).
- The bit-banged MDIO off, as it would share the MAC's pins.

Tested on the IP4M-1026E: netbooted with this DTB appended, the sensor,
SPI-NOR, Ethernet and IAV come up and Divinus streams.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add Amcrest IP4M-1026E device tree and optional DTB-appended uImage

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Add an optional board DTB to the standard uImage for ATAG-only boot loaders.
• Define the IP4M-1026E memory layout, sensor connections, and available peripherals.
• Preserve the plain-zImage uImage when no board DTB is configured.
Diagram

graph TD
  C["DTB config"] --> M["Machine boot make"] --> A["ARM boot make"] --> P(["Appended zImage"]) --> U(["uImage"]) --> B["Dahua U-Boot"]
  D["Board device tree"] -->|compiled DTB| P
  Z(["Plain zImage"]) --> P
  Z -->|empty config| U
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Rename Buildroot's appended uImage
  • ➕ Avoids changing the kernel's uImage build rule.
  • ➖ Requires a board-specific rename or copy step in firmware packaging to supply the expected uImage filename.
2. Pass a separate DTB from U-Boot
  • ➕ Keeps the kernel image and device tree separate.
  • ➖ Requires changing the existing ATAG-only boot flow on the device.

Recommendation: Keep the optional append in the kernel build: it supplies the filename the repack step expects while preserving the existing plain-image path. A Buildroot rename is viable but moves board-specific handling into packaging; changing U-Boot is less practical for this device.

Files changed (4) +135 / -2

Enhancement (2) +123 / -2
MakefileSelect plain or DTB-appended input for uImage +13/-2

Select plain or DTB-appended input for uImage

• Adds a zImage-dtb target that concatenates the kernel and selected DTB. The uImage target uses it when a DTB is configured and otherwise continues to wrap the plain zImage.

arch/arm/boot/Makefile

ambarella-s3l-ip4m1026e.dtsDescribe IP4M-1026E memory and board peripherals +110/-0

Describe IP4M-1026E memory and board peripherals

• Adds the board's Linux/DSP memory split, sensor I2C placeholder and reset GPIO, SPI-NOR, and Ethernet pin and PHY settings. Disables absent or pin-conflicting NAND, IR, I2S, SD, and bit-banged MDIO devices.

arch/arm/boot/dts/ambarella-s3l-ip4m1026e.dts

Other (2) +12 / -0
KconfigExpose an optional Ambarella uImage DTB setting +9/-0

Expose an optional Ambarella uImage DTB setting

• Adds a string setting for the board DTB name without its extension. Its empty default preserves plain-zImage uImages.

arch/arm/mach-ambarella/Kconfig

Makefile.bootResolve the configured board name to a DTB filename +3/-0

Resolve the configured board name to a DTB filename

• Strips Kconfig's string quotes and supplies the selected .dtb filename to the ARM boot Makefile when the setting is nonempty.

arch/arm/mach-ambarella/Makefile.boot

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Selected board trees are ignored at boot ✓ Resolved
Description
CONFIG_AMBARELLA_OPENIPC_DTB makes the build append a DTB without requiring
CONFIG_ARM_APPENDED_DTB, which controls whether the decompressor reads it. With the existing S3L
default configuration, setting only the new board-tree option produces a uImage containing a DTB
that the kernel does not use.

2. Flash boots lose root-device arguments 🐞 Bug ≡ Correctness
Description
The new board DTS relies on the bootloader's ATAG command line, but the appended-DTB boot path
merges ATAG data only when CONFIG_ARM_ATAG_DTB_COMPAT is enabled. If a board build enables
appended-DTB support without that separate option, the DTB supplies no bootargs, so the
bootloader's root-device and flash-partition arguments do not reach the kernel.
Code

arch/arm/boot/dts/ambarella-s3l-ip4m1026e.dts[R6-7]

+ * The Dahua U-Boot 2010.06 on this board boots with ATAGs, so the kernel is built with this
+ * DTB appended. Flash partitions and the root device come from the kernel command line.
Evidence
The DTS says the command line supplies the root device and partitions, but neither it nor the
included chosen node supplies bootargs. The decompressor calls atags_to_fdt only under the
independent compatibility option, and the S3L default configuration does not enable that option.

arch/arm/boot/dts/ambarella-s3l-ip4m1026e.dts[5-7]
arch/arm/boot/dts/ambarella-s3l.dtsi[35-41]
arch/arm/boot/compressed/head.S[255-269]
arch/arm/Kconfig[1952-1964]
arch/arm/configs/ambarella_s3l_defconfig[516-527]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
This board obtains its root-device and partition arguments from ATAGs, but an appended DTB does not inherit them without ARM_ATAG_DTB_COMPAT.
## Fix Focus Areas
- arch/arm/mach-ambarella/Kconfig[66-74]
- arch/arm/boot/dts/ambarella-s3l-ip4m1026e.dts[5-7]
## Recommended Fix
Ensure configurations selecting this board's appended DTB also enable CONFIG_ARM_ATAG_DTB_COMPAT. Keep bootloader command-line merging enabled for the ATAG-based boot path.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Repeat image builds needlessly repackage 🐞 Bug ➹ Performance
Description
zImage-dtb has a FORCE prerequisite and runs cat unconditionally rather than checking whether
its inputs changed. Every repeat uImage build with a selected DTB rewrites zImage-dtb, making
the uImage packaging rule run again even when the kernel and DTB are unchanged.
Code

arch/arm/boot/Makefile[R65-66]

+$(obj)/zImage-dtb:	$(obj)/zImage $(DTB_OBJS_FULL) FORCE
+	@cat $(obj)/zImage $(DTB_OBJS_FULL) > $@
Evidence
FORCE schedules the new recipe on each invocation, and its unconditional cat changes the output
timestamp. The dependent uImage target uses if_changed, whose prerequisite check then observes the
newer zImage-dtb.

arch/arm/boot/Makefile[65-67]
arch/arm/boot/Makefile[89-92]
scripts/Kbuild.include[190-225]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The appended-image recipe rewrites its output on every build and thereby invalidates the packaged uImage.
## Fix Focus Areas
- arch/arm/boot/Makefile[65-67]
## Recommended Fix
Use a Kbuild change-aware command for the concatenation so zImage-dtb is rewritten only when its inputs or command change. Retain dependencies on both zImage and the selected DTB.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can hide the parts of a finding you never read, like the evidence or the agent prompt

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

The decompressor only looks for an appended DTB with
CONFIG_ARM_APPENDED_DTB, so CONFIG_AMBARELLA_OPENIPC_DTB without it
built a uImage carrying a blob the kernel ignores. It now depends on
ARM_APPENDED_DTB, as hisilicon-hi3516cv6xx's
BUILD_ARM_APPENDED_DTB_IMAGE_NAMES does; without it the option is hidden
and the uImage stays the plain zImage.

The IP4M-1026E DTS comment now says which command line the board uses:
the built-in one (CONFIG_CMDLINE), since the one its U-Boot passes is the
stock firmware's.

Tested: with the board's config the uImage is still the zImage plus the
board DTB, and the DTB is unchanged; with ARM_APPENDED_DTB off,
olddefconfig drops the option and the uImage is the plain zImage.
@DeathCamel58

Copy link
Copy Markdown
Author

Thanks. Point 1 is fixed in 11dc6ba: CONFIG_AMBARELLA_OPENIPC_DTB now depends on ARM_APPENDED_DTB, as hisilicon-hi3516cv6xx's BUILD_ARM_APPENDED_DTB_IMAGE_NAMES does. Without it the option is hidden and the uImage stays the plain zImage.

Point 2 is intentional. The Dahua U-Boot passes the stock firmware's command line (root=/dev/mtdblock5 and the stock flash layout), so this board takes its command line from CONFIG_CMDLINE in its kernel fragment. ARM_ATAG_DTB_COMPAT would merge the stock arguments back in. The same commit rewords the DTS comment to say so.

Point 3: the FORCE + cat rule is the one every OpenIPC ARM kernel uses (anyka-ak3918ev300, hisilicon-hi3516cv500/ev200/cv6xx), so I've kept it as is here. A change to it would make sense across all of those kernels at once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants