from mkosi.archive import can_extract_tar, extract_tar, make_cpio, make_tar
from mkosi.bootloader import (
+ KernelType,
efi_boot_binary,
extract_pe_section,
gen_kernel_images,
from mkosi.pager import page
from mkosi.partition import Partition, finalize_root, finalize_roothash
from mkosi.qemu import (
- KernelType,
copy_ephemeral,
finalize_credentials,
finalize_kernel_command_line_extra,
# SPDX-License-Identifier: LGPL-2.1-or-later
+import enum
import itertools
import logging
import os
from mkosi.distributions import Distribution
from mkosi.log import complete_step, die, log_step
from mkosi.partition import Partition
-from mkosi.qemu import KernelType
from mkosi.run import CompletedProcess, run, workdir
from mkosi.sandbox import umask
-from mkosi.util import _FILE, PathString, flatten
+from mkosi.util import _FILE, PathString, StrEnum, flatten
from mkosi.versioncomp import GenericVersion
+class KernelType(StrEnum):
+ pe = enum.auto()
+ uki = enum.auto()
+ addon = enum.auto()
+ unknown = enum.auto()
+
+ @classmethod
+ def identify(cls, config: Config, path: Path) -> "KernelType":
+ pefile = textwrap.dedent(
+ f"""\
+ import pefile
+
+ try:
+ pe = pefile.PE("{workdir(path)}", fast_load=True)
+ sections = {{s.Name.decode().strip("\\0") for s in pe.sections}}
+
+ if all(s in sections for s in (".linux", ".sdmagic", ".osrel")):
+ print("{KernelType.uki}")
+ elif (
+ all(s in sections for s in (".linux", ".sdmagic")) and
+ any(s in sections for s in (".cmdline", ".dtb", ".initrd", ".ucode"))
+ ):
+ print("{KernelType.addon}")
+ else:
+ print("{KernelType.pe}")
+ except pefile.PEFormatError:
+ print("{KernelType.unknown}")
+ """
+ )
+
+ result = run(
+ [python_binary(config)],
+ input=pefile,
+ stdout=subprocess.PIPE,
+ sandbox=config.sandbox(options=["--ro-bind", path, workdir(path)]),
+ )
+
+ return KernelType(result.stdout.strip())
+
+
def want_efi(config: Config) -> bool:
# Do we want to make the image bootable on EFI firmware?
# Note that this returns True also in the case where autodetection might later cause the system to not be
from pathlib import Path
from typing import Optional
+from mkosi.bootloader import KernelType
from mkosi.config import (
Args,
Config,
die("Failed to find an unused VSock connection ID")
-class KernelType(StrEnum):
- pe = enum.auto()
- uki = enum.auto()
- unknown = enum.auto()
-
- @classmethod
- def identify(cls, config: Config, path: Path) -> "KernelType":
- if not config.find_binary("bootctl"):
- logging.warning("bootctl is not installed, assuming 'unknown' kernel type")
- return KernelType.unknown
-
- if (v := systemd_tool_version("bootctl", sandbox=config.sandbox)) < 253:
- logging.warning(f"bootctl {v} doesn't know kernel-identify verb, assuming 'unknown' kernel type")
- return KernelType.unknown
-
- type = run(
- ["bootctl", "kernel-identify", workdir(path)],
- stdout=subprocess.PIPE,
- sandbox=config.sandbox(options=["--ro-bind", path, workdir(path)]),
- ).stdout.strip()
-
- try:
- return cls(type)
- except ValueError:
- logging.warning(f"Unknown kernel type '{type}', assuming 'unknown'")
- return KernelType.unknown
-
-
def find_qemu_binary(config: Config) -> Path:
options = [f"qemu-system-{config.architecture.to_qemu()}"]