From: Daan De Meyer Date: Fri, 15 Dec 2023 13:20:49 +0000 (+0100) Subject: Build initrd if Bootable=auto X-Git-Tag: v20~58^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=73e6b4c75579dbd92d7855f0df87340e03129e97;p=thirdparty%2Fmkosi.git Build initrd if Bootable=auto If building a bootable image is not explicitly disabled and we don't split out an initrd from a UKI because the dependencies are not installed or we're on the wrong architecture, let's still build an initrd so that booting with qemu direct kernel boot still works. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 6e714681e..277aa2757 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -4,6 +4,7 @@ import contextlib import dataclasses import datetime import hashlib +import io import itertools import json import logging @@ -76,6 +77,7 @@ from mkosi.util import ( read_env_file, read_os_release, resource_path, + round_up, scopedenv, try_import, umask, @@ -1412,6 +1414,25 @@ def build_kernel_modules_initrd(state: MkosiState, kver: str) -> Path: return kmods +def join_initrds(initrds: Sequence[Path], output: Path) -> Path: + assert initrds + + if len(initrds) == 1: + copy_tree(initrds[0], output) + return output + + seq = io.BytesIO() + for p in initrds: + initrd = p.read_bytes() + n = len(initrd) + padding = b'\0' * (round_up(n, 4) - n) # pad to 32 bit alignment + seq.write(initrd) + seq.write(padding) + + output.write_bytes(seq.getbuffer()) + return output + + def python_binary(config: MkosiConfig) -> str: # If there's no tools tree, prefer the interpreter from MKOSI_INTERPRETER. If there is a tools # tree, just use the default python3 interpreter. @@ -1692,6 +1713,27 @@ def copy_vmlinuz(state: MkosiState) -> None: break +def copy_initrd(state: MkosiState) -> None: + if (state.staging / state.config.output_split_initrd).exists(): + return + + if state.config.bootable == ConfigFeature.disabled: + return + + if state.config.output_format not in (OutputFormat.disk, OutputFormat.directory): + return + + for kver, _ in gen_kernel_images(state): + microcode = build_microcode_initrd(state) + initrds = [microcode] if microcode else [] + initrds += state.config.initrds or [build_initrd(state)] + if state.config.kernel_modules_initrd: + kver = next(gen_kernel_images(state))[0] + initrds += [build_kernel_modules_initrd(state, kver)] + join_initrds(initrds, state.staging / state.config.output_split_initrd) + break + + def hash_file(of: TextIO, path: Path) -> None: bs = 16 * 1024**2 h = hashlib.sha256() @@ -2565,6 +2607,7 @@ def build_image(args: MkosiArgs, config: MkosiConfig) -> None: make_disk(state, split=True, msg="Extracting partitions") copy_vmlinuz(state) + copy_initrd(state) if state.config.output_format == OutputFormat.tar: make_tar(state.root, state.staging / state.config.output_with_format) diff --git a/mkosi/util.py b/mkosi/util.py index e478e1b95..f932e5276 100644 --- a/mkosi/util.py +++ b/mkosi/util.py @@ -194,3 +194,7 @@ def resource_path(mod: ModuleType) -> Iterator[Path]: t = importlib.resources.files(mod) with importlib.resources.as_file(t) as p: yield p + + +def round_up(x: int, blocksize: int = 4096) -> int: + return (x + blocksize - 1) // blocksize * blocksize