Intel microcode
This article describes the process of updating the microcode on Intel processors.
Installation
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.
Since kernel version 6.6, the microcode loading support is enabled by default, and the above configuration no longer exists:
CONFIG_MICROCODE_INTEL was replaced with CONFIG_CPU_SUP_INTEL. [1]USE flags
USE flags for sys-firmware/intel-microcode Intel IA32/IA64 microcode update data
+initramfs
|
Install a small initramfs for use with CONFIG_MICROCODE_EARLY |
+split-ucode
|
Install the split binary ucode files (used by the kernel directly) |
dist-kernel
|
Delegate microcode initramfs generation to sys-kernel/installkernel |
hostonly
|
Only install ucode(s) supported by currently available (=online) processor(s) |
vanilla
|
Only install microcode updates from Intel's official microcode tarball |
Emerge
By default, the sys-firmware/intel-microcode installs all available firmware files, which can consume a significant amount of space. To install only the firmware files required for the current system, hostonly flag can be enabled. During installation, the emerge will automatically detect the processor family and install the only compatible firmware files.
/etc/portage/package.use/intel-microcodeEnable hostonly USE flagsys-firmware/intel-microcode hostonly
Install the microcode firmware package and the manipulation tool:
root #emerge --ask --noreplace sys-firmware/intel-microcodeConfiguration
If the
initramfs USE flag is active the intel-microcode ebuild will ensure that a cpio archive of all microcode is either directly installed into /boot/intel-uc.img, or it will instruct installkernel to generate one when the kernel is installed.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 genkernel is used to generate the initrd then add the --microcode-initramfs option to have it prepend an early cpio with the Intel and AMD microcode inside. No modifications to the bootloader config are necessary below.
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
Starting with version 2.02-r1, GRUB supports loading an early microcode. If the microcode file is named after one of the following: intel-uc.img, intel-ucode.img, amd-uc.img, amd-ucode.img, early_ucode.cpio, or microcode.cpio, it will be automatically detected when running grub-mkconfig. To declare a microcode file named differently, e.g. ucode.cpio, add this line to /etc/default/grub:
/etc/default/grubGRUB_EARLY_INITRD_LINUX_CUSTOM="ucode.cpio"
Regenerate 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
Finally, reboot.
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 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.
Review and edit the kernel cmdline options from the rEFInd bootloader. With the 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.
/boot/refind_linux.conf"Boot using default options" "root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw initrd=boot\intel-ucode.img initrd=boot\amd-ucode.img initrd=boot\initramfs-%v.img"
Finalize the configuration in /boot/refind_linux.conf. Keep in mind that rEFInd searches initramfs relatively partition, so if the /boot partition is separate, search it with "initrd=intel-ucode.img initrd=initramfs-%v.img" (because boot partition don't have /boot folder). Use backslashes \, or the kernel may not find the files. 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 an initrd line already exists, ensure the microcode entry 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 the xen.cfg with the ucode option. The path to the microcode is relative to the xen.efi binary. Ensure 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.
Embedding microcode into Linux kernel
This will only work on a 64-bit kernel and will have no effect otherwise. 32-bit systems need to use an initramfs.
The Linux kernel allows firmware files to be embedded directly into the kernel executable itself. To do this, the processor signature must be known; the iucode_tool from sys-firmware/intel-microcode utility can be used to identify processor signature.
user $iucode_tool -Siucode_tool: system has processor(s) with signature 0x000306c3
To find the appropriate filename(s) for the listed signature(s) use:
user $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.
See the intel ucode for Core i7-8650U forums post for an easier way to get the necessary microcode file.
Enable and configure the CONFIG_MICROCODE, CONFIG_MICROCODE_INTEL, CONFIG_FIRMWARE_IN_KERNEL, CONFIG_EXTRA_FIRMWARE and CONFIG_EXTRA_FIRMWARE_DIR kernel options. Last two 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.
The CONFIG_EXTRA_FIRMWARE option allows specifying multiple firmware files by listing them space-separated.
Every option must be set as built into the kernel, not as a kernel module.
Processor type and features --->
<*> CPU microcode loading support
[*] Intel microcode loading support
Device Drivers --->
Generic Driver Options --->
Firmware Loader --->
-*- Firmware loading facility
(intel-ucode/06-3c-03) Build named firmware blobs into the kernel binary
(/lib/firmware) Firmware blobs root directory
Rebuild and install the kernel as usual.
Verification
After the next reboot, the loaded microcode revision can be verified by running:
user $grep microcode /proc/cpuinfomicrocode : 0x22 microcode : 0x22
The dmesg output should include:
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.
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 <[email protected]>, 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 <[email protected]>, Peter Oruba
Note how this is the very first step of the kernel logs now.
It is possible the microcode has already been fully updated by your BIOS vendor. In that case the dmesg output does not contain the update log message.
Be aware that injecting the microcode update directly into the motherboard firmware (which might sound 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
- Microcode — describes various ways to update a CPU's microcode in Gentoo.
- AMD microcode — describes updating the microcode for AMD processors.