summaryrefslogtreecommitdiffstats
path: root/debian/initramfs.hook
diff options
context:
space:
mode:
Diffstat (limited to 'debian/initramfs.hook')
-rwxr-xr-xdebian/initramfs.hook168
1 files changed, 168 insertions, 0 deletions
diff --git a/debian/initramfs.hook b/debian/initramfs.hook
new file mode 100755
index 0000000..a464d09
--- /dev/null
+++ b/debian/initramfs.hook
@@ -0,0 +1,168 @@
+#!/bin/sh
+# intel-microcode initramfs-tools hook script version 3
+# Copyright (C) 2012-2016 Henrique de Moraes Holschuh <hmh@debian.org>
+# Released under the GNU GPL v2 or later license
+#
+# Generates a copy of the Intel microcode (by default tailored to the
+# running system), and installs it in the early initramfs.
+#
+# iucode_tool v1.0 or later is required.
+#
+
+PREREQ=""
+IUCODE_CONFIG=/etc/default/intel-microcode
+
+prereqs()
+{
+ echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+ prereqs
+ exit 0
+ ;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+
+verbose()
+{
+ if [ "${verbose}" = "y" ] ; then
+ echo "intel-microcode: $*"
+ fi
+ :
+}
+
+if [ "${verbose}" = "y" ] ; then
+ IUCODE_TOOL_OPTIONS="-l"
+else
+ IUCODE_TOOL_OPTIONS="-q"
+fi
+
+IUCODE_TOOL=$(command -v iucode_tool)
+if [ -z "${IUCODE_TOOL}" ] && [ -x /usr/sbin/iucode_tool ] ; then
+ IUCODE_TOOL=/usr/sbin/iucode_tool
+fi
+
+IUCODE_FW_DIR=/lib/firmware/intel-ucode
+if [ "$MODULES" = "most" ]; then
+ IUCODE_TOOL_INITRAMFS=early
+ IUCODE_TOOL_SCANCPUS=no
+else
+ IUCODE_TOOL_INITRAMFS=auto
+ IUCODE_TOOL_SCANCPUS=yes
+fi
+IUCODE_TOOL_EXTRA_OPTIONS=
+
+[ -r ${IUCODE_CONFIG} ] && . ${IUCODE_CONFIG}
+
+[ -z "${IUCODE_TOOL_INITRAMFS}" ] && IUCODE_TOOL_INITRAMFS=no
+
+case "${IUCODE_TOOL_INITRAMFS}" in
+ no|0)
+ verbose "intel-microcode: disabled by ${IUCODE_CONFIG}"
+ exit 0
+ ;;
+ auto|early)
+ ;;
+ yes|1)
+ IUCODE_TOOL_INITRAMFS=early
+ echo "W: intel-microcode: initramfs mode not supported, using early initramfs mode" >&2
+ ;;
+ *)
+ echo "E: intel-microcode: invalid IUCODE_TOOL_INITRAMFS, using automatic mode" >&2
+ IUCODE_TOOL_INITRAMFS=auto
+esac
+
+# don't do anything unless there's an Intel processor in the system in auto mode
+if [ "${IUCODE_TOOL_INITRAMFS}" = "auto" ] ; then
+ grep -q "^vendor_id[[:blank:]]*:[[:blank:]]*.*GenuineIntel" /proc/cpuinfo || {
+ verbose "no Intel processors detected, nothing to do"
+ exit 0
+ }
+fi
+
+# we require iucode_tool, but something is broken
+if [ ! -x "${IUCODE_TOOL}" ] ; then
+ echo "E: intel-microcode: cannot run iucode_tool!" >&2
+ exit 0
+fi
+
+# Blacklist all kernel versions before v3.10, as they don't support early
+# initramfs mode.
+#
+# This doesn't blacklist early 3.10 kernels in the LTS branches, we don't have
+# enough information at the initramfs-tools layer, due to the way Debian and
+# Ubuntu version kernel packages.
+if dpkg --compare-versions "${version}" lt 3.10 ; then
+ echo "E: intel-microcode: unsupported kernel version!" >&2
+ exit 0
+fi
+
+if [ "${IUCODE_TOOL_SCANCPUS}" != "yes" ] ; then
+ verbose "adding microcode for either all or selected Intel processor models"
+else
+ verbose "adding microcode for currently online and selected Intel processors"
+ grep -q cpu/cpuid /proc/devices || modprobe -q cpuid
+ IUCODE_TOOL_OPTIONS="${IUCODE_TOOL_OPTIONS} --scan-system"
+fi
+
+# paranoia
+[ -z "${DESTDIR}" ] && {
+ echo "E: intel-microcode: DESTDIR empty!" >&2
+ exit 1
+}
+[ -z "${IUCODE_FW_DIR}" ] && {
+ echo "E: intel-microcode: IUCODE_FW_DIR empty!" >&2
+ exit 1
+}
+
+# include the microcode module in the initramfs for logging purposes, but
+# ensure it will have no microcode data files to load. This is also a safety
+# net: we don't want it to be acidentally loaded outside the initramfs.
+#
+# This shouldn't be expensive, as the in-kernel firmware loader is quite
+# fast at detecting missing data files and doesn't wait for them.
+#
+# note: force_load will load a blacklisted module. We depend on that behavior.
+#
+# For 4.4 and later kernels, the microcode driver cannot be a module and will
+# be built-in.
+dpkg --compare-versions "${version}" lt 4.4 && {
+ [ -d "${DESTDIR}${IUCODE_FW_DIR}" ] && rm -fr "${DESTDIR}${IUCODE_FW_DIR}"
+
+ manual_add_modules microcode && {
+ # force_load has broken semanthics when the .ko file is missing
+ find "${DESTDIR}/${MODULESDIR}" -type f -print | grep -qc '/microcode\.ko$' && {
+ verbose "modular microcode driver detected"
+ force_load microcode
+ }
+ }
+}
+
+# generate early initramfs image and prepend
+verbose "using early initramfs microcode update mode..."
+EFW=$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-EFW_XXXXXXXXXX") || {
+ echo "E: intel-microcode: cannot create temporary file" >&2
+ exit 1
+ }
+( find /usr/share/misc -maxdepth 1 -type f -name 'intel-microcode*' -print0 ;
+ find "${IUCODE_FW_DIR}" -maxdepth 0 -type d -print0 ) 2>/dev/null \
+| xargs -0 -r -x ${IUCODE_TOOL} ${IUCODE_TOOL_OPTIONS} \
+ --write-earlyfw="${EFW}" --overwrite \
+ ${IUCODE_TOOL_EXTRA_OPTIONS} \
+&& prepend_earlyinitramfs "${EFW}" && {
+ rm "${EFW}"
+ exit 0
+}
+
+# usually we get here when initramfs-tools is missing prepend_earlyinitramfs()
+# or when iucode_tool does not support --write-earlyfw, i.e. when old versions
+# of these tools are installed.
+
+rm "${EFW}" || true
+
+echo "E: intel-microcode: failed to create or prepend the early initramfs to the initramfs" >&2
+
+: