blob: 5028ad49d58accf351eb57843a808f6c1a5ffdf5 [file] [log] [blame]
#
# Copyright 2021 Google LLC
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Check for EAPI 5+
case "${EAPI:-0}" in
0|1|2|3|4) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
5|6) inherit eapi7-ver ;;
7) ;;
esac
inherit cros-workon cros-kernel2 osreleased
#
# To control the module signing behavior developers can define
# the following variables in an ebuild file:
#
# COS_KERNEL_X509_GENKEY (mandatory) contains path to an OpenSSL
# configuration file used to generate signing keys/certificates
#
# COS_KERNEL_ROOT_CERT (optional) contains path to the list of
# system-wide trusted keys in PEM format
#
CONFIG_FRAGMENTS=(
nvme_tcp
no_io_strict_devmem
)
# When "nofragments" flag is set, do not overlay kernel config
# with fragments and use the config file as-is
IUSE="gpu nofragments ${CONFIG_FRAGMENTS[@]} hardened"
# Describe custom fragments by defining a human-readable
# description and configuration fragment
# foo_desc="Enable FOOBAR support"
# foo_config="
# CONFIG_FOOBAR=y
# "
nvme_tcp_desc="Enable NVME over Fabrics using TCP"
nvme_tcp_config="
CONFIG_NVME_COMMON=y
CONFIG_NVME_FABRICS=m
CONFIG_NVME_TCP=m
CONFIG_NVME_AUTH=y
CONFIG_NVME_TARGET=m
CONFIG_NVME_TARGET_PASSTHRU=y
# CONFIG_NVME_TARGET_LOOP is not set
# CONFIG_NVME_TARGET_FC is not set
CONFIG_NVME_TARGET_TCP=m
CONFIG_NVME_TARGET_AUTH=y
"
no_io_strict_devmem_desc="Disable CONFIG_IO_STRICT_DEVMEM for GPU driver development"
no_io_strict_devmem_config="
# CONFIG_IO_STRICT_DEVMEM is not set
"
cos-kernel_src_prepare() {
cros_allow_gnu_build_tools
cros-kernel2_src_prepare
}
cos-kernel_src_configure() {
# Provide a custom key configuration file, because otherwise the kernel
# would auto-generate one.
mkdir -p "$(cros-workon_get_build_dir)/certs"
if ! [ -f "${COS_KERNEL_X509_GENKEY}" ]; then
die "x509 config not found: '${COS_KERNEL_X509_GENKEY}'"
fi
cp -f "${COS_KERNEL_X509_GENKEY}" \
"$(cros-workon_get_build_dir)/certs/x509.genkey" || die
# The root key belongs to lakitu board.
if [ -n "${COS_KERNEL_ROOT_CERT}" ]; then
if ! [ -f "${COS_KERNEL_ROOT_CERT}" ]; then
die "COS kernel root cert not found: '${COS_KERNEL_ROOT_CERT}'"
fi
cp -f "${COS_KERNEL_ROOT_CERT}" \
"$(cros-workon_get_build_dir)/certs/trusted_key.pem" || die
fi
if use nofragments; then
export CONFIG_FRAGMENTS=()
fi
# * -fstack-clash-protection inserts code to probe each page of the stack space
# as it is allocated to protect from stack-clash style attacks.
# * -D_FORTIFY_SOURCE=2 enables additional security features of the GNU libc when
# calling memory and string handling functions.
if use hardened; then
if [ "${ARCH}" == "amd64" ]; then
export KCFLAGS="-fstack-clash-protection -D_FORTIFY_SOURCE=3 -ftrivial-auto-var-init=zero -fstack-protector-strong"
else
export KCFLAGS="-fstack-clash-protection -D_FORTIFY_SOURCE=3 -ftrivial-auto-var-init=zero -fPIE -fsanitize=shadow-call-stack -fstack-protector-strong"
fi
fi
cros-kernel2_src_configure
}
tar_kernel_source() {
# Put kernel source tarball under /opt to avoid it gets
# masked by INSTALL_MASK.
local source_dir=opt/google/src
dodir "${source_dir}"
pushd "${D}/usr/src/${P}" || die
tar --exclude="./build" -czf "${D}/${source_dir}/kernel-src.tar.gz" .
popd || die
}
tar_kernel_headers() {
einfo "Packaging kernel headers"
# We do pretty much exactly what scripts/package/builddeb does.
pushd "${D}/usr/src/${P}" || die
(
find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl
find arch/*/include include scripts -type f -o -type l
find "arch/$(tc-arch-kernel)" -name module.lds -o -name Kbuild.platforms -o -name Platform
find "arch/$(tc-arch-kernel)" -name include -o -name scripts -type d | while IFS='' read -r line; do
find "${line}" -type f
done
) > "${T}/hdrsrcfiles"
popd || die
pushd "$(cros-workon_get_build_dir)" || die
{
if cros_chkconfig_present OBJTOOL || cros_chkconfig_present STACK_VALIDATION; then
find tools/objtool -type f -executable
fi
find "arch/$(tc-arch-kernel)/include" Module.symvers include scripts -type f
if cros_chkconfig_present GCC_PLUGINS; then
find scripts/gcc-plugins -name \*.so -o -name gcc-common.h
fi
} > "${T}/hdrobjfiles"
popd || die
local destdir="${T}/headers_tmp/usr/src/linux-headers-$(kernelrelease)"
mkdir -p "${destdir}"
tar -c -f - -C "${D}/usr/src/${P}" -T "${T}/hdrsrcfiles" | tar -xf - -C "${destdir}"
tar -c -f - -C "$(cros-workon_get_build_dir)" -T "${T}/hdrobjfiles" | tar -xf - -C "${destdir}"
rm "${T}/hdrsrcfiles" "${T}/hdrobjfiles"
cp "$(cros-workon_get_build_dir)/.config" "${destdir}/.config"
# We don't configure INSTALL_MASK to remove files in /opt, so export the
# headers tarball through /opt.
local source_dir=opt/google/src
dodir "${source_dir}"
pushd "${T}/headers_tmp" || die
tar -czf "${D}/${source_dir}/kernel-headers.tgz" .
popd || die
rm -r "${T}/headers_tmp"
}
write_toolchain_env() {
# Write the compiler info used for kernel compilation
# in toolchain_env.
local toolchain_env_dir=etc
# Example for toolchain_env content:
# CC=x86_64-cros-linux-gnu-clang
# CXX=x86_64-cros-linux-gnu-clang++
# The file will be deleted after copying data to BUILD_DIR artifact
echo "CC=${CC}" > "${D}/${toolchain_env_dir}/toolchain_env"
echo "CXX=${CXX}" >> "${D}/${toolchain_env_dir}/toolchain_env"
}
write_kernel_info() {
# Write kernel information used for building kernel.
local kernel_info_dir=etc
# Example for kernel_info content:
# URL=https://chromium.googlesource.com/chromiumos/third_party/kernel
echo "URL=${CROS_WORKON_REPO}/${CROS_WORKON_PROJECT}" > "${D}/${kernel_info_dir}/kernel_info"
}
get_kernel_commit_id() {
# Provide kernel commit id
# VCSID variable is unconditionally set by the cros-workon eclass, and
# is in the form of "<ebuild_revision>-<sha1>".
echo "${VCSID##*-}"
}
write_kernel_commit() {
# Write kernel commit information used for building kernel.
local kernel_commit_dir=etc
# Example for kernel_commit content:
# c7ad6ff415b5a1e87f8333e2a63c7209e6efc1b2
get_kernel_commit_id > "${D}/${kernel_commit_dir}/kernel_commit"
}
cos-kernel_src_install() {
cros-kernel2_src_install
do_osrelease_field "KERNEL_COMMIT_ID" "$(get_kernel_commit_id)"
if use kernel_sources; then
# Install kernel source and headers tarballs so they can be exported as
# artifacts later.
tar_kernel_source
tar_kernel_headers
# Install kernel compiler information
write_toolchain_env
# Install kernel source information
write_kernel_info
# Install kernel commit information
write_kernel_commit
fi
# Install IMA certificates
insinto /etc/ima
newins "$(cros-workon_get_build_dir)"/certs/signing_key.x509 pubkey.x509
}