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