bootimg: exynos: extract platform and subtype from dt.img header

dtbtool-exynos has two options --platform and --subtype that are
embedded in dt.img header and need to match the values that the
bootloader expects. For most devices these values are 0x50a6 and
0x217584da, respectively, but for some they have other values.

Add functionality to parse the dt.img header and extract these values,
and add them to the deviceinfo as
bootimg_qcdt_exynos_{platform,subtype} if they are not equal to the
default values.

Part-of: https://gitlab.postmarketos.org/postmarketOS/pmbootstrap/-/merge_requests/2638
This commit is contained in:
Henrik Grimler 2025-07-04 13:52:55 +02:00 committed by Oliver Smith
parent 7d2f055bcb
commit 2872ec6be8
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
3 changed files with 38 additions and 0 deletions

View file

@ -76,6 +76,25 @@ def get_qcdt_type(path: PathString) -> str | None:
return None return None
def get_qcdt_exynos_platform_subtype(path: PathString) -> tuple:
"""Get the exynos dt.img platform and subtype by reading the first
four bytes of the file.
:param path: to the qcdt image extracted from boot.img
:returns: ( Type tuple with platform and subtype, like ("0x50a6", "0x217584da")
"""
if not os.path.exists(path):
return (None, None)
with open(path, "rb") as f:
header = f.read(24)
platform = hex(int.from_bytes(header[16:20], "little"))
subtype = hex(int.from_bytes(header[20:24], "little"))
return (platform, subtype)
def bootimg(path: Path) -> Bootimg: def bootimg(path: Path) -> Bootimg:
if not path.exists(): if not path.exists():
raise RuntimeError(f"Could not find file '{path}'") raise RuntimeError(f"Could not find file '{path}'")
@ -171,6 +190,15 @@ def bootimg(path: Path) -> Bootimg:
if value is not None if value is not None
} }
) )
if "bootimg_qcdt_type" in output and output["bootimg_qcdt_type"] == "exynos":
platform, subtype = get_qcdt_exynos_platform_subtype(f"{bootimg_path}-dt")
# Omit if platform is default value 0x50a6
if platform and not platform == "0x50a6":
output.update({"bootimg_qcdt_exynos_platform": f"0x{platform:04x}"})
# Omit if subtype is default value 0x217584da
if subtype and not subtype == "0x217584da":
output.update({"bootimg_qcdt_exynos_subtype": f"0x{subtype:08x}"})
output["dtb_second"] = "true" if is_dtb(f"{bootimg_path}-second") else "" output["dtb_second"] = "true" if is_dtb(f"{bootimg_path}-second") else ""
with open(f"{bootimg_path}-cmdline") as f: with open(f"{bootimg_path}-cmdline") as f:
@ -183,6 +211,8 @@ def bootimg(path: Path) -> Bootimg:
cmdline=output["cmdline"], cmdline=output["cmdline"],
bootimg_qcdt=output["bootimg_qcdt"], bootimg_qcdt=output["bootimg_qcdt"],
bootimg_qcdt_type=output.get("bootimg_qcdt_type"), bootimg_qcdt_type=output.get("bootimg_qcdt_type"),
bootimg_qcdt_exynos_platform=output.get("bootimg_qcdt_exynos_platform", ""),
bootimg_qcdt_exynos_subtype=output.get("bootimg_qcdt_exynos_subtype", ""),
dtb_offset=output.get("dtb_offset"), dtb_offset=output.get("dtb_offset"),
dtb_second=output["dtb_second"], dtb_second=output["dtb_second"],
base=output.get("base", ""), base=output.get("base", ""),

View file

@ -135,6 +135,8 @@ class Bootimg(TypedDict):
cmdline: str cmdline: str
bootimg_qcdt: str bootimg_qcdt: str
bootimg_qcdt_type: str | None bootimg_qcdt_type: str | None
bootimg_qcdt_exynos_platform: str | None
bootimg_qcdt_exynos_subtype: str | None
dtb_offset: str | None dtb_offset: str | None
dtb_second: str dtb_second: str
base: str base: str

View file

@ -18,6 +18,8 @@ test_data: dict[str, tuple[Bootimg | None, list[str], list[str]]] = {
kernel_offset="0x8000", kernel_offset="0x8000",
tags_offset="0x100", tags_offset="0x100",
bootimg_qcdt_type=None, bootimg_qcdt_type=None,
bootimg_qcdt_exynos_platform=None,
bootimg_qcdt_exynos_subtype=None,
dtb_offset=None, dtb_offset=None,
dtb_second="", dtb_second="",
pagesize="2048", pagesize="2048",
@ -44,6 +46,8 @@ test_data: dict[str, tuple[Bootimg | None, list[str], list[str]]] = {
kernel_offset="", kernel_offset="",
tags_offset="", tags_offset="",
bootimg_qcdt_type=None, bootimg_qcdt_type=None,
bootimg_qcdt_exynos_platform=None,
bootimg_qcdt_exynos_subtype=None,
dtb_offset="0x101f00000", dtb_offset="0x101f00000",
dtb_second="", dtb_second="",
pagesize="2048", pagesize="2048",
@ -69,6 +73,8 @@ test_data: dict[str, tuple[Bootimg | None, list[str], list[str]]] = {
kernel_offset="", kernel_offset="",
tags_offset="", tags_offset="",
bootimg_qcdt_type=None, bootimg_qcdt_type=None,
bootimg_qcdt_exynos_platform=None,
bootimg_qcdt_exynos_subtype=None,
dtb_offset="", dtb_offset="",
dtb_second="", dtb_second="",
pagesize="4096", pagesize="4096",