blob: 059821dbfd2fa7a688139f61c08d2778370659d7 [file] [log] [blame]
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Flexor build library."""
import os
from pathlib import Path
from typing import Optional
from chromite.lib import build_target_lib
from chromite.lib import cros_build_lib
from chromite.lib import kernel_builder
FLEXOR_KERNEL_IMAGE = Path("flexor.img")
FLEXOR_VMLINUZ = Path("flexor_vmlinuz")
KERNEL_FLAGS = (
"flexor_ramfs",
"tpm",
"i2cdev",
"vfat",
"kernel_compress_xz",
"pcserial",
"-kernel_afdo",
)
class Error(Exception):
"""Base error class for the module."""
class FlexorBuildError(Error):
"""Error class thrown when failing to build the Flexor kernel (image)."""
def create_flexor_kernel_image(
build_target: build_target_lib.BuildTarget,
version: str,
work_dir: Path,
keys_dir: Path,
public_key: Path,
private_key: Path,
keyblock: Path,
serial: Optional[str],
jobs: int,
build_kernel: bool = True,
) -> str:
"""Creates the Flexor kernel image.
And puts it in the work directory.
Args:
jobs: The number of packages to build in parallel.
build_target: The target to build the kernel for.
version: The chromeos version string.
work_dir: The directory for keeping intermediary files.
keys_dir: The path to kernel keys directories.
public_key: Filename to the public key whose private part signed the
keyblock.
private_key: Filename to the private key whose public part is baked into
the keyblock.
keyblock: Filename to the kernel keyblock.
serial: Serial port for the kernel console (e.g. printks).
build_kernel: Build a new kernel from source.
Returns:
The path to the generated kernel image.
"""
board = build_target.name
install_root = Path(build_target.full_path("factory-root"))
kb = kernel_builder.Builder(board, work_dir, install_root, jobs)
if build_kernel:
# Flexor ramfs cannot be built with multiple conflicting `_ramfs`
# flags.
try:
kb.CreateCustomKernel(
KERNEL_FLAGS,
[
x
for x in os.environ.get("USE", "").split()
if not x.endswith("_ramfs")
],
)
except kernel_builder.KernelBuildError as e:
raise FlexorBuildError(
"flexor: Failed to build flexor kernel image"
) from e
kernel = work_dir / FLEXOR_KERNEL_IMAGE
assert " " not in version, f"bad version: {version}"
boot_args = f"noinitrd panic=60 cros_flexor_version={version}"
try:
kb.CreateKernelImage(
kernel,
boot_args=boot_args,
serial=serial,
keys_dir=keys_dir,
public_key=public_key,
private_key=private_key,
keyblock=keyblock,
)
except:
raise FlexorBuildError(
"flexor: Failed to create flexor kernel image"
) from e
vmlinuz = work_dir / FLEXOR_VMLINUZ
try:
cros_build_lib.sudo_run(
["vbutil_kernel", "--get-vmlinuz", kernel, "--vmlinuz-out", vmlinuz]
)
except cros_build_lib.RunCommandError as e:
raise FlexorBuildError("Failed to extract flexor vmlinuz") from e
return vmlinuz