#!/bin/bash CWD=$(pwd) KERNEL_SRC=linux GIT_ROOT=$(git rev-parse --show-toplevel) set -e if [ ! -d ${KERNEL_SRC} ]; then echo "Linux Kernel source directory does not exists, please 'git clone'" exit 1 fi cd ${KERNEL_SRC} if [ -d .git ]; then echo "I: Clean modified files - reset Git repo" git reset --hard HEAD git clean --force -d -x fi if [ -d /usr/lib/ccache/ ]; then export PATH=/usr/lib/ccache:$PATH fi KERNEL_VERSION=$(make kernelversion) KERNEL_SUFFIX=-$(awk -F "= " '/kernel_flavor/ {print $2}' ../../../../data/defaults.toml | tr -d \") echo "I: Generate Kernel config" ARCH=$(dpkg --print-architecture) # array to hold config fragments for merging # allows safe handling of paths with spaces and avoids word-splitting issues # The first entry is the base defconfig; subsequent entries are merged on top. KCONFIG_MERGE_FRAGMENTS=() if [ "${ARCH}" = "arm64" ]; then KCONFIG_MERGE_FRAGMENTS+=("${CWD}/config/arm64/vyos_defconfig") elif [ "${ARCH}" = "amd64" ]; then KCONFIG_MERGE_FRAGMENTS+=("${CWD}/config/x86/vyos_defconfig") else echo "E: unsupported architecture" exit 1 fi # NOTE: do NOT export KCONFIG_CONFIG here. KCONFIG_CONFIG is interpreted by # kbuild as the path to the OUTPUT .config file. Exporting it globally would # cause `make vyos_defconfig` (and the rest of the kernel build) to write the # resulting config to that path instead of producing a normal `.config` in the # kernel source root, which breaks downstream steps that expect `linux/.config` # to exist. # VyOS requires some small Kernel Patches - apply them here # It's easier to have them here and make use of the upstream # repository instead of maintaining a full Kernel Fork. # Saving time/resources is essential :-) # Note that the patches should be applied BEFORE the kernel config is generated # because patches may add new options! PATCH_DIR=${CWD}/patches/kernel for patch in $(ls ${PATCH_DIR}) do echo "I: Apply Kernel patch: ${PATCH_DIR}/${patch}" patch -p1 < ${PATCH_DIR}/${patch} done # Change name of Signing Cert sed -i -e "s/CN =.*/CN=VyOS Networks build time autogenerated Kernel key/" certs/default_x509.genkey TRUSTED_KEYS_FILE=trusted_keys.pem # start with empty key file echo -n "" > $TRUSTED_KEYS_FILE CERTS=$(find ${GIT_ROOT}/data/certificates -name "*.pem" -type f || true) TRUSTED_KEYS_FRAGMENT_TMP="" if [ ! -z "${CERTS}" ]; then # add known public keys to Kernel certificate chain for file in $CERTS; do cat $file >> $TRUSTED_KEYS_FILE done # Force Kernel module signing and embed public keys TRUSTED_KEYS_FRAGMENT_TMP=$(mktemp --suffix=.config) echo "CONFIG_SYSTEM_TRUSTED_KEYRING=y" > $TRUSTED_KEYS_FRAGMENT_TMP echo "CONFIG_SYSTEM_TRUSTED_KEYS=\"$TRUSTED_KEYS_FILE\"" >> $TRUSTED_KEYS_FRAGMENT_TMP fi echo "I: Merge Kernel config snippets" # Collect config fragments into the fragment array for fragment in "${CWD}"/config/*.config; do [ -f "${fragment}" ] || continue echo "I: adding configuration snippet ${fragment}" KCONFIG_MERGE_FRAGMENTS+=("${fragment}") done if [ -n "${TRUSTED_KEYS_FRAGMENT_TMP}" ]; then echo "I: adding configuration snippet ${TRUSTED_KEYS_FRAGMENT_TMP}" KCONFIG_MERGE_FRAGMENTS+=("${TRUSTED_KEYS_FRAGMENT_TMP}") fi # Use the kernel's own merge_config.sh to properly merge all config fragments. # This writes .config into the current (kernel source) dir. # The first fragment in the array is the base defconfig; the remaining ones # are merged on top of it. merge_config.sh will run `make alldefconfig` at # the end to expand defaults, this replaces the previous separate # `make vyos_defconfig` step. # This will contain some warnings about " not in final .config" # which can mostly be ignored, but may provide relevant insight so we # don't suppress it. echo "I: Run scripts/kconfig/merge_config.sh to produce .config" if [ ${#KCONFIG_MERGE_FRAGMENTS[@]} -eq 0 ]; then echo "E: No config fragments found for merging, cannot proceed" exit 1 fi scripts/kconfig/merge_config.sh "${KCONFIG_MERGE_FRAGMENTS[@]}" if [ ! -f .config ]; then echo "E: merge_config.sh did not produce a .config in $(pwd)" exit 1 fi echo "I: Generate environment file containing Kernel variable" EPHEMERAL_KEY="/tmp/ephemeral.key" EPHEMERAL_PEM="/tmp/ephemeral.pem" cat << EOF >${CWD}/kernel-vars #!/bin/sh export KERNEL_VERSION=${KERNEL_VERSION} export KERNEL_SUFFIX=${KERNEL_SUFFIX} export KERNEL_DIR=${CWD}/${KERNEL_SRC} export EPHEMERAL_KEY=${EPHEMERAL_KEY} export EPHEMERAL_CERT=${EPHEMERAL_PEM} EOF echo "I: Build Debian Kernel package" touch .scmversion make bindeb-pkg BUILD_TOOLS=1 LOCALVERSION=${KERNEL_SUFFIX} KDEB_PKGVERSION=${KERNEL_VERSION}-1 -j $(getconf _NPROCESSORS_ONLN) # Back to the old Kernel build-scripts directory cd $CWD EPHEMERAL_KERNEL_KEY=$(grep -E "^CONFIG_MODULE_SIG_KEY=" "${KERNEL_SRC}/.config" | awk -F= '{print $2}' | tr -d \") if test -f "${EPHEMERAL_KEY}"; then rm -f ${EPHEMERAL_KEY} fi if test -f "${EPHEMERAL_PEM}"; then rm -f ${EPHEMERAL_PEM} fi if test -f "${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY}"; then openssl rsa -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_KEY} openssl x509 -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_PEM} fi