blob: b6d156dc9058f2bb775a9dc56e911d09e0480342 [file] [log] [blame] [view]
# COS Kernel Devenv container
## Overview
## Building COS Kernel Devenv Image
### Locally (for testing the image)
For testing, you can simply build and test this docker container locally on your
workstation:
```shell
$ docker build -t gcr.io/cloud-kernel-build/cos-kernel-devenv:dev .
```
### Production (push into GCR)
```shell
$ VERSION=<version> # e.g., v20211031
$ docker build -t gcr.io/cloud-kernel-build/cos-kernel-devenv:$VERSION .
$ docker build -t gcr.io/cloud-kernel-build/cos-kernel-devenv:latest .
$ gcloud docker -- push gcr.io/cloud-kernel-build/cos-kernel-devenv:$VERSION
$ gcloud docker -- push gcr.io/cloud-kernel-build/cos-kernel-devenv:latest
```
## Using COS Kernel Devenv Image
### Download
Get the latest version of the `cos-kernel-devenv` container by running the
following command:
```shell
$ docker pull gcr.io/cloud-kernel-build/cos-kernel-devenv
```
### Overview
`cos-kernel-devenv` provides the development environment for building Linux
kernel or standalone kernel modules. The container supports four operational
modes:
- wrapper for make command with kernel-specific arguments and env variables
- automatic kernel build
- automatic module out-of-tree module build
- interactive shell
The development environment includes a cross-compilation toolchain and
optional kernel headers. Kernel headers only provided if the environment
replicates the environment of an official COS release (specified
using `-R` command-line switch) or of an CI build (specified by
using `-b` and `-B` command-line switches).
### Preparations
Kernel sources or module sources are passed to the container as a volume
(directory mapped from the host machine into a container). Non-interactive
operational modes assume that the working directory is the top-level build
directory.
`cos-kernel-devenv` image does not contain any actual toolchain and populates
binaries and kernel headers from network sources to `/build` location in the
container. In order to save time on every invocation users can map a host
directory to `/build` volume to make installed files persistent between runs.
Some of the network sources require access to GCS buckets so to pass gcloud
config and credentials from the host into a container `~/.config/gcloud`
host directory needs to be mapped into `/root/.config/gcloud` volume.
To hide all this complexity you can use the code snippet below that wraps it all
up in a convenient shell function.
```shell
# cache directory for toolchains
mkdir -p ~/cos-build
function cos_kmake() {
docker run --rm -ti \
-v ~/.config/gcloud:/root/.config/gcloud \
-v ~/cos-build:/build -v $(pwd):/src -w /src \
gcr.io/cloud-kernel-build/cos-kernel-devenv \
"$@"
}
export -f cos_kmake
```
At this point you should be able to run `cos_kmake -h` and get a list of
available command-line options:
```
Usage: /devenv.sh [-k | -m | -i] [-Hcd] [-A <x86_64|arm64>]
[-C <kernelconfig>[,fragment1.config,...]] [-O <objdir>]
[-B <build> -b <board> | -R <release> | -G <bucket>]
[-t <toolchain_version>] [VAR=value ...] [target ...]
Options:
-A <arch> target architecture. Valid values are x86_64 and arm64.
-B <build> seed the toolchain from the COS build <build>.
Example: R93-16623.0.0. Instead of the actual
build number developer can specify the branch name
to use the latest build off that branch.
Example: main-R93, release-R89. Requires -b option.
-C <configs> kernel configs target. Example: lakitu_defconfig.
It's also possible to specify main config and fragments
separated by coma, i.e.: lakitu_defconfig,google/xfstest.config
-G <bucket> seed the toolchain and kernel headers from the custom
GCS bucket <bucket>. Directory structure needs to conform
to the COS standard.
-H create a package with kernel headers for the respective
kernel package. Should be used only with -k option.
-O <objdir> value for KBUILD_OUTPUT to separate obj files from
sources
-R <release> seed the toolchain and kernel headers from the
specified official COS release. Example: 16442.0.0
-b <board> specify board for -B argument. Example: lakitu
-c perform "mrproper" step when building a kernel package or
"clean" step when building a module.
Should be used only with -k and -m option.
-d create a pakcage with debug symbols for the respective
kernel package. Should be used only with -k option.
-h show this message.
-i invoke interactive shell with kernel development
environment initialized.
-k build a kernel package for sources mapped from the host
to the current working directory.
-m build an out-of-tree module for sources mapped from
the host to the current working directory.
This mode requires either -R or -B/b options.
-t seed the toolchain from the Chromium OS upstream.
Example: 2021.06.26.094653
```
### Building the COS Kernel
#### Getting the Source Code
`cos_kmake` should be used at the top-level of the checked out kernel source tree:
```
$ git clone -b cos-5.10 https://cos.googlesource.com/third_party/kernel cos-kernel
$ cd cos-kernel
```
#### Pass-through make
Unless one of `-i`, `-k` or `-m` command-line switches is specified the container
acts as a wrapper for a `make` command so the build procedure for the
kernel looks the same as a normal build:
```
cos_kmake mrproper
cos_kmake lakitu_defconfig
cos_kmake bzImage modules
```
`cos-kernel-devenv` supports two target arcitectgures: `x86_64` and `arm64` that
can be set for an invocation by passing `-A <arch>` argument to the command.
Unless specified the `x86_64` target is the default one.
To build ARM64 kernel and modules you can use the following sequence of commands:
```
cos_kmake -A arm64 mrproper
cos_kmake -A arm64 lakitu_defconfig
cos_kmake -A arm64 Image modules
```
All examples below build binaries for `x86_64` architecture but can be converted to
`arm64` by adding `-A arm64` command-line switch.
#### Building Kernel Packages
In addition to acting as a `make` wrapper, `cos-kernel-devenv` can also create
kernel packages: archives with the kernel, modules, and debug symbols. These
packages can be used to inject kernel into a custom image or in a VM in
development mode.
To build kernel package run `cos_kmake -k`. This command produces
`cos-kernel-<version>-<arch>.txz` file that contains `/boot` and `/lib/modules`
directories that can be used as a drop-in replacement for the COS image/VM.
By default kernel configuration step uses `defconfig` as a target. You can
override this by passing `-C <kernelconfig>` argument, i.e.:
`-C lakitu_defconfig`, `-C olddefconfig`.
To ensure clean build you can also add `make mrproper` step to the beginning
of the build sequence by passing `-c` command line switch.
Debug symbols package can be produced by using `-d` command-line switch.
When this switch passed to the container `cos-kernel-devenv` also generates
`cos-kernel-debug-<version>-<arch>.txz` archive with debug symbols
for the kernel and modules. This package can be used for kernel instrumention
if required.
#### Building Out of Tree Modules
The main purpose of this mode is to build out-of-tree kernel module
for the specific COS version. The version can be either an official
COS release or a CI build. To use an official COS release pass it
as an argument to `-R` command line switch, i.e.:
```
cos_kmake -m -R 16442.0.0
```
CI builds is identified by a combination of board and build number
passed as arguments for `-b` and `-B` switches respectively:
```
cos_kmake -m -b lakitu -B R93-16623.0.0
```
`cos_kmake -m ...` is an equivalent of running two commands in the working
directory:
```
make -C /path/to/kheaders M=$(pwd) clean
make -C /path/to/kheaders M=$(pwd) modules
```
#### Interactive Mode
For more complex use cases expert developers can use an interactive shell,
activated by `-i` command-line switch. The shell has kernel and development
environment variable pre-configured. It also defines a `make` wrapper `kmake`
that can be used as a shorthand to run make for kernel-related tasks:
```
% cos_kmake -i -A arm64
** Kernel architecture: arm64
** Toolchain architecture: aarch64
Mode: cross
[INFO 2021-10-29 18:41:02 UTC] Configuring environment variables for
cross-compilation
Starting interactive shell for the kernel devenv
root@0244bcbd8239:/src# $CC -v
Chromium OS 12.0_pre422132_p20210405-r9 clang version 13.0.0
(/var/tmp/portage/sys-devel/llvm-12.0_pre422132_p20210405-r9/work/llvm-12.0_pre422132_p20210405/clang
cd442157cff4aad209ae532cbf031abbe10bc1df)
Target: aarch64-cros-linux-gnu
Thread model: posix
InstalledDir: /build/cros-2021.06.26.094653-aarch64/usr/bin
Found candidate GCC installation:
/build/cros-2021.06.26.094653-aarch64/usr/bin/../lib/gcc/aarch64-cros-linux-gnu/10.2.0
Selected GCC installation:
/build/cros-2021.06.26.094653-aarch64/usr/bin/../lib/gcc/aarch64-cros-linux-gnu/10.2.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
root@0244bcbd8239:/src# kmake kernelrelease
5.10.75-ovt
root@0244bcbd8239:/src#
```
When interactive shell invoked with `-R` or `-b/-B` switches the location of
kernel headers for the specified COS version is accessible as `KHEADERS` env
variable.