blob: 036743e878afd70483cae6b56f7d8466db47a53d [file] [log] [blame]
Serge Bazanskif055a7f2021-04-13 16:22:33 +02001# Copyright 2020 The Monogon Project Authors.
2#
3# SPDX-License-Identifier: Apache-2.0
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""
18Rules for building Linux kernel images.
19
20This currently performs the build in a fully unhermetic manner, using
Leopoldbc93c2b2023-01-14 13:12:23 +010021make/gcc/... from the sandbox sysroot, and is only slightly better than a genrule. This
Serge Bazanskif055a7f2021-04-13 16:22:33 +020022should be replaced by a hermetic build that at least uses rules_cc toolchain
23information, or even better, just uses cc_library targets.
24"""
25
26load("//build/utils:detect_root.bzl", "detect_root")
Tim Windelschmidt08054ca2025-04-04 01:11:56 +020027load("//osbase/build:def.bzl", "ignore_unused_configuration")
Serge Bazanskif055a7f2021-04-13 16:22:33 +020028
Serge Bazanskif9c82492024-09-16 16:50:39 +020029def _linux_image_impl_resources(_os, _ninputs):
30 """
31 Configures linux build resources.
32
33 See `resource_set` documentation in builtins.actions Bazel docs.
34 """
Tim Windelschmidt156248b2025-01-10 00:27:45 +010035
Serge Bazanskif9c82492024-09-16 16:50:39 +020036 # 16 threads seems about right - this fits well in both our build machines and
37 # development machines.
38 cpu = 16
Tim Windelschmidt156248b2025-01-10 00:27:45 +010039
Serge Bazanskif9c82492024-09-16 16:50:39 +020040 # In MB. Picked based on observing build in htop.
41 mb_per_cpu = 256
42 return {
Tim Windelschmidt156248b2025-01-10 00:27:45 +010043 "cpu": cpu,
44 "memory": cpu * mb_per_cpu,
45 "local_test": 0,
Serge Bazanskif9c82492024-09-16 16:50:39 +020046 }
Serge Bazanskif055a7f2021-04-13 16:22:33 +020047
48def _linux_image_impl(ctx):
49 kernel_config = ctx.file.kernel_config
50 kernel_src = ctx.files.kernel_src
51 image_format = ctx.attr.image_format
52
53 # Tuple containing information about how to build and access the resulting
54 # image.
55 # The first element (target) is the make target to build, the second
Mateusz Zalega9a66b182021-12-22 20:33:12 +010056 # (image_source) is the resulting file to be copied and the last
57 # (image_name) is the name of the image that will be generated by this
Serge Bazanskif055a7f2021-04-13 16:22:33 +020058 # rule.
Mateusz Zalega9a66b182021-12-22 20:33:12 +010059 (target, image_source, image_name) = {
Tim Windelschmidt156248b2025-01-10 00:27:45 +010060 "vmlinux": ("vmlinux modules", "vmlinux", "vmlinux"),
61 "bzImage": ("all modules", "arch/x86/boot/bzImage", "bzImage"),
Serge Bazanskif055a7f2021-04-13 16:22:33 +020062 }[image_format]
63
64 # Root of the given Linux sources.
65 root = detect_root(ctx.attr.kernel_src)
66
Mateusz Zalega9a66b182021-12-22 20:33:12 +010067 image = ctx.actions.declare_file(image_name)
68 modinfo = ctx.actions.declare_file("modules.builtin.modinfo")
Lorenz Brun6c454342023-06-01 12:23:38 +020069 modules = ctx.actions.declare_directory("modules")
Serge Bazanskif055a7f2021-04-13 16:22:33 +020070 ctx.actions.run_shell(
Tim Windelschmidt156248b2025-01-10 00:27:45 +010071 outputs = [image, modinfo, modules],
72 inputs = [kernel_config] + kernel_src,
Serge Bazanskif9c82492024-09-16 16:50:39 +020073 resource_set = _linux_image_impl_resources,
Serge Bazanskif055a7f2021-04-13 16:22:33 +020074 command = '''
75 kconfig=$1
76 target=$2
Mateusz Zalega9a66b182021-12-22 20:33:12 +010077 image_source=$3
78 image=$4
Serge Bazanskif055a7f2021-04-13 16:22:33 +020079 root=$5
Mateusz Zalega9a66b182021-12-22 20:33:12 +010080 modinfo=$6
Lorenz Brun6c454342023-06-01 12:23:38 +020081 modules=$7
82
83 builddir=$(mktemp -d)
Serge Bazanskif055a7f2021-04-13 16:22:33 +020084
85 mkdir ${root}/.bin
Lorenz Brun6c454342023-06-01 12:23:38 +020086 cp ${kconfig} ${builddir}/.config
Serge Bazanskif9c82492024-09-16 16:50:39 +020087 (cd ${root} && KBUILD_OUTPUT="${builddir}" make -j 16 ${target} >/dev/null)
Lorenz Brun6c454342023-06-01 12:23:38 +020088 cp "${builddir}"/${image_source} ${image}
89 cp "${builddir}"/modules.builtin.modinfo ${modinfo}
90 # Not using modules_install as it tries to run depmod and friends
91 for f in $(find "${builddir}" -name '*.ko' -type f -printf "%P\n" ); do
92 install -D "${builddir}/$f" "${modules}/$f"
93 done
94 rm -Rf "$builddir"
Serge Bazanskif055a7f2021-04-13 16:22:33 +020095 ''',
96 arguments = [
97 kernel_config.path,
98 target,
Mateusz Zalega9a66b182021-12-22 20:33:12 +010099 image_source,
100 image.path,
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200101 root,
Lorenz Brun6c454342023-06-01 12:23:38 +0200102 modinfo.path,
103 modules.path,
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200104 ],
105 use_default_shell_env = True,
106 )
107
Mateusz Zalega9a66b182021-12-22 20:33:12 +0100108 return [
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100109 DefaultInfo(
110 files = depset([image]),
111 runfiles = ctx.runfiles(files = [image]),
112 ),
113 OutputGroupInfo(
114 modinfo = depset([modinfo]),
115 modules = depset([modules]),
116 ),
Mateusz Zalega9a66b182021-12-22 20:33:12 +0100117 ]
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200118
119linux_image = rule(
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100120 doc = """
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200121 Build Linux kernel image unhermetically in a given format.
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100122 """,
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200123 implementation = _linux_image_impl,
124 cfg = ignore_unused_configuration,
125 attrs = {
126 "kernel_config": attr.label(
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100127 doc = """
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200128 Linux kernel configuration file to build this kernel image with.
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100129 """,
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200130 allow_single_file = True,
131 default = ":linux-metropolis.config",
132 ),
133 "kernel_src": attr.label(
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100134 doc = """
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200135 Filegroup containing Linux kernel sources.
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100136 """,
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200137 default = "@linux//:all",
138 ),
139 "image_format": attr.string(
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100140 doc = """
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200141 Format of generated Linux image, one of 'vmlinux' or 'bzImage',
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100142 """,
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200143 values = [
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100144 "vmlinux",
145 "bzImage",
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200146 ],
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100147 default = "bzImage",
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200148 ),
149 "_allowlist_function_transition": attr.label(
Tim Windelschmidt156248b2025-01-10 00:27:45 +0100150 default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200151 ),
152 },
153)