-
Notifications
You must be signed in to change notification settings - Fork 0
Add avocado guide for custom avocado kernels #394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,308 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| sidebar_position: 6 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: 'Custom kernel' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'Bring your own Linux kernel to Avocado - cross-compile from source or install a pre-built kernel package with the required configuration for system extensions, systemd, and boot.' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| Avocado runtimes ship with a default kernel provided by the `avocado-img-bootfiles` package (pulled in by the `avocado-runtime` meta-package). When your project requires a specific kernel version, vendor-supplied kernel sources, or custom driver support, the `kernel` configuration option lets you replace the default kernel with your own. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| This guide covers: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - How to configure `avocado.yaml` for a custom kernel | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Required kernel configuration options Avocado depends on | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Writing compile and install scripts | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Adapting the workflow for different hardware targets | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| :::tip vendor kernels | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| For hardware like NVIDIA Jetson, NXP i.MX, or Qualcomm platforms, start with the kernel source tree provided by the silicon vendor. These trees include board-specific device tree files, peripheral drivers, and GPU support that upstream kernels may lack. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ::: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Configuration modes | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| The `kernel` section in a runtime supports two mutually exclusive modes: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Compile from source | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| Cross-compile a kernel inside the SDK container: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```yaml | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| runtimes: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| dev: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| kernel: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| compile: kernel # References an sdk.compile section by name | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| install: kernel-install.sh # Copies the built image into the runtime | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - `compile` -- References an `sdk.compile` section that runs the build. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| - `install` -- A script executed after compilation. It receives `AVOCADO_RUNTIME_BUILD_DIR` (pointing to `$AVOCADO_PREFIX/runtimes/<runtime>/`) and is responsible for copying the kernel image there. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Install from package | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| Use a pre-built kernel RPM from your package feed: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```yaml | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| runtimes: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| dev: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| kernel: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| package: kernel-image | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| version: '6.12.69' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| `package` and `compile` are mutually exclusive. If the `kernel` section is omitted entirely, the default Avocado kernel is used. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## SDK compile section | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| When compiling from source, define the compile section that the runtime references: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```yaml | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| sdk: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| image: docker.io/avocadolinux/sdk:{{ avocado.distro.channel }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| compile: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| kernel: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| compile: kernel-compile.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| packages: # Target sysroot packages installed before the script runs | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| libelf1: '*' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| packages: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| avocado-sdk-toolchain: '{{ avocado.distro.version }}' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| nativesdk-bc: '*' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| nativesdk-libelf1: '*' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| The `packages` field inside `sdk.compile.kernel` declares target sysroot dependencies. The `sdk.packages` field declares host-side SDK packages installed into the SDK sysroot. Common ones for kernel builds include `bc` (for `timeconst.h` generation) and `libelf` (for `objtool`). Check your SDK package feed for the correct package names. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Writing the compile script | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| The compile script runs inside the SDK container where the OpenEmbedded cross-compilation environment is already sourced. Variables like `CROSS_COMPILE`, `ARCH`, and `OECORE_TARGET_SYSROOT` are set before your script executes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Handling SDK environment conflicts | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| The OE SDK sets `CC`, `CFLAGS`, `LDFLAGS`, and other variables with `--sysroot` flags and tuning options designed for userspace cross-compilation. The kernel build system manages its own flags and derives `CC` from `CROSS_COMPILE` internally, so these SDK variables **conflict** with it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| Save the variables you need, unset the rest, then restore: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Save what the kernel build needs | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _CROSS_COMPILE="${CROSS_COMPILE}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _ARCH="${ARCH}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _TARGET_SYSROOT="${OECORE_TARGET_SYSROOT}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Clear everything the SDK sets that conflicts with the kernel build system | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| unset CC CXX CPP LD AR AS NM STRIP OBJCOPY OBJDUMP READELF RANLIB | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| unset CFLAGS CXXFLAGS CPPFLAGS LDFLAGS | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| unset KCFLAGS | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Restore | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| export CROSS_COMPILE="${_CROSS_COMPILE}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| export ARCH="${_ARCH}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Setting up host tool compilation | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| The kernel builds host-side tools (`fixdep`, `objtool`, `genksyms`, etc.) that run on the build machine during compilation. Three issues arise in the SDK environment: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. **No bare `gcc`/`ld`/`ar`.** The SDK container only ships cross-prefixed tools (e.g., `x86_64-avocado-linux-gcc`). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| 2. **Make assignment semantics.** The kernel Makefile uses `HOSTCC = gcc` (unconditional assignment). In GNU make, environment variables do **not** override unconditional assignments -- you must pass them on the **command line**. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| 3. **No default sysroot.** The bare cross-compiler has no built-in sysroot, so standard headers like `sys/types.h` are not found. Point it at the target sysroot with `--sysroot`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| HOSTCC="${CROSS_COMPILE}gcc --sysroot=${_TARGET_SYSROOT}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| HOSTCXX="${CROSS_COMPILE}g++ --sysroot=${_TARGET_SYSROOT}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| HOSTLD="${CROSS_COMPILE}ld" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| HOSTAR="${CROSS_COMPILE}ar" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+105
to
+115
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. **No bare `gcc`/`ld`/`ar`.** The SDK container only ships cross-prefixed tools (e.g., `x86_64-avocado-linux-gcc`). | |
| 2. **Make assignment semantics.** The kernel Makefile uses `HOSTCC = gcc` (unconditional assignment). In GNU make, environment variables do **not** override unconditional assignments -- you must pass them on the **command line**. | |
| 3. **No default sysroot.** The bare cross-compiler has no built-in sysroot, so standard headers like `sys/types.h` are not found. Point it at the target sysroot with `--sysroot`. | |
| ```bash | |
| HOSTCC="${CROSS_COMPILE}gcc --sysroot=${_TARGET_SYSROOT}" | |
| HOSTCXX="${CROSS_COMPILE}g++ --sysroot=${_TARGET_SYSROOT}" | |
| HOSTLD="${CROSS_COMPILE}ld" | |
| HOSTAR="${CROSS_COMPILE}ar" | |
| 1. **No obvious host `gcc`/`ld`/`ar`.** The SDK container primarily exposes cross-prefixed tools for the target. You must instead use the *native SDK* toolchain from `$OECORE_NATIVE_SYSROOT` (or a `nativesdk-gcc` package) for host tools. | |
| 2. **Make assignment semantics.** The kernel Makefile uses `HOSTCC = gcc` (unconditional assignment). In GNU make, environment variables do **not** override unconditional assignments -- you must pass them on the **command line**. | |
| 3. **Host vs. target toolchains.** Host tools must run on the build machine and should be compiled with a host compiler. Do **not** point `HOSTCC`/`HOSTCXX` at the target cross-compiler (`${CROSS_COMPILE}gcc`) or the target sysroot (`${_TARGET_SYSROOT}`); reserve those only for `CC`/`CROSS_COMPILE`. | |
| ```bash | |
| # Use the native SDK (host) toolchain for HOST*. | |
| # Adjust binary names to match your SDK; these are examples only. | |
| HOST_NATIVE_BIN="${OECORE_NATIVE_SYSROOT}/usr/bin" | |
| HOSTCC="${HOST_NATIVE_BIN}/gcc" | |
| HOSTCXX="${HOST_NATIVE_BIN}/g++" | |
| HOSTLD="${HOST_NATIVE_BIN}/ld" | |
| HOSTAR="${HOST_NATIVE_BIN}/ar" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the example SDK package list,
nativesdk-libelf1is a runtime library and typically won't include headers needed for building kernel host tools likeobjtool. This guide later suggests addingnativesdk-libelf-devin troubleshooting—these should be consistent. Update the example to use the appropriate *-dev package name(s) for the SDK feed.