summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Ammerlaan <andrewammerlaan@gentoo.org>2024-06-27 12:26:35 +0200
committerAndrew Ammerlaan <andrewammerlaan@gentoo.org>2024-06-28 15:35:35 +0200
commitafeaf7f98275b3d5d7b1902bd22adc93593ba32d (patch)
tree55fb00b3b24e8adb19c024c9a7f27c98ac8ab831
parentsys-firmware/intel-microcode: add ucode image generator hooks (diff)
downloadgentoo-afeaf7f98275b3d5d7b1902bd22adc93593ba32d.tar.gz
gentoo-afeaf7f98275b3d5d7b1902bd22adc93593ba32d.tar.bz2
gentoo-afeaf7f98275b3d5d7b1902bd22adc93593ba32d.zip
sys-kernel/linux-firmware: add ucode image generator hooks
This creates a AMD microcode image when installing the kernel and when installkernel/kernel-install is configured to use an initramfs generator other then dracut. Dracut bundles the microcode in the image it generates, many other initramfs generators do not and we want these users to also get the latest CPU microcode. installkernel-gentoo.git has recently gained support for handling these ucode images and passing them on to bootloaders and UKI generators. Note that this should be here and not in installkernel-gentoo.git because we only want to install this when the initramfs flag is enabled to avoid the situation where users who don't want an ucode.img get one anyway. To avoid code-duplication we add and install a little helper script that we can call both from the ebuild and from the hooks. Co-authored-by: Zen <z@pyl.onl> Signed-off-by: Andrew Ammerlaan <andrewammerlaan@gentoo.org> Closes: https://github.com/gentoo/gentoo/pull/37320 Signed-off-by: Andrew Ammerlaan <andrewammerlaan@gentoo.org>
-rw-r--r--sys-kernel/linux-firmware/files/35-amd-microcode-systemd.install35
-rw-r--r--sys-kernel/linux-firmware/files/35-amd-microcode.install39
-rw-r--r--sys-kernel/linux-firmware/files/linux-firmware-make-amd-ucode-img.bash79
-rw-r--r--sys-kernel/linux-firmware/linux-firmware-20240610-r1.ebuild (renamed from sys-kernel/linux-firmware/linux-firmware-20240610.ebuild)33
-rw-r--r--sys-kernel/linux-firmware/linux-firmware-99999999.ebuild32
5 files changed, 181 insertions, 37 deletions
diff --git a/sys-kernel/linux-firmware/files/35-amd-microcode-systemd.install b/sys-kernel/linux-firmware/files/35-amd-microcode-systemd.install
new file mode 100644
index 000000000000..edafb4d63035
--- /dev/null
+++ b/sys-kernel/linux-firmware/files/35-amd-microcode-systemd.install
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+
+# Copyright 2024 Gentoo Authors
+# This script is installed by sys-kernel/linux-firmware, it is executed by
+# systemd's kernel-install, NOT by the traditional installkernel. I.e. this
+# plugin is run when the systemd USE flag is enabled or
+# SYSTEMD_KERNEL_INSTALL=1 is set in the environment.
+
+COMMAND="${1}"
+
+if [[ ${COMMAND} != add ]]; then
+ exit 0
+fi
+
+if [[ ${KERNEL_INSTALL_INITRD_GENERATOR} == dracut ]]; then
+ # Dracut bundles microcode in its initramfs images
+ [[ ${KERNEL_INSTALL_VERBOSE} == 1 ]] && echo \
+ "initrd_generator=${KERNEL_INSTALL_INITRD_GENERATOR} bundles CPU microcode, nothing to do here."
+ exit 0
+fi
+
+# do nothing if somehow make-amd-ucode-img is not installed
+if ! command -v make-amd-ucode-img >/dev/null; then
+ [[ ${KERNEL_INSTALL_VERBOSE} == 1 ]] && echo \
+ "make-amd-ucode-img command not available"
+ exit 1
+fi
+
+[[ ${KERNEL_INSTALL_VERBOSE} == 1 ]] && echo \
+ "Generating AMD CPU Microcode early initramfs image..."
+
+make-amd-ucode-img \
+ ${KERNEL_INSTALL_STAGING_AREA}/microcode-amd \
+ /lib/firmware/amd-ucode ||
+ { echo "make-amd-ucode-img failed" && exit 1; }
diff --git a/sys-kernel/linux-firmware/files/35-amd-microcode.install b/sys-kernel/linux-firmware/files/35-amd-microcode.install
new file mode 100644
index 000000000000..185e57be0dae
--- /dev/null
+++ b/sys-kernel/linux-firmware/files/35-amd-microcode.install
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+# Copyright 2024 Gentoo Authors
+# This script is installed by sys-kernel/linux-firmware, it is executed by
+# the traditional installkernel, NOT by systemd's kernel-install. I.e. this
+# plugin is run when the systemd USE flag is disabled or
+# SYSTEMD_KERNEL_INSTALL=0 is set in the environment.
+
+# familiar helpers, we intentionally don't use Gentoo functions.sh
+die() {
+ echo -e " ${NOCOLOR-\e[1;31m*\e[0m }${*}" >&2
+ exit 1
+}
+
+einfo() {
+ echo -e " ${NOCOLOR-\e[1;32m*\e[0m }${*}" >&2
+}
+
+main() {
+ # re-define for subst to work
+ [[ -n ${NOCOLOR+yes} ]] && NOCOLOR=
+
+ if [[ ${INSTALLKERNEL_INITRD_GENERATOR} == dracut ]]; then
+ # Dracut bundles microcode in its initramfs images
+ echo "initrd_generator=${INSTALLKERNEL_INITRD_GENERATOR} bundles CPU microcode, nothing to do here."
+ exit 0
+ fi
+
+ # do nothing if somehow make-amd-ucode-img is not installed
+ [[ -x $(command -v make-amd-ucode-img) ]] || die "make-amd-ucode-img command not available"
+
+ [[ ${EUID} -eq 0 ]] || die "Please run this script as root"
+
+ einfo "Generating AMD CPU Microcode early initramfs image..."
+ make-amd-ucode-img /boot/amd-uc.img /lib/firmware/amd-ucode ||
+ die "make-amd-ucode-img failed"
+}
+
+main
diff --git a/sys-kernel/linux-firmware/files/linux-firmware-make-amd-ucode-img.bash b/sys-kernel/linux-firmware/files/linux-firmware-make-amd-ucode-img.bash
new file mode 100644
index 000000000000..5fac567e063d
--- /dev/null
+++ b/sys-kernel/linux-firmware/files/linux-firmware-make-amd-ucode-img.bash
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+
+# Copyright 2024 Gentoo Authors
+
+our_name=${0}
+out=${1}
+in=${2}
+
+# familiar helpers, we intentionally don't use Gentoo functions.sh
+die() {
+ echo -e " ${NOCOLOR-\e[1;31m*\e[0m }${*}" >&2
+ exit 1
+}
+
+einfo() {
+ echo -e " ${NOCOLOR-\e[1;32m*\e[0m }${*}" >&2
+}
+
+main() {
+ # re-define for subst to work
+ [[ -n ${NOCOLOR+yes} ]] && NOCOLOR=
+
+
+ # Set the output file to arg 1 if it's not a directory.
+ # If it's a directory, set the out file to the directory with the default name.
+ # If it's a relative filename, include it in the variable.
+ local ucode_file=${out:-"/boot/amd-uc.img"}
+ if [[ -d ${ucode_file} ]]; then
+ ucode_file="${ucode_file}/amd-uc.img"
+ einfo "Output file is a directory. Using default name: ${ucode_file}"
+ elif [[ ${ucode_file} != /* ]]; then
+ ucode_file="$(pwd)/${ucode_file}"
+ einfo "Output file is a relative path. Using full path: ${ucode_file}"
+ elif [[ -z ${ucode_file} ]]; then
+ einfo "Usage: ${our_name} <output image> <microcode directory>"
+ die "No output file specified"
+ fi
+
+ # Only AMD microcode is in the linux-firmmware package
+ local ucode_dir=${in:-"/lib/firmware/amd-ucode"}
+ if [[ ! -d ${ucode_dir} ]]; then
+ einfo "Usage: ${our_name} <output image> <microcode directory>"
+ die "AMD microcode directory does not exist: ${ucode_dir}"
+ fi
+
+ # Make the tmp dir for the microcode archive
+ local ucode_tmp_dir="$(mktemp -d)" || die "Failed to create temporary directory"
+ einfo "Created temporary directory: ${ucode_tmp_dir}"
+ local ucode_bin_dir="${ucode_tmp_dir}/kernel/x86/microcode"
+ local ucode_bin_file="${ucode_bin_dir}/AuthenticAMD.bin"
+
+ # Write "1" to the early_cpio flag file
+ echo 1 > "${ucode_tmp_dir}/early_cpio" || die
+
+ # Make the directory for the microcode bin files
+ mkdir -p "${ucode_bin_dir}" || die "Failed to create microcode bin directory: ${ucode_bin_dir}"
+
+ # Concatenate all microcode bin files into a single file
+ cat "${ucode_dir}"/*.bin > "${ucode_bin_file}" || die "Failed to concatenate microcode files into: ${ucode_bin_file}"
+
+ # Check that the concatenated file is not empty
+ [[ -s "${ucode_bin_file}" ]] || die "Empty microcode file: ${ucode_bin_file}"
+
+ pushd "${ucode_tmp_dir}" &> /dev/null || die
+ # Create the cpio archive
+ find . -print0 | cpio --quiet --null -o -H newc -R 0:0 > "${ucode_file}" || die "Failed to create microcode archive in: ${ucode_file}"
+ popd &> /dev/null || die
+
+ # Check that the cpio archive is not empty
+ [[ -s "${ucode_file}" ]] || die "Empty microcode archive at: ${ucode_file}"
+
+ einfo "Created microcode archive at: ${ucode_file}"
+ # Clean up the tmp dir
+ rm -r "${ucode_tmp_dir}" || die "Failed to remove temporary directory: ${ucode_tmp_dir}"
+ einfo "Cleaned up temporary directory: ${ucode_tmp_dir}"
+}
+
+main
+
diff --git a/sys-kernel/linux-firmware/linux-firmware-20240610.ebuild b/sys-kernel/linux-firmware/linux-firmware-20240610-r1.ebuild
index 1bb6954d00c8..32bd327957ea 100644
--- a/sys-kernel/linux-firmware/linux-firmware-20240610.ebuild
+++ b/sys-kernel/linux-firmware/linux-firmware-20240610-r1.ebuild
@@ -102,7 +102,6 @@ src_unpack() {
}
src_prepare() {
-
default
find . -type f -not -perm 0644 -print0 \
@@ -110,27 +109,12 @@ src_prepare() {
|| die
chmod +x copy-firmware.sh || die
+ cp "${FILESDIR}/${PN}-make-amd-ucode-img.bash" "${T}/make-amd-ucode-img" || die
+ chmod +x "${T}/make-amd-ucode-img" || die
if use initramfs && ! use dist-kernel; then
if [[ -d "${S}/amd-ucode" ]]; then
- local UCODETMP="${T}/ucode_tmp"
- local UCODEDIR="${UCODETMP}/kernel/x86/microcode"
- mkdir -p "${UCODEDIR}" || die
- echo 1 > "${UCODETMP}/early_cpio"
-
- local amd_ucode_file="${UCODEDIR}/AuthenticAMD.bin"
- cat "${S}"/amd-ucode/*.bin > "${amd_ucode_file}" || die "Failed to concat amd cpu ucode"
-
- if [[ ! -s "${amd_ucode_file}" ]]; then
- die "Sanity check failed: '${amd_ucode_file}' is empty!"
- fi
-
- pushd "${UCODETMP}" &>/dev/null || die
- find . -print0 | cpio --quiet --null -o -H newc -R 0:0 > "${S}"/amd-uc.img
- popd &>/dev/null || die
- if [[ ! -s "${S}/amd-uc.img" ]]; then
- die "Failed to create '${S}/amd-uc.img'!"
- fi
+ "${T}/make-amd-ucode-img" "${S}" "${S}/amd-ucode" || die
else
# If this will ever happen something has changed which
# must be reviewed
@@ -357,6 +341,17 @@ src_install() {
insinto /usr/lib/dracut/dracut.conf.d
newins - 10-${PN}.conf <<<"early_microcode=$(usex initramfs)"
)
+ if use initramfs; then
+ # Install installkernel/kernel-install hooks for non-dracut initramfs
+ # generators that don't bundled the microcode
+ dobin "${T}/make-amd-ucode-img"
+ (
+ exeinto /usr/lib/kernel/preinst.d
+ doexe "${FILESDIR}/35-amd-microcode.install"
+ exeinto /usr/lib/kernel/install.d
+ doexe "${FILESDIR}/35-amd-microcode-systemd.install"
+ )
+ fi
if use initramfs && ! use dist-kernel; then
insinto /boot
diff --git a/sys-kernel/linux-firmware/linux-firmware-99999999.ebuild b/sys-kernel/linux-firmware/linux-firmware-99999999.ebuild
index dc02d051d7ea..26c21e80395e 100644
--- a/sys-kernel/linux-firmware/linux-firmware-99999999.ebuild
+++ b/sys-kernel/linux-firmware/linux-firmware-99999999.ebuild
@@ -107,27 +107,12 @@ src_prepare() {
|| die
chmod +x copy-firmware.sh || die
+ cp "${FILESDIR}/${PN}-make-amd-ucode-img.bash" "${T}/make-amd-ucode-img" || die
+ chmod +x "${T}/make-amd-ucode-img" || die
if use initramfs && ! use dist-kernel; then
if [[ -d "${S}/amd-ucode" ]]; then
- local UCODETMP="${T}/ucode_tmp"
- local UCODEDIR="${UCODETMP}/kernel/x86/microcode"
- mkdir -p "${UCODEDIR}" || die
- echo 1 > "${UCODETMP}/early_cpio"
-
- local amd_ucode_file="${UCODEDIR}/AuthenticAMD.bin"
- cat "${S}"/amd-ucode/*.bin > "${amd_ucode_file}" || die "Failed to concat amd cpu ucode"
-
- if [[ ! -s "${amd_ucode_file}" ]]; then
- die "Sanity check failed: '${amd_ucode_file}' is empty!"
- fi
-
- pushd "${UCODETMP}" &>/dev/null || die
- find . -print0 | cpio --quiet --null -o -H newc -R 0:0 > "${S}"/amd-uc.img
- popd &>/dev/null || die
- if [[ ! -s "${S}/amd-uc.img" ]]; then
- die "Failed to create '${S}/amd-uc.img'!"
- fi
+ ."/${T}/make-amd-ucode-img" "${S}/amd-ucode" "${S}/amd-ucode.img" || die
else
# If this will ever happen something has changed which
# must be reviewed
@@ -361,6 +346,17 @@ src_install() {
insinto /usr/lib/dracut/dracut.conf.d
newins - 10-${PN}.conf <<<"early_microcode=$(usex initramfs)"
)
+ if use initramfs; then
+ # Install installkernel/kernel-install hooks for non-dracut initramfs
+ # generators that don't bundled the microcode
+ dobin "${T}/make-amd-ucode-img"
+ (
+ exeinto /usr/lib/kernel/preinst.d
+ doexe "${FILESDIR}/35-amd-microcode.install"
+ exeinto /usr/lib/kernel/install.d
+ doexe "${FILESDIR}/35-amd-microcode-systemd.install"
+ )
+ fi
if use initramfs && ! use dist-kernel; then
insinto /boot