Kindly support DOTSLASHLINUX on Patreon to keep the website up and running while remaining ads free.

Building Intel CPU Microcode Updates Directly into the Linux Kernel

microcode
Firas Khalil Khana | 30/04/2017

DOTSLASHLINUX is proud to say that part of this article was added to the Gentoo Wiki

To achieve our dream of booting the kernel without an initrd/initramfs we have to build our CPU’s microcode updates directly into the linux kernel (removing any need for an initrd/initramfs). This is doable, but due to lack of documentation on the process, one may find this thing hard to do. Yes, I know, that’s why DOTSLASHLINUX was created xD.

For those who’d like to know, I’m using Gentoo Linux. Any distro will be fine though, as long as you can access your kernel’s source files. The version of the kernel’s source files that I’m using is 4.10.13.


1. Getting Ready


Fire up your favorite terminal emulator, navigate to your kernel’s source folder:

cd /usr/src/linux


Now make sure you have ncurses installed and type in:

make menuconfig


If you don’t have ncurses installed you can use:

  • make gconfig if you had GTK installed
  • make xconfig if you had Qt installed

I personally prefer make menuconfig as it’s better maintained and can be accessed from your terminal emulator or from a TTY. But as long as you can store your changes whenever you want, and go back and forth with the configuration menus then you’re good to go.

2. Enable CPU Microcode Loading Support


Navigate to Processor type and features and mark CONFIG_MICROCODE as built-in. You’ll receive two options now “Blue vs Red” microcode loading support or should I say CONFIG_MICROCODE_INTEL vs CONFIG_MICROCODE_AMD.

  [∗] DMA memory allocation support
  [∗] Symmetric multi-processing support
  [ ] Enable MPS table
  [ ] Intel Resource Director Technology Allocation support
  [ ] Support for extended (non-PC) x86 platforms
  [ ] Intel Low Power Subsystem Support
  [ ] AMD ACPI2Platform devices support
  < > Intel SoC IOSF Sideband support for SoC platforms
  [ ] Single-depth WCHAN output
  [ ] Linux guest support  ----
  Processor family (Core 2/newer Xeon)  --->
  [∗] Supported processor vendors  --->
  [∗] Enable DMI scanning
  [ ] IBM Calgary IOMMU support
  [ ] Enable Maximum number of SMP Processors and NUMA Nodes
  (8) Maximum number of CPUs
  [∗] SMT (Hyperthreading) scheduler support
  [∗] Multi-core scheduler support
  [∗]   CPU core priorities scheduler support
  Preemption Model (No Forced Preemption (Server))  --->
  [ ] Reroute for broken boot IRQs
  [∗] Machine Check / overheating reporting
  [∗]   Intel MCE features
  < > Machine check injector support
  Performance monitoring  --->
  [ ] Enable support for 16-bit segments
  [∗] Enable vsyscall emulation
  < > Dell i8k legacy laptop support
  [∗] CPU microcode loading support
  [∗]   Intel microcode loading support
  [ ]   AMD microcode loading support
  <∗> /dev/cpu/∗/msr - Model-specific register support
  <∗> /dev/cpu/∗/cpuid - CPU information support
  [∗] Numa Memory Allocation and Scheduler Support
  [ ]   Old style AMD Opteron NUMA detection
  [∗]   ACPI NUMA detection
  [ ]   NUMA emulation
  (2) Maximum NUMA Nodes (as a power of 2)
  Memory model (Sparse Memory)  --->



3- Installing Intel CPU Microcode Updates


Gentoo Linux:

emerge --sync && emerge -av sys-firmware/intel-microcode


Void Linux:

xbps-install -Su && xbps-install -S intel-ucode


Arch Linux:

pacman -Syu intel-ucode


Now hold on, don’t follow your wiki’s guide on how to build microcode updates with an initrd/initramfs, remember we’re not using an initrd/initramfs here.

Instead, we’re going to check to see if /lib/firmware was populated with intel’s CPUs microcode update files:

ls -l /lib/firmware
drwxr-xr-x 2 root root 4096 Apr 13 21:47 intel-ucode


Alright, looks like a new folder intel-ucode was created. Let’s see if it had the microcode update files:

