blob: 3a2735187770cac7badc9ec8c76374209920730b [file] [view]
# The Zircon build
## Kernel switchsets, or how the kernel is compiled and linked
- **What**: A suite of kernel-specific GN toolchains parameterized by CPU
architecture, representing compiler and linker flags (e.g., optimization
levels, debug levels, asserts, defines).
- **Where in source**: Switchsets are defined at
`//zircon/kernel/switch/set/$name:kernel_$cpu.$name` using the
[kernel_switchset()](/zircon/kernel/kernel_switchset.gni) template.
- **Where in the build directory**: The compilation artifacts for a given
switchset will be placed under `<build_dir>/kernel_$cpu.$name/`
- **Constraint**: A switchset must be _defined_ within the default toolchain.
**Current switchsets**:
- [lk_debug_level_0](/zircon/kernel/switch/set/lk_debug_level_0/BUILD.gn):
Production-like configuration with minimal debug-like features, setting
`LK_DEBUGLEVEL=0`;
- [lk_debug_level_2](/zircon/kernel/switch/set/lk_debug_level_2/BUILD.gn):
Development-like configuration with full debug-like features, setting
`LK_DEBUGLEVEL=2`.
## Kernel executables
- **What**: ELF-producing targets representing the kernel binary itself. Defines
what is included in the kernel link (e.g., tests and debug commands).
- **Where in source**: Defined in `//zircon/kernel/bin/BUILD.gn` using the
[kernel_executable()](/zircon/kernel/bin/BUILD.gn) template.
- **Where in the build directory**: The unstripped ELF binary compiled under a
given switchset is placed at `<build_dir>/kernel_$cpu.$switchset/$executable`.
- **Constraint**: Must only be evaluated within a kernel switchset toolchain.
**Current kernel executables**:
- `vmzircon`: Standard kernel intended for production (no tests or extra debug
commands). This is what is packaged in user-like products.
- `vmzircon.with-tests`: Standard kernel intended for development (compiled with
unit tests and additional debug commands). This is what is packaged in eng
products.
## Kernel Images (A.K.A. kernel ZBIs)
- **What**: Minimal bootable ZBIs containing a kernel (by definition) and
everything needing to boot it. They package a kernel executable (evaluated
under a specific switchset), along with things like boot options, code
patching inputs, userboot, and a vDSO.
- **Where in source**: Defined at `//zircon/kernel/image/$name:$name` using the
[kernel_image()](/zircon/kernel/kernel_image.gni) template
- **Where in the build directory**: The ZBI is placed at
`<build_dir>/kernel.$name.zbi`.
**Current kernel images**:
- [eng](/zircon/kernel/image/eng/BUILD.gn): Assembled into eng products. Uses
`vmzircon.with-tests` under the `lk_debug_level_2` switchset, with
debug/serial syscalls enabled.
- [user](/zircon/kernel/image/user/BUILD.gn): Assembled into user products. Uses
`vmzircon` under the `lk_debug_level_0` switchset, with serial/debug syscalls
disabled.
- [userdebug](/zircon/kernel/image/userdebug/BUILD.gn): Assembled into userdebug
products. Uses `vmzircon` under the `lk_debug_level_0` switchset, but with
serial output enabled.
- [eng.lk_debug_level_0](/zircon/kernel/image/eng.lk_debug_level_0/BUILD.gn):
Eng-like test image to verify that debug assertions are not load-bearing. Uses
`vmzircon.with-tests` under `lk_debug_level_0`.
## Source organization
While it might well be more convenient to have consolidated more of these
definitions in fewer build files, the current organization is intended to
minimize the amount of unnecessary GN evaluation that happens at `gen` time.
(Recall that if GN sees a redirect to another toolchain in a build file, it will
follow it, and so on.)
- **Switchsets** are isolated in subdirectories so they are only evaluated when
explicitly referenced.
- **Executables** are centralized in `//zircon/kernel/bin/BUILD.gn` for
readability and to ensure they are only evaluated under kernel switchsets.
- **Images** are separated to allow different images to depend on different
switchsets without accidentally referencing unused switchsets.
## FAQ
### Which kernel does Product Assembly end up using?
Product Assembly knows about three particular kernel images: `eng`, `user`, and
`userdebug`, and only by label. Its contract with the kernel build is simply
that it will pick out the appropriate kernel image based based on a product's
build type.
### Which kernel do core tests end up running against?
By default, 'kernel ZBI tests' (e.g., core tests) run against the `eng` kernel
image, which in turn packages the `vmzircon.with-tests` executable under the
`lk_debug_level_2` switchset. To run these tests against additional kernel
images (e.g., `eng.lk_debug_level_0`), set the `extra_kernel_test_images` GN arg
in your `args.gn`:
```gn
extra_kernel_test_images = [ "eng.lk_debug_level_0" ]
```
Generally, this will cause
[kernel_zbi_test()](/build/testing/boot_tests/kernel_zbi_test.gni) targets to
also generate test variants for the specified images (e.g.,
`path/to/test:test.user` alongside `path/to/test:test.eng`), which can then be
run via `fx run-boot-test`. The above example is what all bringup builders set.
For core tests in particular, one may run
`fx core-tests --kernel=$kernel_image_name` to locally run core tests against a
given kernel image under QEMU. Here `$kernel_image_name` must be one of `eng`
(the default) or an entry in your local `extra_kernel_test_images`.
### How to enable boot options in core tests only?
`//zircon/kernel/image/$name:$name.test-data-deps` are data dependencies that
every instance of
[kernel_zbi_test()](/build/testing/boot_tests/kernel_zbi_test.gni) (e.g., core
tests) includes. This target may be updated to depend on desired
[`kernel_cmdline()`](/build/zbi/kernel_cmdline.gni) instances to enable
test-only boot options.
### How to disassemble the kernel?
It is most practical to run `fx dis vmzircon` or `fx dis vmzircon.with-tests` to
disassemble `vmzircon` or `vmzircon.with-tests` across all switchsets in your
build. One can also run `fx dis 'vmzircon*'` include both executables.
### I just want to build the kernel
There is no longer a singular 'kernel' to build. For a more minimal build while
iterating on kernel build, it is recommended that one build kernel images
directly (e.g., `fx build '//zircon/kernel/image/eng'` or
`fx build -- kernel.eng.zbi`).