Skip to content

Commit

Permalink
Introduce support for overriding system's DeviceTree
Browse files Browse the repository at this point in the history
While experimenting with OS images on development boards where either
the bootloader doesn't load a Flattened DeviceTree Blob, or if one wants
to replace the one provided by the bootloader with a specific/new one
for development/experimentation/testing purposes, it's convenient to use
the OS-loaders ability to load a specific DeviceTree blob.

Add a new option to mkosi, to cause a specified DeviceTree blob to be
baked into the UKI, or copied into /boot and added to the systemd loader
entry.

As different distributions store the dtb files in different locations
the requested file is searched for in the locations spotted in Debian,
Fedora, Arch Linux packages (both from distro and kernel build system -
as these differs as well).

Resolves #2439
Based on initial effort by Manuel Traut.

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
  • Loading branch information
quic-bjorande committed Jan 12, 2025
1 parent fe188ce commit 17c3f63
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
31 changes: 31 additions & 0 deletions mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,21 @@ def build_kernel_modules_initrd(context: Context, kver: str) -> Path:
return kmods


def find_requested_devicetree(context: Context, kver: str) -> Path:
assert context.config.devicetree

for f in (
context.root / f"lib/firmware/{kver}/device-tree",
context.root / f"usr/lib/modules/{kver}/dtb",
context.root / f"usr/lib/linux-image-{kver}",
):
dtb = f / context.config.devicetree
if dtb.exists():
return dtb

die(f"Requested devicetree {context.config.devicetree} not found")


def join_initrds(initrds: Sequence[Path], output: Path) -> Path:
assert initrds

Expand Down Expand Up @@ -1609,6 +1624,11 @@ def build_uki(
*flatten(["--ro-bind", os.fspath(profile), os.fspath(workdir(profile))] for profile in profiles),
] # fmt: skip

if context.config.devicetree:
dtb = find_requested_devicetree(context, kver)
arguments += ["--devicetree", workdir(dtb)]
options += ["--ro-bind", dtb, workdir(dtb)]

if context.config.secure_boot:
assert context.config.secure_boot_key
assert context.config.secure_boot_certificate
Expand Down Expand Up @@ -1814,6 +1834,14 @@ def install_type1(

kmods = build_kernel_modules_initrd(context, kver)

dtb = None
if context.config.devicetree:
dtb_src = find_requested_devicetree(context, kver)

dtb = dst / context.config.devicetree
dtb.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(dtb_src, dtb)

with umask(~0o600):
if (
want_efi(context.config)
Expand Down Expand Up @@ -1846,6 +1874,9 @@ def install_type1(
for initrd in initrds:
f.write(f"initrd /{initrd.relative_to(context.root / 'boot')}\n")

if dtb:
f.write(f"devicetree /{dtb.relative_to(context.root / 'boot')}\n")

if want_grub_efi(context) or want_grub_bios(context, partitions):
config = prepare_grub_config(context)
assert config
Expand Down
8 changes: 8 additions & 0 deletions mkosi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,7 @@ class Config:
initrd_packages: list[str]
initrd_volatile_packages: list[str]
microcode_host: bool
devicetree: Optional[Path]
kernel_command_line: list[str]
kernel_modules_include: list[str]
kernel_modules_exclude: list[str]
Expand Down Expand Up @@ -2757,6 +2758,12 @@ def parse_ini(path: Path, only_sections: Collection[str] = ()) -> Iterator[tuple
parse=config_make_list_parser(delimiter=","),
help="Packages to install in the initrd that are not cached",
),
ConfigSetting(
dest="devicetree",
section="Content",
parse=config_parse_string,
help="Devicetree to be used by the booting kernel",
),
ConfigSetting(
dest="kernel_command_line",
metavar="OPTIONS",
Expand Down Expand Up @@ -4816,6 +4823,7 @@ def summary(config: Config) -> str:
Initrds: {line_join_list(config.initrds)}
Initrd Packages: {line_join_list(config.initrd_packages)}
Initrd Volatile Packages: {line_join_list(config.initrd_volatile_packages)}
Devicetree: {config.devicetree}
Kernel Command Line: {line_join_list(config.kernel_command_line)}
Kernel Modules Include: {line_join_list(config.kernel_modules_include)}
Kernel Modules Exclude: {line_join_list(config.kernel_modules_exclude)}
Expand Down
2 changes: 2 additions & 0 deletions tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def test_config() -> None:
"Dependencies": [
"dep1"
],
"Devicetree": "freescale/imx8mm-verdin-nonwifi-dev.dtb",
"Distribution": "fedora",
"Drives": [
{
Expand Down Expand Up @@ -480,6 +481,7 @@ def test_config() -> None:
make_initrd=False,
manifest_format=[ManifestFormat.json, ManifestFormat.changelog],
microcode_host=True,
devicetree=Path("freescale/imx8mm-verdin-nonwifi-dev.dtb"),
minimum_version=GenericVersion("123"),
mirror=None,
nspawn_settings=None,
Expand Down

0 comments on commit 17c3f63

Please sign in to comment.