pmbootstrap-meow/pmb/types.py
Henrik Grimler 2872ec6be8
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
2025-07-10 21:03:01 +02:00

296 lines
7.3 KiB
Python

# Copyright 2024 Caleb Connolly
# SPDX-License-Identifier: GPL-3.0-or-later
import enum
import subprocess
from argparse import Namespace
from pathlib import Path
from typing import Any, Literal, TypedDict
from pmb.core.arch import Arch
from pmb.core.chroot import Chroot
class CrossCompile(enum.Enum):
# Cross compilation isn't needed for this package:
# 1) Either because the arch we will build for is exactly the same as the
# native arch, or
# 2) because CPU emulation is not needed (e.g. x86 on x86_64)
UNNECESSARY = "unnecessary"
# Cross compilation disabled, only use QEMU
QEMU_ONLY = "qemu-only"
# Cross compilation will use crossdirect
CROSSDIRECT = "crossdirect"
# Cross compilation will use cross-native
CROSS_NATIVE = "cross-native"
# Cross compilation will use cross-native2
CROSS_NATIVE2 = "cross-native2"
def __str__(self) -> str:
return self.value
def enabled(self) -> bool:
"""Are we cross-compiling for this value of cross?"""
return self not in [CrossCompile.UNNECESSARY, CrossCompile.QEMU_ONLY]
def host_chroot(self, arch: Arch) -> Chroot:
"""Chroot for the package target architecture (the "host" machine).
Cross native (v1) is the exception, since we exclusively use the native
chroot for that."""
if arch == Arch.native():
return Chroot.native()
match self:
case CrossCompile.CROSS_NATIVE:
return Chroot.native()
case _:
return Chroot.buildroot(arch)
def build_chroot(self, arch: Arch) -> Chroot:
"""Chroot for the package build architecture (the "build" machine)."""
if arch == Arch.native():
return Chroot.native()
match self:
case CrossCompile.UNNECESSARY | CrossCompile.CROSSDIRECT | CrossCompile.QEMU_ONLY:
return Chroot.buildroot(arch)
case CrossCompile.CROSS_NATIVE | CrossCompile.CROSS_NATIVE2:
return Chroot.native()
class RunOutputTypeDefault(enum.Enum):
LOG = enum.auto()
STDOUT = enum.auto()
INTERACTIVE = enum.auto()
TUI = enum.auto()
NULL = enum.auto()
def is_to_stdout(self) -> bool:
match self:
case self.STDOUT | self.INTERACTIVE:
return True
case self.LOG | self.TUI | self.NULL:
return False
case _:
raise AssertionError
def has_timeout(self) -> bool:
match self:
case self.LOG | self.STDOUT:
return True
case self.INTERACTIVE | self.TUI | self.NULL:
return False
case _:
raise AssertionError
def has_pass_stdin(self) -> bool:
match self:
case self.INTERACTIVE | self.TUI:
return True
case self.LOG | self.STDOUT | self.NULL:
return False
case _:
raise AssertionError
class RunOutputTypePopen(enum.Enum):
BACKGROUND = enum.auto()
PIPE = enum.auto()
def is_to_stdout(self) -> bool:
return False
def has_timeout(self) -> bool:
return False
def has_pass_stdin(self) -> bool:
return False
RunOutputType = RunOutputTypeDefault | RunOutputTypePopen
RunReturnType = str | int | subprocess.Popen
PathString = Path | str
Env = dict[str, PathString]
Apkbuild = dict[str, Any]
WithExtraRepos = Literal["default", "enabled", "disabled"]
# These types are not definitive / API, they exist to describe the current
# state of things so that we can improve our type hinting coverage and make
# future refactoring efforts easier.
class PartitionLayout(TypedDict):
kernel: int | None
boot: int
reserve: int | None
root: int
class AportGenEntry(TypedDict):
prefixes: list[str]
confirm_overwrite: bool
class Bootimg(TypedDict):
cmdline: str
bootimg_qcdt: str
bootimg_qcdt_type: str | None
bootimg_qcdt_exynos_platform: str | None
bootimg_qcdt_exynos_subtype: str | None
dtb_offset: str | None
dtb_second: str
base: str
kernel_offset: str
ramdisk_offset: str
second_offset: str
tags_offset: str
pagesize: str
header_version: str | None
mtk_label_kernel: str
mtk_label_ramdisk: str
# Property list generated with:
# $ rg --vimgrep "((^|\s)args\.\w+)" --only-matching | cut -d"." -f3 | sort | uniq
class PmbArgs(Namespace):
action_flasher: str
action_initfs: str
action_kconfig: str
action_netboot: str
action_test: str
add: str
all: bool
all_git: bool
all_stable: bool
android_recovery_zip: bool
apkindex_path: Path
aports: list[Path] | None
arch: Arch | None
as_root: bool
assume_yes: bool
auto: bool
autoinstall: bool
boot_size: str
build_default_device_arch: str
buildroot: str
built: bool
ccache: bool
ccache_size: str
chroot_usb: bool
cipher: str
clear_log: bool
cmdline: str
command: str
config: Path
cross: bool
details: bool
details_to_stdout: bool
deviceinfo_parse_kernel: str
devices: str
disk: Path
dry: bool
efi: bool
envkernel: bool
export_folder: Path
extra_space: str
fast: bool
file: str
filesystem: str
flash_method: str
folder: str
force: bool
fork_alpine: bool
fork_alpine_retain_branch: bool
full_disk_encryption: bool
go_mod_cache: bool
hook: str
host: str
host_qemu: bool
http: bool
ignore_depends: bool
image_size: str
image: bool
install_base: bool
install_blockdev: bool
install_cgpt: bool
install_key: bool
install_local_pkgs: bool
install_recommends: bool
is_default_channel: str
iter_time: str
jobs: str
kconfig_check_details: bool
kernel: str
keymap: str
keep_going: bool
lines: int
log: Path
mirror_alpine: str
mirror_postmarketos: str
name: str
nconfig: bool
netboot: bool
no_depends: bool
no_fde: bool
no_firewall: bool
no_image: bool
no_reboot: bool
no_sshd: bool
non_existing: str
odin_flashable_tar: bool
offline: bool
on_device_installer: bool
ondev_cp: list[tuple[str, str]]
ondev_no_rootfs: bool
output: RunOutputType
overview: bool
# FIXME (#2324): figure out the args.package vs args.packages situation
package: str | list[str]
packages: list[str]
partition: str
password: str
path: Path
pkgname: str
pkgname_pkgver_srcurl: str
pkgs_local: bool
pkgs_local_mismatch: bool
pkgs_online_mismatch: bool
port: str
qemu_audio: str
qemu_cpu: str
qemu_display: str
qemu_gl: bool
qemu_kvm: bool
qemu_redir_stdio: str
qemu_tablet: bool
qemu_video: str
recovery_flash_kernel: bool
recovery_install_partition: str
ref: str
replace: bool
repository: str
reset: bool
resume: bool
rootfs: bool
rsync: bool
scripts: str
second_storage: str
sector_size: int | None
selected_providers: dict[str, str]
sparse: bool
split: bool
src: str
ssh_keys: str
strict: bool
sudo_timer: bool
suffix: str
systemd: str
timeout: float
user: str
value: str
verbose: bool
verify: bool
work: Path
xauth: bool
xconfig: bool
zap: bool