For testing, you can simply build and test this docker container locally on your workstation:
$ docker build -t gcr.io/cloud-kernel-build/cos-kernel-devenv:dev .
$ 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
Get the latest version of the cos-kernel-devenv
container by running the following command:
$ docker pull gcr.io/cloud-kernel-build/cos-kernel-devenv
cos-kernel-devenv
provides the development environment for building Linux kernel or standalone kernel modules. The container supports four operational modes:
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).
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.
# 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
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
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.
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.
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
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.