Intel microcode
This article describes the process of updating the microcode on Intel processors.
Installation
The microcode-ctl utility has been deprecated as of version 1.28-r1(Gentoo unstable)[1] and no longer contains the init script. It also does not work on certain CPUs such as Intel Haswells, you should switch to the "Early microcode" method explained directly below. If however you wish to continue using microcode-ctl please skip to the Microcode-ctl section.
Kernel
The following kernel support is required to be built-in:
General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
Processor type and features --->
<*> CPU microcode loading support
[*] Intel microcode loading support
Modules do not work for early microcode, so make sure microcode loading is built-in.
Emerge
Install the microcode firmware package and the manipulation tool:
root #emerge --ask --noreplace sys-firmware/intel-microcode sys-apps/iucode_toolConfiguration
If the
initramfs USE flag is active the intel-microcode ebuild will automatically install a cpio archive of all microcode into /boot/intel-uc.img.To manually generate the microcode cpio archive use iucode_tool:
root #iucode_tool -S --write-earlyfw=/boot/early_ucode.cpio /lib/firmware/intel-ucode/*iucode_tool: system has processor(s) with signature 0x000306c3 iucode_tool: Writing selected microcodes to: /boot/early_ucode.cpio
Genkernel
If you use genkernel to generate your initrd then add the --microcode option to have it prepend an early cpio with the Intel and AMD microcode inside. No modifications to your bootloader config are necessary below.
You need >=sys-kernel/genkernel-3.5.0.7 for microcode support which isn't yet stabilized. Please see for how to keyword a single package.
Syslinux
Multiple initrd files are separated by commas in the INITRD line. Set early_ucode.cpio to load first:
/boot/syslinux.cfgLABEL gentoo
MENU LABEL Gentoo Linux 4.4.6
LINUX /vmlinuz-4.4.6-gentoo
INITRD /early_ucode.cpio,/initrd-4.4.6-gentoo.img
GRUB Legacy
Add the generated microcode to the kernel command-line as the first initrd. The root initramfs goes second separated by space. This step is necessary even if the system does not use an initrd image in order to boot. The microcode update merely leverages the initrd hooks:
/boot/grub/grub.confExample GRUB Legacy configuration for microcode updatetitle Gentoo Linux 4.4.6
root (hd0,0)
kernel /boot/vmlinuz-4.4.6-gentoo root=/dev/sda3
initrd /boot/intel-uc.img /boot/initrd.img
GRUB
If using Grub's scripted configuration, change this small section of /etc/grub.d/10_linux from:
/etc/grub.d/10_linuxBeforeinitrd=
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd="$i"
break
fi
done
To this:
/etc/grub.d/10_linuxAfterinitrd=
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd="early_ucode.cpio ${rel_dirname}/${i}"
break
else
initrd="early_ucode.cpio"
fi
done
This is the most pain-free method I've found to load the microcode, works with or without an initramfs.
If you were not using an initrd before, make sure to specify the root partition by name instead of UUID. This can be done by setting flag
GRUB_DISABLE_LINUX_UUID=true in /etc/default/grub followed by regenerating the grub.cfg.
Alternatively, the root partition name can be specified directly in GRUB menu or by editing grub.cfgRegenerate the grub.cfg with:
root #grub-mkconfig -o /boot/grub/grub.cfgGenerating grub configuration file ... Found linux image: /boot/vmlinuz-4.6.3-gentoo Found initrd image: /boot/early_ucode.cpio /initramfs-genkernel-x86_64-4.6.3-gentoo done
This is similar to what you should see, minus the initramfs if you do not have one.
Or edit grub.cfg directly to add the microcode.cpio as your first initrd:
/boot/grub/grub.cfgmenuentry 'Gentoo Linux 4.14' {
root=hd0,1
linux /boot/linux-4.14.12 root=LABEL=ROOT rootfstype=ext4 ro
initrd /boot/intel-uc.img /boot/initrd.img
}
Reboot and you're all done.
rEFInd
/efi/EFI/refind/refind.confmenuentry Linux {
icon EFI/refind/icons/os_gentoo.png
volume foo
loader boot/vmlinuz
options "initrd=boot/early_ucode.cpio initrd=boot/bootsplash-initramfs console=tty1 ro root=foo"
submenuentry "Old Kernel" {
loader boot/vmlinuz.old
}
}
This example system has the EFI partition /dev/sda1 mounted to /efi. The Linux kernel and initrd files have been placed in /boot on the Linux rootfs.
If you are using the initrd keyword instead of the options keyword for specifying initrd, then try specifying multiple initrd files via separate initrd keywords, or migrate the declarations into options. Specifying multiple initrd via one initrd keyword fails on rEFInd. As always, make sure boot/early_code.cpio is the first initrd specified.
You can review and edit the kernel cmdline options from the rEFInd bootloader. With your Gentoo OS entry highlighted, press F2 to access the menu entries, and press F2 again over the desired entry to review and edit. This is very useful for quick experimenting without need to edit refind.conf.
See refind.conf for keyword descriptions and The rEFInd Homepage for more on how to use rEFInd.
systemd-boot
Add the microcode as an argument to an initrd line. If you already have an initrd line, ensure the microcode line occurs first. The path to the microcode should be absolute to the root of the ESP.
/boot/EFI/loader/entries/exampletitle Gentoo/Linux
version 4.13.13
options root=/dev/sda1
linux /4.13.13/linux
initrd /4.13.13/intel_ucode
initrd /4.13.13/initrd
For more information, see The Boot Loader Specification.
Xen (EFI)
Add a line to your xen.cfg with the ucode option. The path to the microcode is relative to the xen.efi binary, so you will need to write the microcode into the correct location (default is /boot/EFI/Gentoo) or copy it there.
/boot/EFI/Gentoo/xen.cfg[global]
default=gentoo
[gentoo]
kernel=vmlinuz-4.4.6-gentoo root=/dev/sda1
ramdisk=initrd-4.4.6-gentoo.img
ucode=early_ucode.cpio
For more information, see the Xen EFI documentation.
Verification
Here is an example of a CPU with no available microcode updates (microcode already current) or the system was not configured to load them properly:
root #dmesg | grep microcode[ 1.196567] microcode: CPU0 sig=0x6fd, pf=0x80, revision=0xa3 [ 1.196575] microcode: CPU1 sig=0x6fd, pf=0x80, revision=0xa3 [ 1.196623] microcode: Microcode Update Driver: v2.01 <tigran@aivazian.fsnet.co.uk>, Peter Oruba
Here is the same CPU but with microcode updates being applied successfully:
root #dmesg | grep microcode[ 0.000000] microcode: microcode updated early to revision 0xa4, date = 2010-10-02 [ 1.207385] microcode: CPU0 sig=0x6fd, pf=0x80, revision=0xa4 [ 1.207393] microcode: CPU1 sig=0x6fd, pf=0x80, revision=0xa4 [ 1.207445] microcode: Microcode Update Driver: v2.01 <tigran@aivazian.fsnet.co.uk>, Peter Oruba
The loaded microcode revision can be verified by running:
user $grep microcode /proc/cpuinfomicrocode : 0xa4 microcode : 0xa4
Microcode-ctl
The microcode-ctl utility has been deprecated as of 1.28-r1 (Gentoo unstable) and will no longer contain the init script. It also does not work on certain CPUs such as Intel Haswells, the information below this point is only relevant to microcode-ctl users.
Kernel
Activate the following kernel options:
Processor type and features --->
<M> CPU microcode loading support
[*] Intel microcode loading support
If you build it as module, it will automatically get loaded as needed and then unloaded after microcode update saving some memory.
Software
Install sys-apps/microcode-ctl:
root #emerge --ask sys-apps/microcode-ctlOpenRC
Start microcode-ctl:
root #/etc/init.d/microcode_ctl startTo start microcode-ctl at boot time, add it your boot runlevel:
root #rc-update add microcode_ctl bootUsing boot runlevel ensures the CPU is updated as soon as possible.
systemd
See: Systemd. Simply make sure that the Microcode loader is set as a module in the kernel configuration as noted above. You don't need to add a service or do anything else.
New method without initram-fs/disk
This will only work on a 64-bit kernel and will have no effect otherwise. On 32-bit systems you need to use an initramfs.
This method should be preferable, especially for EFI-Stub systems (some motherboard firmware might have issues with parsing/passing custom boot command line options), since these changes are less likely to leave your system unbootable (and possibly unrepairable without an EFI compatible rescue disk which can be very tricky on headless machines) the way a broken firmware boot entry and/or incorrect initram-fs/disk would, while it also works on BIOS systems or EFI systems with custom bootloaders on disk. However, this requires a relatively recent kernel version (possibly unstable at the time of writing). It was tested with Linux 4.8.0
Software
The sys-firmware/intel-microcode-20171117-r1 package has been rewritten to use iucode_tool to process microcode data files. Users can now use the MICROCODE_SIGNATURES variable to install only a subset of microcode data files.
To install microcode data files for the system processor(s):
/etc/portage/make.confMICROCODE_SIGNATURES="-S"
To install microcode data files for a specific processor use MICROCODE_SIGNATURES="-s 0x000306c3", or MICROCODE_SIGNATURES="-s !0x000306c3" to exclude a specific processor. An empty or undefined MICROCODE_SIGNATURES variable will install all microcode data files.
Install the microcode data files:
root #emerge --ask sys-firmware/intel-microcodeThe sys-firmware/intel-microcode-20171117-r1 installs iucode_tool which can be used to identify the processor signature(s).
root #iucode_tool -Siucode_tool: system has processor(s) with signature 0x000306c3
To find the appropriate filename(s) for the listed signature(s) use:
root #iucode_tool -S -l /lib/firmware/intel-ucode/*iucode_tool: system has processor(s) with signature 0x000306c3 [...] microcode bundle 49: /lib/firmware/intel-ucode/06-3c-03 [...] selected microcodes: 049/001: sig 0x000306c3, pf_mask 0x32, 2017-01-27, rev 0x0022, size 22528
The signature is found in microcode bundle 49, so the filename to use is /lib/firmware/intel-ucode/06-3c-03.
Kernel
Enable and configure the CONFIG_MICROCODE, CONFIG_MICROCODE_INTEL, CONFIG_FIRMWARE_IN_KERNEL, CONFIG_EXTRA_FIRMWARE and CONFIG_EXTRA_FIRMWARE_DIR kernel options. The options must be built-in.
Processor type and features --->
<*> CPU microcode loading support
[*] Intel microcode loading support
Device Drivers --->
Generic Driver Options --->
[*] Include in-kernel firmware blobs in kernel binary
(intel-ucode/06-3c-03) External firmware blobs to build into the kernel binary
(/lib/firmware) Firmware blobs root directory
The CONFIG_EXTRA_FIRMWARE and CONFIG_EXTRA_FIRMWARE_DIR options need to be set to the values identified by iucode_tool. In this example for an Intel i7-4790K processor, CONFIG_EXTRA_FIRMWARE is set to
intel-ucode/06-3c-03 and CONFIG_EXTRA_FIRMWARE_DIR is set to /lib/firmware.Rebuild and install the kernel as usual.
Verification
After the next reboot, you should see something like this:
root #dmesg | grep microcode[ 0.000000] microcode: microcode updated early to revision 0x22, date = 2017-01-27 [ 1.153262] microcode: sig=0x306c3, pf=0x2, revision=0x22 [ 1.153815] microcode: Microcode Update Driver: v2.2.
Note how this is the very first step of the kernel logs now.
If you use genkernel and legacy grub, you will not have the first line. Just check the microcode revision before and after the changes.
Be aware that injecting the microcode update directly into the motherboard firmware (which might sounds tempting) might result in CPU0 being updated but the rest of the CPUs (or CPU cores in a multi-core system) being left at their initial revision (which might cause more problems than running them all at the same initial version). And, since most stock motherboard firmware has some microcode updates (even in their initial release versions), it's probably a good enough reason for everybody to make sure their kernel tries to update all CPUs (and cores) to the same version (so, let this update driver running even if the kernel has the same version which is stored in the motherboard firmware). Injecting the microcode into the firmware might be desirable still (to make sure it's loaded for the boot CPU before the kernel is loaded and able to update the rest of the microcode).
See also
- Intel — the open source graphics driver for Intel GMA on-board graphics cards and Intel iGPU and Intel Arc dedicated graphics cards, starting with the Intel 810.
External resources
- http://www.win-raid.com/t154f16-Tool-Guide-News-quot-UEFI-BIOS-Updater-quot-UBU.html - An example unofficial source for microcodes
References
- ↑ https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=719cc5ef240b766953ddbe1e7a6593f8091eed12 The microcode-ctl utility has been deprecated as of version 1.28-r1(Gentoo unstable) and no longer contains the init script. It also does not work on certain CPUs such as Intel Haswells.