Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 1 | """Rules for generating EFI unified kernel images. These are EFI-bootable PE/COFF files containing a stub loader, |
| 2 | a kernel, and optional commandline and initramfs in one file. |
| 3 | See https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images for more information. |
| 4 | """ |
| 5 | |
| 6 | load("//build/toolchain/llvm-efi:transition.bzl", "build_efi_transition") |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 7 | load("//metropolis/node/build:def.bzl", "VerityConfig") |
Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 8 | |
| 9 | def _efi_unified_kernel_image_impl(ctx): |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 10 | # Find the dependency paths to be passed to mkpayload. |
| 11 | deps = { |
Lorenz Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 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, |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 17 | } |
Lorenz Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 18 | |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 19 | # 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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 23 | ctx.actions.write( |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 24 | output = cmdline, |
Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 25 | content = ctx.attr.cmdline, |
| 26 | ) |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 27 | deps["cmdline"] = cmdline |
Lorenz Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 28 | |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 29 | # Get the dm-verity target table from VerityConfig provider. |
| 30 | if ctx.attr.verity: |
Lorenz Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 31 | deps["rootfs_dm_table"] = ctx.attr.verity[VerityConfig].table |
| 32 | |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 33 | # Format deps into command line arguments while keeping track of mkpayload |
| 34 | # runtime inputs. |
Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 35 | args = [] |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 36 | inputs = [] |
| 37 | for name, file in deps.items(): |
Lorenz Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 38 | if file: |
| 39 | args.append("-{}={}".format(name, file.path)) |
| 40 | inputs.append(file) |
| 41 | |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 42 | # 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 Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 46 | |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 47 | # 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 Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 51 | |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 52 | # Run mkpayload. |
Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 53 | ctx.actions.run( |
Lorenz Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 54 | 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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 60 | ) |
Lorenz Brun | f099c09 | 2022-02-24 17:22:26 +0100 | [diff] [blame^] | 61 | |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 62 | # Return the unified kernel image file. |
| 63 | return [DefaultInfo(files = depset([image]), runfiles = ctx.runfiles(files = [image]))] |
Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 64 | |
| 65 | efi_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 Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 98 | "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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 110 | "_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 | ) |