summaryrefslogtreecommitdiff
path: root/kleaf/docs/impl.md
blob: af3f31c33c1fed3b292f6dbdf084fb1d1cf9cfba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# Build your kernels and drivers with Bazel

**Note**:
You may view the documentation for the following Bazel rules and macros on
Android Continuous Integration:

[https://ci.android.com/builds/latest/branches/aosp_kernel-common-android-mainline/targets/kleaf_docs/view/index.html](https://ci.android.com/builds/latest/branches/aosp_kernel-common-android-mainline/targets/kleaf_docs/view/index.html)

## Manifest changes

Make the following changes to the kernel manifest to support Bazel build.

* Add `.source_date_epoch_dir` symlink to your `${KERNEL_DIR}`
  * The date of the last commit in this directory
    determines `$SOURCE_DATE_EPOCH`.
    See [SOURCE\_DATE\_EPOCH](https://reproducible-builds.org/docs/source-date-epoch/).
  * **NOTE**: This is subject to change. In the future, this may not be required
      any more.
* Add `tools/bazel` symlink to `build/kernel/kleaf/bazel.sh`
* Add `WORKSPACE` symlink to `build/kernel/kleaf/bazel.WORKSPACE`
* Dependent repositories for Bazel, including:
    * [prebuilts/bazel/linux-x86\_64](https://android.googlesource.com/platform/prebuilts/bazel/linux-x86_64/)
    * [prebuilts/jdk/jdk11](https://android.googlesource.com/platform/prebuilts/jdk/jdk11/)
    * [build/bazel\_common\_rules](https://android.googlesource.com/platform/build/bazel_common_rules/)
    * [external/bazel-skylib](https://android.googlesource.com/platform/external/bazel-skylib/)
    * [external/stardoc](https://android.googlesource.com/platform/external/stardoc/)

Example for Pixel 2021:

[https://android.googlesource.com/kernel/manifest/+/refs/heads/gs-android-gs-raviole-mainline/default.xml](https://android.googlesource.com/kernel/manifest/+/refs/heads/gs-android-gs-raviole-mainline/default.xml)

Example for Android Common Kernel and Cloud Android kernel:

[https://android.googlesource.com/kernel/manifest/+/refs/heads/common-android-mainline/default.xml](https://android.googlesource.com/kernel/manifest/+/refs/heads/common-android-mainline/default.xml)

## Building a custom kernel

**WARNING**: It is recommended to use the common Android kernel
under `//common` (the so-called "mixed build") instead of building a custom
kernel.

You may define a `kernel_build` target to build a custom kernel. The name of
the `kernel_build` target is usually the name of your device, e.g. `tuna`.

The `outs` attribute of the target should align with the `FILES` variable in
build.config. This may include DTB files and kernel images, e.g. `vmlinux`.

The `module_outs` attribute of the target includes the list of in-tree drivers
that you are building. See section to [build in-tree drivers (Step 1)](#step-1)
below.

```
load("//build/kernel/kleaf:kernel.bzl","kernel_build")
load("//build/kernel/kleaf:common_kernels.bzl", "arm64_outs")
kernel_build(
   name = "tuna",
   srcs = glob(
       ["**"],
       exclude = [
           "**/BUILD.bazel",
           "**/*.bzl",
           ".git/**",
       ],
   ),
   outs = arm64_outs,
   build_config = "build.config.tuna",
)
```

## Building kernel modules and DTB files

### Step 1: (Optional) Define a target to build in-tree drivers and DTB files {#step-1}

If you have a separate kernel tree to build in-tree drivers, define
a `kernel_build` target to build these modules. The name of the `kernel_build`
target is usually the name of your device, e.g. `tuna`.

If you also have external kernel modules to be built, be sure to set visibility
accordingly, so that the targets to build external kernel modules can refer to
this `kernel_build` target.

If you are building a custom kernel, you may reuse the existing `kernel_build`
target, and keep kernel images in `outs`. If you are building against GKI, set
the `base_kernel` attribute accordingly (e.g. to `//common:kernel_aarch64`).

The `build_config` attribute of the target should point to the
main `build.config` file. To use `build.config` files generated on the fly, you
may use the `kernel_build_config` rule. See example for Pixel 2021 below.

The `outs` attribute of the target should align with the `FILES` variable in
build.config. This may include DTB files.

The `module_outs` attribute of the target includes the list of in-tree drivers
that you are building.

* Hint: You may leave the list empty and build the target. If the list is not
  up to date, modify the list according to the error message.

**Note**: It is recommended that kernel modules are moved out of the kernel tree
to be built as external kernel modules. This means keeping the list
of `module_outs` empty or as short as possible. See Step 2 for building external
kernel modules.

For other build configurations defined in the `build.config` file, see
[build_configs.md](build_configs.md).

Example for Pixel 2021 (see the `kernel_build` target named `slider`):

[https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel](https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel)

### Step 2: Define targets to build external kernel modules

Define `kernel_module` targets to build external kernel modules. You should
create a `kernel_module` target for each item in `EXT_MODULES` variable
in `build.config`.

The `kernel_build` attribute should be the target to the `kernel_build` you have
previously created in step 1, or  `//common:kernel_aarch64` if you did not do
step 1.

The `outs` attribute should be set to a list of `*.ko` files built by this
external module.

* Hint: You may leave the list empty and build the target. If the list is not
  up to date, modify the list according to the error message.

Be sure to set visibility accordingly, so that these targets are visible to
the `kernel_modules_install` target that will be created in step 3.

If the module depends on other modules, set `kernel_module_deps` accordingly.
See the `bms` and `power/reset` module below for an example.

If the module depends on headers in other locations, add headers to a filegroup,
then add the headers to `srcs`. See the `bms` and `power/reset` module below for
an example.

Minimal example for the `edgetpu` driver of Pixel 2021:

[https://android.googlesource.com/kernel/google-modules/edgetpu/+/refs/heads/android-gs-raviole-mainline/drivers/edgetpu/BUILD.bazel](https://android.googlesource.com/kernel/google-modules/edgetpu/+/refs/heads/android-gs-raviole-mainline/drivers/edgetpu/BUILD.bazel)

Example for the `bms` driver of Pixel 2021:

[https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel](https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel)

Example for the `power/reset` driver of Pixel 2021:

[https://android.googlesource.com/kernel/google-modules/power/reset/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel](https://android.googlesource.com/kernel/google-modules/power/reset/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel)

### Step 3: Define a target to run `depmod`

Define a `kernel_modules_install` target that includes all external kernel
modules created in Step 2. This is equivalent to running `make modules_install`,
which runs `depmod`.

The name of the target is usually the name of your device
with `_modules_install` appended to it, e.g. `tuna_modules_install`.

See Step 2 to determine the `kernel_build` attribute of the target.

Example for Pixel 2021 (see the `kernel_modules_install` target
named `slider_modules_install`):

[https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel](https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel)

### Step 4: (Optional) Define a target to build all boot images

The `kernel_images` macro produces partition images that are ready to be flashed
and tested immediately on your device. It can build the `initramfs`
image, `boot` image, `vendor_boot` image, `vendor_dlkm` image, `system_dlkm` image, etc.

The name of the target is usually the name of your device with `_images`
appended to it, e.g. `tuna_images`.

If you do not need to build any partition images, skip this step.

Example for Pixel 2021 (see the `kernel_images` target named `slider_images`):

[https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel](https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel)

### Step 5: Define a target for distribution {#step-5}

Define a `copy_to_dist_dir` target that includes the targets you want in the
distribution directory. The name of this `copy_to_dist_dir` target is usually
the name of your device with `_dist` appended to it, e.g. `tuna_dist`.

Set `flat = True` so the directory structure within `dist_dir` is flattened.

Set `dist_dir` so there's less typing at build time. For example:

```text
copy_to_dist_dir(
   dist_dir = "out/dist"
)
```

... or if you want to be strictly consistent with the behavior of `build.sh`:

```text
load("@kernel_toolchain_info//:dict.bzl", "BRANCH")
copy_to_dist_dir(
   # ...
   dist_dir = "out/{branch}/dist".format(branch = BRANCH)
)
```

Add the following to the `data` attribute of the `copy_to_dist_dir` target so
that the outputs are analogous to those produced by `build/build.sh`:

* The name of the `kernel_build` you have created in Step 1,
  e.g. `:tuna`. This adds all `outs`
  and `module_outs` to the distribution directory.
  * This usually includes DTB files and in-tree kernel modules.
* The name of the `kernel_modules_install` target you have created in Step 3.
  You may skip the `kernel_modules` targets created in Step 2, because
  the `kernel_modules_install` target includes all `kernel_modules` targets.
  This copies all external kernel modules to the distribution directory.
* The name of the `kernel_images` target you have created in Step 4. This copies
  all partition images to the distribution directory.
* GKI artifacts, including:
  * `//common:kernel_aarch64`
  * `//common:kernel_aarch64_additional_artifacts`
* UAPI headers, e.g. `//common:kernel_aarch64_uapi_headers`
* GKI modules
  * If you are using all GKI modules, add `//common:kernel_aarch64_modules`.
  * If you are using part of the GKI modules, add them individually, e.g.:
    * `//common:kernel_aarch64/zram.ko`
    * `//common:kernel_aarch64/zsmalloc.ko`
  * Modules from the device kernel build with the same name as GKI modules
    (e.g. on android13-5.15, you have `zram.ko` in `kernel_build.module_outs`)
    does not need to be specified, because `module_outs` are added to
    distribution.

Example for Pixel 2021 (see the `copy_to_dist_dir` target named `slider_dist`):

[https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel](https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/BUILD.bazel)

### Step 6: Build, flash and test

```shell
# Optional: prepare the device by flashing a base build.
# During development, you may want to wipe, disable verity and disable verification.
# fastboot update tuna-img.zip -w --disable-verity --disable-verification

# Assuming dist_dir=out/dist
$ tools/bazel run //private/path/to/sources:tuna_dist
# Flash static partitions
$ fastboot flash boot out/dist/boot.img
$ fastboot flash system_dlkm out/dist/system_dlkm.img
$ fastboot flash vendor_boot out/dist/vendor_boot.img
$ fastboot flash dtbo out/dist/dtbo.img
$ fastboot reboot fastboot
# Flash dynamic partitions
$ fastboot flash vendor_dlkm out/dist/vendor_dlkm.img
$ fastboot reboot
```

## Resolving common errors

See [errors.md](errors.md).

## Handling SCM version

See [scmversion.md](scmversion.md).

## Advanced usage

### Disable LTO during development

See [lto.md](lto.md).

### Using configurable build attributes `select()`

See official Bazel documentation for `select()`
here: https://docs.bazel.build/versions/main/configurable-attributes.html

In general, inputs to a target are configurable, while declared outputs are not.
One exception is that the `kernel_build` rule provides limited support
of `select()` in `outs` and `module_outs` attributes. See documentations
of `kernel_build` for details.

[https://ci.android.com/builds/latest/branches/aosp_kernel-common-android-mainline/targets/kleaf_docs/view/index.html](https://ci.android.com/builds/latest/branches/aosp_kernel-common-android-mainline/targets/kleaf_docs/view/index.html)

### `bazelrc` files

By default, the `.bazelrc` (symlink to `build/kernel/kleaf/common.bazelrc`)
tries to import the following two files if they exist:

* `device.bazelrc`: Device-specific bazelrc file (e.g. GKI prebuilt settings)
* `user.bazelrc`: User-specific bazelrc file (e.g. LTO settings)

To add device-specific configurations, you may create a `device.bazelrc`
file in the device kernel tree, then create a symlink at the repo root.

### Notes on hermeticity

Bazel builds are hermetic by default. Hermeticity is ensured by manually
declaring each target to depend on `//build/kernel:hermetic-tools`.

At this time of writing (2022-03-08), the following binaries are still
expected from the environement, or host machine, to build the kernel with
Bazel, in addition to the list of the allowlist of host tools specified in
`//build/kernel:hermetic-tools`. This is because the following usage does
not depend on `//build/kernel:hermetic-tools`.
* `cp` used by [`copy_file`](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/copy_file.bzl)
  in `copy_to_dist_dir` rules
* `echo`, `readlink`, `git` used by `build/kernel/kleaf/workspace_status.sh`