| # 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. |