ls -l /lib/firmware/intel-ucode
06-03-02  06-06-05  06-08-01  06-0a-01	06-0f-02  06-16-01  06-1c-02  06-26-01	06-3c-03  06-3f-04  06-56-02  0f-01-02	0f-03-02  0f-04-07  0f-06-05
06-05-00  06-06-0a  06-08-03  06-0b-01	06-0f-06  06-17-06  06-1c-0a  06-2a-07	06-3d-04  06-45-01  06-56-03  0f-02-04	0f-03-03  0f-04-08  0f-06-08
06-05-01  06-06-0d  06-08-06  06-0b-04	06-0f-07  06-17-07  06-1d-01  06-2d-06	06-3e-04  06-46-01  06-56-04  0f-02-05	0f-03-04  0f-04-09
06-05-02  06-07-01  06-08-0a  06-0d-06	06-0f-0a  06-17-0a  06-1e-05  06-2d-07	06-3e-06  06-47-01  06-5e-03  0f-02-06	0f-04-01  0f-04-0a
06-05-03  06-07-02  06-09-05  06-0e-08	06-0f-0b  06-1a-04  06-25-02  06-2f-02	06-3e-07  06-4e-03  0f-00-07  0f-02-07	0f-04-03  0f-06-02
06-06-00  06-07-03  06-0a-00  06-0e-0c	06-0f-0d  06-1a-05  06-25-05  06-3a-09	06-3f-02  06-4f-01  0f-00-0a  0f-02-09	0f-04-04  0f-06-04


Awesome, here are all of intel’s CPUs microcode update files! Now, we have to do some research to figure out which file is the one to use for our cpu :D


4- Choosing the Correct Microcode Update File


The file names here are somewhat related to the CPUID signature. The default way to get your CPUID signature (as suggested by the Gentoo Wiki) is to install a tool called iucode_tool:

emerge --sync && emerge -av sys-apps/iucode_tool


iucode_tool is also available in Arch’s AUR. (This package isn’t available on Void Linux by the time this article was written).

Now run this:

iucode_tool -S
iucode_tool: system has processor(s) with signature 0x000306c3


As you can see my CPUID signature is 0x000306c3. If that didn’t work for you then don’t worry we have other ways as well to get your CPUID signature.

You can do your research and find your CPUID signature. For example, my CPU is a 4th Gen. Intel Core i7 4700MQ, a little googling and I found this on cpu-world.com :

cpuid

Another way to do this is to install cpuid:

emerge --sync && emerge -av sys-apps/cpuid


cpuid is also available in Arch’s AUR. (This package isn’t available on Void Linux by the time this article was written).

Now run:

cpuid | grep "processor serial number"
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000
      processor serial number                = false
   processor serial number: 0003-06C3-0000-0000-0000-0000


Notice how it says processor serial number: 0003-06C3-0000-0000-0000-0000. I’ve highlighted this part 0003-06C3.

Another way to do it, is to install dmidecode:

Gentoo Linux:

emerge --sync && emerge -av sys-apps/dmidecode


Void Linux:

xbps-install -Su && xbps-install -S dmidecode


Arch Linux:

pacman -Syu dmidecode


Now run:

dmidecode | grep -w ID
  ID: 0
	ID: 1
	ID: 2
	ID: 3
	ID: 4
	ID: C3 06 03 00 FF FB EB BF


As you can see, (C, 3, 6, 0) are popping wherever I looked. You may simply choose to stop here if the signature was pretty obvious to you and you could easily identify the correct microcode update file to use (in my case I can easily tell that it’s 06-3c-03).

Now we can use iucode_tool to identify the correct microcode update file (and with the magic of grep):

iucode_tool -L /lib/firmware/intel-ucode | grep 0x000306c3 -B 1
microcode bundle 26: /lib/firmware/intel-ucode/06-3c-03
  026/001: sig 0x000306c3, pf_mask 0x32, 2017-01-27, rev 0x0022, size 22528
  026/002: sig 0x000306c3, pf_mask 0x32, 2017-01-27, rev 0x0022, size 22528


As you can clearly see my microcode update file in /lib/firmware/intel-ucode is 06-3c-03.


5- Configuring the Linux Kernel to Build with the Correct Microcode Update File


Woot.. The hard part is done, all we have to do right now is to tell the linux kernel the location of our microcode update file so that it’ll be included in the kernel’s build process.

