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 = { |
| 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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 22 | ctx.actions.write( |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 23 | output = cmdline, |
Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 24 | content = ctx.attr.cmdline, |
| 25 | ) |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 26 | 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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 32 | args = [] |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 33 | 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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 47 | ctx.actions.run( |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 48 | 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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 54 | ) |
Mateusz Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 55 | # Return the unified kernel image file. |
| 56 | return [DefaultInfo(files = depset([image]), runfiles = ctx.runfiles(files = [image]))] |
Lorenz Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 57 | |
| 58 | efi_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 Zalega | 8c2c771 | 2022-01-25 19:42:21 +0100 | [diff] [blame] | 91 | "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 Brun | 2f9f387 | 2021-09-29 19:48:08 +0200 | [diff] [blame] | 103 | "_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 | ) |