blob: f9d0f44834ce7e5bfdbd443770a695293ebf9311 [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 = {
Lorenz Brunf099c092022-02-24 17:22:26 +010012 "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,
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010017 }
Lorenz Brunf099c092022-02-24 17:22:26 +010018
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010019 # Since cmdline is a string attribute, put it into a file, then append
20 # that file to deps.
21 if ctx.attr.cmdline and ctx.attr.cmdline != "":
22 cmdline = ctx.actions.declare_file("cmdline")
Lorenz Brun2f9f3872021-09-29 19:48:08 +020023 ctx.actions.write(
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010024 output = cmdline,
Lorenz Brun2f9f3872021-09-29 19:48:08 +020025 content = ctx.attr.cmdline,
26 )
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010027 deps["cmdline"] = cmdline
Lorenz Brunf099c092022-02-24 17:22:26 +010028
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010029 # Get the dm-verity target table from VerityConfig provider.
30 if ctx.attr.verity:
Lorenz Brunf099c092022-02-24 17:22:26 +010031 deps["rootfs_dm_table"] = ctx.attr.verity[VerityConfig].table
32
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010033 # Format deps into command line arguments while keeping track of mkpayload
34 # runtime inputs.
Lorenz Brun2f9f3872021-09-29 19:48:08 +020035 args = []
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010036 inputs = []
37 for name, file in deps.items():
Lorenz Brunf099c092022-02-24 17:22:26 +010038 if file:
39 args.append("-{}={}".format(name, file.path))
40 inputs.append(file)
41
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010042 # Append the output parameter separately, as it doesn't belong with the
43 # runtime inputs.
44 image = ctx.actions.declare_file(ctx.attr.name + ".efi")
45 args.append("-output={}".format(image.path))
Lorenz Brunf099c092022-02-24 17:22:26 +010046
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010047 # Append the objcopy parameter separately, as it's not of File type, and
48 # it does not constitute an input, since it's part of the toolchain.
49 objcopy = ctx.attr._toolchain[platform_common.ToolchainInfo].objcopy_executable
50 args.append("-objcopy={}".format(objcopy))
Lorenz Brunf099c092022-02-24 17:22:26 +010051
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010052 # Run mkpayload.
Lorenz Brun2f9f3872021-09-29 19:48:08 +020053 ctx.actions.run(
Lorenz Brunf099c092022-02-24 17:22:26 +010054 mnemonic = "GenEFIKernelImage",
55 progress_message = "Generating EFI unified kernel image",
56 inputs = inputs,
57 outputs = [image],
58 executable = ctx.file._mkpayload,
59 arguments = args,
Lorenz Brun2f9f3872021-09-29 19:48:08 +020060 )
Lorenz Brunf099c092022-02-24 17:22:26 +010061
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010062 # Return the unified kernel image file.
63 return [DefaultInfo(files = depset([image]), runfiles = ctx.runfiles(files = [image]))]
Lorenz Brun2f9f3872021-09-29 19:48:08 +020064
65efi_unified_kernel_image = rule(
66 implementation = _efi_unified_kernel_image_impl,
67 attrs = {
68 "kernel": attr.label(
69 doc = "The Linux kernel executable bzImage. Needs to have EFI handover and EFI stub enabled.",
70 mandatory = True,
71 allow_single_file = True,
72 ),
73 "cmdline": attr.string(
74 doc = "The kernel commandline to be embedded.",
75 ),
76 "initramfs": attr.label(
77 doc = "The initramfs to be embedded.",
78 allow_single_file = True,
79 ),
80 "os_release": attr.label(
81 doc = """
82 The os-release file identifying the operating system.
83 See https://www.freedesktop.org/software/systemd/man/os-release.html for format.
84 """,
85 allow_single_file = True,
86 ),
87 "splash": attr.label(
88 doc = "An image in BMP format which will be displayed as a splash screen until the kernel takes over.",
89 allow_single_file = True,
90 ),
91 "stub": attr.label(
92 doc = "The stub executable itself as a PE/COFF executable.",
93 default = "@efistub//:efistub",
94 allow_single_file = True,
95 executable = True,
96 cfg = build_efi_transition,
97 ),
Mateusz Zalega8c2c7712022-01-25 19:42:21 +010098 "verity": attr.label(
99 doc = "The DeviceMapper Verity rootfs target table.",
100 allow_single_file = True,
101 providers = [DefaultInfo, VerityConfig],
102 ),
103 "_mkpayload": attr.label(
104 doc = "The mkpayload executable.",
105 default = "//metropolis/node/build/mkpayload",
106 allow_single_file = True,
107 executable = True,
108 cfg = "exec",
109 ),
Lorenz Brun2f9f3872021-09-29 19:48:08 +0200110 "_toolchain": attr.label(
111 doc = "The toolchain used for objcopy.",
112 default = "//build/toolchain/llvm-efi:efi_cc_suite",
113 providers = [platform_common.ToolchainInfo],
114 ),
115 # Allow for transitions to be attached to this rule.
116 "_whitelist_function_transition": attr.label(
117 default = "@bazel_tools//tools/whitelists/function_transition_whitelist",
118 ),
119 },
120)