Fire up your favorite terminal, and run:

cd /usr/src/linux
make menuconfig


Navigate to Device Drivers then to Generic Driver Options.

Now include CONFIG_FIRMWARE_IN_KERNEL,CONFIG_EXTRA_FIRMWARE and CONFIG_EXTRA_FIRMWARE_DIR as shown below:

  [ ] Support for uevent helper
  -∗- Maintain a devtmpfs filesystem to mount at /dev
  [∗]   Automount devtmpfs at /dev, after the kernel mounted the rootfs
  [∗] Select only drivers that don't need compile-time external firmware
  [∗] Prevent firmware from being built
  -∗- Userspace firmware loading support
  [∗]   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
  [ ] Fallback user-helper invocation for firmware loading
  [ ] Allow device coredump
  [ ] Driver Core verbose debug messages
  [ ] Managed device resources verbose debug messages
  [ ] Test driver remove calls during probe (UNSTABLE)
  < > Build kernel module to test asynchronous driver probing
  [ ] Enable verbose DMA_FENCE_TRACE messages


Change:

CONFIG_EXTRA_FIRMWARE to intel-ucode/YOUR_MICROCODE_UPDATE_FILE_NAME

CONFIG_EXTRA_FIRMWARE_DIR to /lib/firmware

Save your configuration file, compile your kernel and reboot. Microcode updates should be working now without using an initrd.


6- Verify that Microcode Updates are Working

This is quite simple, just run:

dmesg | grep microcode
[    0.000000] microcode: microcode updated early to revision 0x22, date = 2017-01-27
[    0.795219] microcode: sig=0x306c3, pf=0x10, revision=0x22
[    0.795433] microcode: Microcode Update Driver: v2.01 <tigran@aivazian.fsnet.co.uk>, Peter Oruba


As you can see, microcode updates are 100% working, final revision 0x22 is being used.


Conclusion

If you followed our previous article Booting the Linux Kernel Without an initrd/initramfs, your boot folder now should only have the kernel inside it, as it contains everything from your modules to your microcode updates!

8 Comments

atbd

03/06/2017


Hello, thank you for your articles, this one particularly! To be sure to not miss one, can you make them available via rss ?

DOTSLASHLINUX

03/06/2017


@atbd, you’re most welcome! RSS feed is now available!

atbd

03/06/2017


By the way, I found a « method » to be sure about microcode signature: * install iucode_tool (available on gentoo, i don’t know for others) * run dmesg | grep microcode & search for signature * run iucode_tool -L /lib/firmware/intel-ucode/ and grep the signature found in your dmesg

DOTSLASHLINUX

03/06/2017


@atbd, I agree that should be the most obvious way to get the signature;however, on some installations the output of “dmesg” may be a lot more that it can be truncated and the microcode part won’t be shown, another thing is that the user may reduce the verbosity of dmesg so the microcode updates won’t be shown.

The user might also be using a custom kernel build and has disabled “early microcode updates support” from his/her kernel.

The point is to get the signature from more than one source to successfully choose your microcode update file. Another way would be to choose all microcode update files and let the kernel pick the right one for you. That might work but still the article was intended to make things easier for the reader.

Thanks for your reply! Your suggestion is much appreciated!

rabbit

27/06/2017


Best article ever! Thank you a lot for your work! Great stuff!!!

DOTSLASHLINUX

27/06/2017


@rabbit, thanks a lot! Your feedback means a lot and it sure motivated me further more to continue writing useful articles. Really glad that you found this one helpful. And I’m proud to say that part of this article was added to the Gentoo wiki.

Joe

07/11/2017


Thanks for this.

But the folder intel-ucode does not exist on Arch Linux after installing the package. It just installs a .img file in /boot which works with initrd only I guess!

Any tips appreciated!

DOTSLASHLINUX

10/11/2017


@Joe, Thanks and I’m sorry to hear that. Arch linux tends to build the microcode update files as an image into the initramfs itself (which is the sane thing to do for a distribution targeting such a large user base). You can still manually download the microcode update files from Intel’s website (a 2-3MB microcode-date.tgz file) and extract it to ‘/lib/firmware’. Make sure that it’s owned by root:root and it has 755 permissions.

Hope that helps! Let me know if you have any more questions!

Leave A Comment