Building Intel CPU Microcode Updates Directly into the Linux Kernel

By Firas Khalil Khana on 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 :


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.


  [ ] 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




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 <>, Peter Oruba

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


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!




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



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



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



@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!



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



@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.

Leave A Comment

Become a Patron

To help keep DOTSLASHLINUX up and running and ads free, kindly consider supporting it on Patreon.

Thanks a lot for your support!


Recommended Distros

Gentoo Linux Void Linux Arch Linux

Upcoming Articles

  • Best QEMU and KVM Configuration for Windows Guests on Linux Hosts


Apart from the comments' section, if you wanted to see an article on how to configure a certain application for a GNU/Linux distro, or wanted to share one (perhaps one that you've written), feel free to send me an email on: