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") |
| 7 | |
| 8 | def _efi_unified_kernel_image_impl(ctx): |
| 9 | out = ctx.actions.declare_file(ctx.attr.name + ".efi") |
| 10 | |
| 11 | toolchain_info = ctx.attr._toolchain[platform_common.ToolchainInfo] |
| 12 | |
| 13 | sections = [ |
| 14 | dict(name = ".linux", file = ctx.file.kernel, vma = 0x2000000), |
| 15 | ] |
| 16 | |
| 17 | if ctx.attr.cmdline != "": |
| 18 | cmdline_file = ctx.actions.declare_file("cmdline") |
| 19 | ctx.actions.write( |
| 20 | output = cmdline_file, |
| 21 | content = ctx.attr.cmdline, |
| 22 | ) |
| 23 | sections.append(dict(name = ".cmdline", file = cmdline_file, vma = 0x30000)) |
| 24 | |
| 25 | if ctx.file.initramfs: |
| 26 | sections += [dict(name = ".initrd", file = ctx.file.initramfs, vma = 0x5000000)] |
| 27 | if ctx.file.os_release: |
| 28 | sections += [dict(name = ".osrel", file = ctx.file.os_release, vma = 0x20000)] |
| 29 | if ctx.file.splash: |
| 30 | sections += [dict(name = ".splash", file = ctx.file.splash, vma = 0x40000)] |
| 31 | |
| 32 | args = [] |
| 33 | for sec in sections: |
| 34 | args.append("--add-section") |
| 35 | args.append("{}={}".format(sec["name"], sec["file"].path)) |
| 36 | args.append("--change-section-vma") |
| 37 | args.append("{}={}".format(sec["name"], sec["vma"])) |
| 38 | |
| 39 | ctx.actions.run( |
| 40 | mnemonic = "GenEFIKernelImage", |
| 41 | progress_message = "Generating EFI unified kernel image", |
| 42 | inputs = [ctx.file.stub] + [s["file"] for s in sections], |
| 43 | outputs = [out], |
| 44 | executable = toolchain_info.objcopy_executable, |
| 45 | arguments = args + [ |
| 46 | ctx.file.stub.path, |
| 47 | out.path, |
| 48 | ], |
| 49 | ) |
| 50 | return [DefaultInfo(files = depset([out]), runfiles = ctx.runfiles(files = [out]))] |
| 51 | |
| 52 | efi_unified_kernel_image = rule( |
| 53 | implementation = _efi_unified_kernel_image_impl, |
| 54 | attrs = { |
| 55 | "kernel": attr.label( |
| 56 | doc = "The Linux kernel executable bzImage. Needs to have EFI handover and EFI stub enabled.", |
| 57 | mandatory = True, |
| 58 | allow_single_file = True, |
| 59 | ), |
| 60 | "cmdline": attr.string( |
| 61 | doc = "The kernel commandline to be embedded.", |
| 62 | ), |
| 63 | "initramfs": attr.label( |
| 64 | doc = "The initramfs to be embedded.", |
| 65 | allow_single_file = True, |
| 66 | ), |
| 67 | "os_release": attr.label( |
| 68 | doc = """ |
| 69 | The os-release file identifying the operating system. |
| 70 | See https://www.freedesktop.org/software/systemd/man/os-release.html for format. |
| 71 | """, |
| 72 | allow_single_file = True, |
| 73 | ), |
| 74 | "splash": attr.label( |
| 75 | doc = "An image in BMP format which will be displayed as a splash screen until the kernel takes over.", |
| 76 | allow_single_file = True, |
| 77 | ), |
| 78 | "stub": attr.label( |
| 79 | doc = "The stub executable itself as a PE/COFF executable.", |
| 80 | default = "@efistub//:efistub", |
| 81 | allow_single_file = True, |
| 82 | executable = True, |
| 83 | cfg = build_efi_transition, |
| 84 | ), |
| 85 | "_toolchain": attr.label( |
| 86 | doc = "The toolchain used for objcopy.", |
| 87 | default = "//build/toolchain/llvm-efi:efi_cc_suite", |
| 88 | providers = [platform_common.ToolchainInfo], |
| 89 | ), |
| 90 | # Allow for transitions to be attached to this rule. |
| 91 | "_whitelist_function_transition": attr.label( |
| 92 | default = "@bazel_tools//tools/whitelists/function_transition_whitelist", |
| 93 | ), |
| 94 | }, |
| 95 | ) |