The standalone workflow lets you compile, test, and deploy kernel changes without
building the full Yocto image. All required cross-compilation and image-packaging
tools are bundled in the kmake-image Docker container.
Limitations and caveats
The standalone workflow builds and packages the kernel and modules only. It does
not produce a root file system. To build or modify out-of-tree kernel modules that
depend on the full Yocto BSP, use the Yocto-based workflow instead.
- Toolchain: the
kmake-image Docker image provides an aarch64 cross-toolchain,
systemd ukify, and image-packaging scripts. No host toolchain installation is needed.
- DTB packaging: when building standalone, you must package the DTB manually
using a static ITS configuration from the
qcom-dtb-metadata repository.
The Yocto build handles this automatically via
meta-qcom.
- Source revision: to match the exact source used in a release build, check the
SRCREV field in meta-qcom/recipes-kernel/linux/linux-qcom_6.18.bb.
Access kernel sources
Clone the kernel repository directly:
git clone --branch qcom-6.18.y \
https://github.com/qualcomm-linux/kernel.git kernel
Table: Kernel branches
| Branch | Use case |
|---|
qcom-6.18.y | LTS production builds; recommended for SoC bring-up and integration |
qcom-next | Upstream contribution and validation against the latest kernel |
Clone and build the kmake-image container:
git clone https://github.com/qualcomm-linux/kmake-image.git
cd kmake-image
docker build --build-arg USER_ID=$(id -u) \
--build-arg GROUP_ID=$(id -g) \
--build-arg USER_NAME=$(whoami) \
-t kmake-image .
cd ..
Set up shell aliases for convenience. Add these to your shell profile to persist
across sessions:
alias kmake-image-run='docker run -it --rm \
--user $(id -u):$(id -g) \
--workdir="$PWD" \
-v "$(dirname $PWD)":"$(dirname $PWD)" \
kmake-image'
alias kmake='kmake-image-run make'
Gather build artifacts
Create an artifacts/ directory to hold the ramdisk, boot binaries, and DTB
metadata required to assemble the final images:
Get the initramfs ramdisk
wget -O artifacts/ramdisk.gz \
http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230703.0/arm64/rootfs.cpio.gz
Get systemd-boot binaries
wget -O artifacts/systemd-boot-efi.deb \
http://ports.ubuntu.com/pool/universe/s/systemd/systemd-boot-efi_255.4-1ubuntu8_arm64.deb
dpkg-deb -xv artifacts/systemd-boot-efi.deb artifacts/systemd
Get DTB metadata
When building standalone, DTBs must be packaged manually using a static ITS
configuration. Clone the qcom-dtb-metadata repository to get the required
qcom-metadata.dts and qcom-next-fitimage.its files:
git clone https://github.com/qualcomm-linux/qcom-dtb-metadata.git \
artifacts/qcom-dtb-metadata
Build the kernel and modules
Configure and build the kernel using the standard Qualcomm® configuration
fragments, then install modules into a staging directory:
cd kernel
mkdir -p ../kobj
env -u KCONFIG_CONFIG ./scripts/kconfig/merge_config.sh -m -O ../kobj \
arch/arm64/configs/defconfig \
arch/arm64/configs/prune.config \
arch/arm64/configs/qcom.config
kmake O=../kobj olddefconfig
kmake O=../kobj -j$(nproc)
kmake O=../kobj -j$(nproc) dir-pkg INSTALL_MOD_STRIP=1
Package the built kernel modules (DLKMs) into the ramdisk:
(cd ../kobj/tar-install ; \
find lib/modules | cpio -o -H newc -R +0:+0 | gzip -9 >> ../../artifacts/ramdisk.gz)
Package the boot images
Generate efi.bin (ESP partition)
The efi.bin image contains systemd-boot, the kernel (packaged as a UKI
type-2 image), and the initramfs:
cd ..
# Default command line matches the Yocto UKI_CMDLINE from esp-qcom-image.bb.
# Override CMDLINE if your rootfs partition label or console differs.
CMDLINE="root=PARTLABEL=rootfs rw rootwait console=ttyMSM0,115200"
kmake-image-run generate_boot_bins.sh efi \
--ramdisk artifacts/ramdisk.gz \
--systemd-boot artifacts/systemd/usr/lib/systemd/boot/efi/systemd-bootaa64.efi \
--stub artifacts/systemd/usr/lib/systemd/boot/efi/linuxaa64.efi.stub \
--linux kobj/arch/arm64/boot/Image \
--cmdline "${CMDLINE}" \
--output images
Generate dtb.bin (DTB partition)
Build a FIT-based dtb.bin for all targets that support device tree:
kmake-image-run make_fitimage.sh \
--metadata artifacts/qcom-dtb-metadata/qcom-metadata.dts \
--its artifacts/qcom-dtb-metadata/qcom-next-fitimage.its \
--kobj kobj \
--output images
Both efi.bin and dtb.bin are placed in the images/ directory and are
ready to flash.
Kernel Image Build Script
Above build and package steps are wrapped under a build.sh script which is
part of docker, to automate building and packaging a bootable kernel image into
efi.bin, dtb.bin, and boot.img.
To use this alternative build.sh script run following:
kmake-image-run build.sh --dtb qcs6490-rb3gen2.dtb \
--out kobj \
--systemd artifacts/systemd/usr/lib/systemd/boot/efi \
--ramdisk artifacts/ramdisk.gz \
--images images \
--cmdline "${CMDLINE}"
- The —dtb argument is mandatory. It specifies the Device Tree Blob to be
packed into the kernel image. Above command shows using
qcs6490-rb3gen2.dtb
as an example.
- Initialize CMDLINE to set your kernel cmdline parameter else a default
generic is used.
Flash and boot
Put the device into fastboot mode, then flash both images:
fastboot flash efi images/efi.bin
fastboot flash dtb_a images/dtb.bin
fastboot reboot
After the device reboots, verify the running kernel version as described in
Install & boot the kernel.