blob: 12d32db1e37576ebf3ebb0449f17c19af69a6b71 [file] [log] [blame]
Lorenz Brun2f9f3872021-09-29 19:48:08 +02001"""Rules for generating EFI unified kernel images. These are EFI-bootable PE/COFF files containing a stub loader,
2a kernel, and optional commandline and initramfs in one file.
3See https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images for more information.
4"""
5
6load("//build/toolchain/llvm-efi:transition.bzl", "build_efi_transition")
Mateusz Zalega8c2c7712022-01-25 19:42:21 +01007load("//metropolis/node/build:def.bzl", "VerityConfig")
Lorenz Brun2f9f3872021-09-29 19:48:08 +02008
9def _efi_unified_kernel_image_impl(ctx):
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010010 # Find the dependency paths to be passed to mkpayload.
11 deps = {
12 "linux": ctx.file.kernel,
13 "initrd": ctx.file.initramfs,
14 "osrel": ctx.file.os_release,
15 "splash": ctx.file.splash,
16 "stub": ctx.file.stub,
17 }
18 # Since cmdline is a string attribute, put it into a file, then append
19 # that file to deps.
20 if ctx.attr.cmdline and ctx.attr.cmdline != "":
21 cmdline = ctx.actions.declare_file("cmdline")
Lorenz Brun2f9f3872021-09-29 19:48:08 +020022 ctx.actions.write(
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010023 output = cmdline,
Lorenz Brun2f9f3872021-09-29 19:48:08 +020024 content = ctx.attr.cmdline,
25 )
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010026 deps["cmdline"] = cmdline
27 # Get the dm-verity target table from VerityConfig provider.
28 if ctx.attr.verity:
29 deps["rootfs_dm_table"] = ctx.attr.verity[VerityConfig].table
30 # Format deps into command line arguments while keeping track of mkpayload
31 # runtime inputs.
Lorenz Brun2f9f3872021-09-29 19:48:08 +020032 args = []
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010033 inputs = []
34 for name, file in deps.items():
35 if file:
36 args.append("-{}={}".format(name, file.path))
37 inputs.append(file)
38 # Append the output parameter separately, as it doesn't belong with the
39 # runtime inputs.
40 image = ctx.actions.declare_file(ctx.attr.name + ".efi")
41 args.append("-output={}".format(image.path))
42 # Append the objcopy parameter separately, as it's not of File type, and
43 # it does not constitute an input, since it's part of the toolchain.
44 objcopy = ctx.attr._toolchain[platform_common.ToolchainInfo].objcopy_executable
45 args.append("-objcopy={}".format(objcopy))
46 # Run mkpayload.
Lorenz Brun2f9f3872021-09-29 19:48:08 +020047 ctx.actions.run(
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010048 mnemonic = "GenEFIKernelImage",
49 progress_message = "Generating EFI unified kernel image",
50 inputs = inputs,
51 outputs = [image],
52 executable = ctx.file._mkpayload,
53 arguments = args
Lorenz Brun2f9f3872021-09-29 19:48:08 +020054 )
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010055 # Return the unified kernel image file.
56 return [DefaultInfo(files = depset([image]), runfiles = ctx.runfiles(files = [image]))]
Lorenz Brun2f9f3872021-09-29 19:48:08 +020057
58efi_unified_kernel_image = rule(
59 implementation = _efi_unified_kernel_image_impl,
60 attrs = {
61 "kernel": attr.label(
62 doc = "The Linux kernel executable bzImage. Needs to have EFI handover and EFI stub enabled.",
63 mandatory = True,
64 allow_single_file = True,
65 ),
66 "cmdline": attr.string(
67 doc = "The kernel commandline to be embedded.",
68 ),
69 "initramfs": attr.label(
70 doc = "The initramfs to be embedded.",
71 allow_single_file = True,
72 ),
73 "os_release": attr.label(
74 doc = """
75 The os-release file identifying the operating system.
76 See https://www.freedesktop.org/software/systemd/man/os-release.html for format.
77 """,
78 allow_single_file = True,
79 ),
80 "splash": attr.label(
81 doc = "An image in BMP format which will be displayed as a splash screen until the kernel takes over.",
82 allow_single_file = True,
83 ),
84 "stub": attr.label(
85 doc = "The stub executable itself as a PE/COFF executable.",
86 default = "@efistub//:efistub",
87 allow_single_file = True,
88 executable = True,
89 cfg = build_efi_transition,
90 ),
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010091 "verity": attr.label(
92 doc = "The DeviceMapper Verity rootfs target table.",
93 allow_single_file = True,
94 providers = [DefaultInfo, VerityConfig],
95 ),
96 "_mkpayload": attr.label(
97 doc = "The mkpayload executable.",
98 default = "//metropolis/node/build/mkpayload",
99 allow_single_file = True,
100 executable = True,
101 cfg = "exec",
102 ),
Lorenz Brun2f9f3872021-09-29 19:48:08 +0200103 "_toolchain": attr.label(
104 doc = "The toolchain used for objcopy.",
105 default = "//build/toolchain/llvm-efi:efi_cc_suite",
106 providers = [platform_common.ToolchainInfo],
107 ),
108 # Allow for transitions to be attached to this rule.
109 "_whitelist_function_transition": attr.label(
110 default = "@bazel_tools//tools/whitelists/function_transition_whitelist",
111 ),
112 },
113)