summaryrefslogtreecommitdiff
path: root/eclass/dist-kernel-utils.eclass
diff options
context:
space:
mode:
Diffstat (limited to 'eclass/dist-kernel-utils.eclass')
-rw-r--r--eclass/dist-kernel-utils.eclass161
1 files changed, 161 insertions, 0 deletions
diff --git a/eclass/dist-kernel-utils.eclass b/eclass/dist-kernel-utils.eclass
new file mode 100644
index 000000000000..9ab65b097b32
--- /dev/null
+++ b/eclass/dist-kernel-utils.eclass
@@ -0,0 +1,161 @@
+# Copyright 2020-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: dist-kernel-utils.eclass
+# @MAINTAINER:
+# Distribution Kernel Project <dist-kernel@gentoo.org>
+# @AUTHOR:
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 7
+# @BLURB: Utility functions related to Distribution Kernels
+# @DESCRIPTION:
+# This eclass provides various utility functions related to Distribution
+# Kernels.
+
+if [[ ! ${_DIST_KERNEL_UTILS} ]]; then
+
+case "${EAPI:-0}" in
+ 0|1|2|3|4|5|6)
+ die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
+ ;;
+ 7)
+ ;;
+ *)
+ die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
+ ;;
+esac
+
+# @FUNCTION: dist-kernel_build_initramfs
+# @USAGE: <output> <version>
+# @DESCRIPTION:
+# Build an initramfs for the kernel. <output> specifies the absolute
+# path where initramfs will be created, while <version> specifies
+# the kernel version, used to find modules.
+#
+# Note: while this function uses dracut at the moment, other initramfs
+# variants may be supported in the future.
+dist-kernel_build_initramfs() {
+ debug-print-function ${FUNCNAME} "${@}"
+
+ [[ ${#} -eq 2 ]] || die "${FUNCNAME}: invalid arguments"
+ local output=${1}
+ local version=${2}
+
+ local rel_image_path=$(dist-kernel_get_image_path)
+ local image=${output%/*}/${rel_image_path##*/}
+
+ local args=(
+ --force
+ # if uefi=yes is used, dracut needs to locate the kernel image
+ --kernel-image "${image}"
+
+ # positional arguments
+ "${output}" "${version}"
+ )
+
+ ebegin "Building initramfs via dracut"
+ dracut "${args[@]}"
+ eend ${?} || die -n "Building initramfs failed"
+}
+
+# @FUNCTION: dist-kernel_get_image_path
+# @DESCRIPTION:
+# Get relative kernel image path specific to the current ${ARCH}.
+dist-kernel_get_image_path() {
+ case ${ARCH} in
+ amd64|x86)
+ echo arch/x86/boot/bzImage
+ ;;
+ arm64)
+ echo arch/arm64/boot/Image.gz
+ ;;
+ arm)
+ echo arch/arm/boot/zImage
+ ;;
+ ppc64)
+ # ./ is required because of ${image_path%/*}
+ # substitutions in the code
+ echo ./vmlinux
+ ;;
+ *)
+ die "${FUNCNAME}: unsupported ARCH=${ARCH}"
+ ;;
+ esac
+}
+
+# @FUNCTION: dist-kernel_install_kernel
+# @USAGE: <version> <image> <system.map>
+# @DESCRIPTION:
+# Install kernel using installkernel tool. <version> specifies
+# the kernel version, <image> full path to the image, <system.map>
+# full path to System.map.
+dist-kernel_install_kernel() {
+ debug-print-function ${FUNCNAME} "${@}"
+
+ [[ ${#} -eq 3 ]] || die "${FUNCNAME}: invalid arguments"
+ local version=${1}
+ local image=${2}
+ local map=${3}
+
+ # if dracut is used in uefi=yes mode, initrd will actually
+ # be a combined kernel+initramfs UEFI executable. we can easily
+ # recognize it by PE magic (vs cpio for a regular initramfs)
+ local initrd=${image%/*}/initrd
+ local magic
+ [[ -s ${initrd} ]] && read -n 2 magic < "${initrd}"
+ if [[ ${magic} == MZ ]]; then
+ einfo "Combined UEFI kernel+initramfs executable found"
+ # install the combined executable in place of kernel
+ image=${initrd}.uefi
+ mv "${initrd}" "${image}" || die
+ # put an empty file in place of initrd. installing a duplicate
+ # file would waste disk space, and removing it entirely provokes
+ # kernel-install to regenerate it via dracut.
+ > "${initrd}"
+ fi
+
+ ebegin "Installing the kernel via installkernel"
+ # note: .config is taken relatively to System.map;
+ # initrd relatively to bzImage
+ installkernel "${version}" "${image}" "${map}"
+ eend ${?} || die -n "Installing the kernel failed"
+}
+
+# @FUNCTION: dist-kernel_reinstall_initramfs
+# @USAGE: <kv-dir> <kv-full>
+# @DESCRIPTION:
+# Rebuild and install initramfs for the specified dist-kernel.
+# <kv-dir> is the kernel source directory (${KV_DIR} from linux-info),
+# while <kv-full> is the full kernel version (${KV_FULL}).
+# The function will determine whether <kernel-dir> is actually
+# a dist-kernel, and whether initramfs was used.
+#
+# This function is to be used in pkg_postinst() of ebuilds installing
+# kernel modules that are included in the initramfs.
+dist-kernel_reinstall_initramfs() {
+ debug-print-function ${FUNCNAME} "${@}"
+
+ [[ ${#} -eq 2 ]] || die "${FUNCNAME}: invalid arguments"
+ local kernel_dir=${1}
+ local ver=${2}
+
+ local image_path=${kernel_dir}/$(dist-kernel_get_image_path)
+ local initramfs_path=${image_path%/*}/initrd
+ if [[ ! -f ${image_path} ]]; then
+ eerror "Kernel install missing, image not found:"
+ eerror " ${image_path}"
+ eerror "Initramfs will not be updated. Please reinstall your kernel."
+ return
+ fi
+ if [[ ! -f ${initramfs_path} ]]; then
+ einfo "No initramfs found at ${initramfs_path}"
+ return
+ fi
+
+ dist-kernel_build_initramfs "${initramfs_path}" "${ver}"
+ dist-kernel_install_kernel "${ver}" "${image_path}" \
+ "${kernel_dir}/System.map"
+}
+
+_DIST_KERNEL_UTILS=1
+fi