Gentoo Linux installations without initramfs: Updating Intel CPU microcode

This post explains how I configured the Gentoo Linux (amd64) installation on my Clevo W230SS laptop to make it update the Intel CPU microcode using the kernel Microcode Early Update driver.

Back in April I installed Gentoo Linux Stable and built the kernel using the default manual configuration steps given in the Gentoo Handbook, and my installation therefore did not use an initramfs. The contents of the /boot directory were as listed below:

# ls -1 /boot
System.map-3.18.11-gentoo
config-3.18.11-gentoo
grub
lost+found
vmlinuz-3.18.11-gentoo

Contrast the above with the boot directory of the Gentoo Linux Testing (~amd64) installation on my Compal NBLB2 laptop, which does use an initramfs because I built the kernel using the optional genkernel utility:

# ls -1 /boot
System.map-genkernel-x86_64-3.18.11-gentoo
boot
grub
initramfs-genkernel-x86_64-3.18.11-gentoo
kernel-genkernel-x86_64-3.18.11-gentoo
lost+found

Since I wrote my earlier post on updating CPU microcode, the use of a kernel module and initscript to update CPU microcode has been dropped (in Gentoo Linux, at least). This is because updating CPU microcode relatively late in the boot process may cause problems if some processes have started before the update has taken place. The only safe way to update CPU microcode is to use the kernel’s built-in Microcode Early Update driver (METHOD 2 in my earlier post).

Now, new versions of the relevant Gentoo Linux ebuilds (microcode-ctl-1.28-r1, microcode-data-20150121-r1 and iucode_tool-1.3) have recently been released (see Gentoo Bug Report No. 528712). If a Gentoo Linux installation does not use an initramfs, the microcode-data ebuild now includes an ‘initramfs‘ USE flag which you can set in order to create a minimal initramfs to load the CPU microcode at boot. Below I explain in detail how I configured my installation to update the CPU microcode early during boot.

Before doing anything at all, I checked the microcode version for my CPU (Intel Core i7-4810MQ @ 2.80GHz):

# grep microcode /proc/cpuinfo
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
# dmesg | grep microcode
[    0.262544] microcode: CPU0 sig=0x306c3, pf=0x10, revision=0x12
[    0.262641] microcode: CPU1 sig=0x306c3, pf=0x10, revision=0x12
[    0.262740] microcode: CPU2 sig=0x306c3, pf=0x10, revision=0x12
[    0.262841] microcode: CPU3 sig=0x306c3, pf=0x10, revision=0x12
[    0.262939] microcode: CPU4 sig=0x306c3, pf=0x10, revision=0x12
[    0.263038] microcode: CPU5 sig=0x306c3, pf=0x10, revision=0x12
[    0.263138] microcode: CPU6 sig=0x306c3, pf=0x10, revision=0x12
[    0.263236] microcode: CPU7 sig=0x306c3, pf=0x10, revision=0x12
[    0.263367] microcode: Microcode Update Driver: v2.00 , Peter Oruba

Fortunately I did not need to rebuild the kernel as I had already configured it back in April when I installed Gentoo, with a view to implementing early microcode updating at some point:

# grep CONFIG_BLK_DEV_INITRD /usr/src/linux/.config
CONFIG_BLK_DEV_INITRD=y
# grep CONFIG_MICROCODE /usr/src/linux/.config
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_MICROCODE_INTEL_EARLY=y
# CONFIG_MICROCODE_AMD_EARLY is not set
CONFIG_MICROCODE_EARLY=y
# grep CONFIG_INITRAMFS_SOURCE /usr/src/linux/.config
CONFIG_INITRAMFS_SOURCE=""

Then I set the initramfs USE flag and unmasked the ~amd64 ebuilds created by Gentoo developer SpanKY (microcode-ctl-1.28-r1.ebuild, microcode-data-20150121-r1.ebuild and iucode_tool-1.3.ebuild) as discussed in the above-mentioned Gentoo bug report:

# cat /etc/portage/package.use/microcode-data
sys-apps/microcode-data initramfs
# cat /etc/portage/package.accept_keywords/microcode-data
sys-apps/microcode-data ~amd64
sys-apps/iucode_tool ~amd64
# cat /etc/portage/package.accept_keywords/microcode-ctl
sys-apps/microcode-ctl ~amd64

Then I merged the packages:

# emerge --ask microcode-ctl microcode-data

This resulted in the following files:

# ls -la /lib/firmware/microcode.cpio
-rw-r--r-- 1 root root 663552 Aug 26 15:06 /lib/firmware/microcode.cpio
# ls -la /lib/firmware/intel-ucode
total 768
drwxr-xr-x  2 root root  4096 Aug 26 15:06 .
drwxr-xr-x 62 root root 16384 Aug 26 15:06 ..
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-03-02
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-05-00
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-05-01
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-05-02
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-05-03
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-06-00
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-06-05
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-06-0a
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-06-0d
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-07-01
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-07-02
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-07-03
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-08-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-08-03
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-08-06
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-08-0a
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-09-05
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-0a-00
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-0a-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0b-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0b-04
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-0d-06
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0e-08
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-0e-0c
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-0f-02
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-0f-06
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-0f-07
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0f-0a
-rw-r--r--  1 root root 28672 Aug 26 15:06 06-0f-0b
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-0f-0d
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-16-01
-rw-r--r--  1 root root 20480 Aug 26 15:06 06-17-06
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-17-07
-rw-r--r--  1 root root 24576 Aug 26 15:06 06-17-0a
-rw-r--r--  1 root root 14336 Aug 26 15:06 06-1a-04
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-1a-05
-rw-r--r--  1 root root 15360 Aug 26 15:06 06-1c-02
-rw-r--r--  1 root root 20480 Aug 26 15:06 06-1c-0a
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-1d-01
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-1e-04
-rw-r--r--  1 root root  7168 Aug 26 15:06 06-1e-05
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-25-02
-rw-r--r--  1 root root  3072 Aug 26 15:06 06-25-05
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-26-01
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-2a-07
-rw-r--r--  1 root root 16384 Aug 26 15:06 06-2d-06
-rw-r--r--  1 root root 17408 Aug 26 15:06 06-2d-07
-rw-r--r--  1 root root 13312 Aug 26 15:06 06-2f-02
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-3a-09
-rw-r--r--  1 root root 21504 Aug 26 15:06 06-3c-03
-rw-r--r--  1 root root 14336 Aug 26 15:06 06-3d-04
-rw-r--r--  1 root root 13312 Aug 26 15:06 06-3e-04
-rw-r--r--  1 root root 11264 Aug 26 15:06 06-3e-06
-rw-r--r--  1 root root 15360 Aug 26 15:06 06-3e-07
-rw-r--r--  1 root root 28672 Aug 26 15:06 06-3f-02
-rw-r--r--  1 root root 20480 Aug 26 15:06 06-45-01
-rw-r--r--  1 root root 23552 Aug 26 15:06 06-46-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 0f-00-07
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-00-0a
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-01-02
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-02-04
-rw-r--r--  1 root root  8192 Aug 26 15:06 0f-02-05
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-02-06
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-02-07
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-02-09
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-03-02
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-03-03
-rw-r--r--  1 root root  7168 Aug 26 15:06 0f-03-04
-rw-r--r--  1 root root 10240 Aug 26 15:06 0f-04-01
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-04-03
-rw-r--r--  1 root root  3072 Aug 26 15:06 0f-04-04
-rw-r--r--  1 root root  3072 Aug 26 15:06 0f-04-07
-rw-r--r--  1 root root  9216 Aug 26 15:06 0f-04-08
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-04-09
-rw-r--r--  1 root root  4096 Aug 26 15:06 0f-04-0a
-rw-r--r--  1 root root  3072 Aug 26 15:06 0f-06-02
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-06-04
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-06-05
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-06-08

(By the way, the file 06-3c-03 is the microcode file for my particular CPU: Family 06h, Model 03Ch, Stepping 03h, as determined from the CPU World Web site.)

Then I copied to the boot directory the cpio file created when I merged the packages:

# cp /lib/firmware/microcode.cpio /boot/

Then I added an initrd line to /boot/grub/grub.cfg as shown below:

# grep -B 15 -A 1 initrd /boot/grub/grub.cfg

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Gentoo GNU/Linux' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-525a90f1-8ad2-44a3-ade3-20f18a0a9595' {
        load_video
        insmod gzio
        insmod part_msdos
        insmod ext2
        set root='hd0,msdos1'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  f6ffc085-66fe-4bbe-b080-cec355749f85
        else
          search --no-floppy --fs-uuid --set=root f6ffc085-66fe-4bbe-b080-cec355749f85
        fi
        echo    'Loading Linux 3.18.11-gentoo ...'
        linux   /vmlinuz-3.18.11-gentoo root=/dev/sda5 ro  drm_kms_helper.edid_firmware=edid/1920x1080_Clevo_W230SS.bin i915.modeset=1 rcutree.rcu_idle_gp_delay=1
        initrd /microcode.cpio
}

After rebooting:

# grep microcode /proc/cpuinfo
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
# dmesg | grep microcode
[    0.000000] CPU0 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.049968] CPU1 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.065070] CPU2 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.080101] CPU3 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.268736] microcode: CPU0 sig=0x306c3, pf=0x10, revision=0x1c
[    0.268838] microcode: CPU1 sig=0x306c3, pf=0x10, revision=0x1c
[    0.268935] microcode: CPU2 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269034] microcode: CPU3 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269131] microcode: CPU4 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269230] microcode: CPU5 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269329] microcode: CPU6 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269448] microcode: CPU7 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269570] microcode: Microcode Update Driver: v2.00 , Peter Oruba

As you can see above, the microcode early update kernel driver updates the microcode version to 0x1c at boot (cf. 0x12 originally). If you have a different model of CPU to mine, of course the version in your case could be different.

Note that the line ‘initrd /lib/firmware/microcode.cpio‘ in the file grub.cfg does not work for me. It has to be ‘initrd /microcode.cpio‘ and the file microcode.cpio has to be in the /boot directory:

# ls /boot
System.map-3.18.11-gentoo  config-3.18.11-gentoo  grub  lost+found  microcode.cpio  vmlinuz-3.18.11-gentoo

Note also that the precise steps specified in Comment #41 of Gentoo Bug Report No. 528712 do not work for me and others (see Gentoo Forums thread microcode-data-20150121-r1 with USE=initramfs: kernel panic). If I build the kernel with CONFIG_INITRAMFS_SOURCE="/lib/firmware/microcode.cpio", delete the line ‘initrd /microcode‘ from grub.cfg, delete the file /boot/microcode.cpio and reboot, the kernel panics and the last two console lines are as follows:

[    3.142079] drm_kms_helper: panic occurred, switching back to text console
[    3.142879] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,5)

Unless Gentoo developer SpanKY explains how he managed to get the procedure he gave in Comment #41 of Gentoo Bug Report No. 528712 to work, it seems the normal behaviour when applying the steps he gave would be for the kernel to panic. Even Gentoo developer Daniel Pielmeier experienced a kernel panic when he applied SpanKY‘s steps (Comment #54 of Gentoo Bug Report No. 528712).

As the procedure I gave above works fine, I therefore reverted to using CONFIG_INITRAMFS_SOURCE="", copying /lib/firmware/microcode.cpio to /boot/microcode.cpio again and re-adding the line ‘initrd /microcode.cpio‘ in the file grub.cfg. However, if you did not have an initramfs and were able to get the precise procedure given in Comment #41 of Gentoo Bug Report #528712 to work, please post a comment here.

About Fitzcarraldo
A Linux user with an interest in all things technical.

2 Responses to Gentoo Linux installations without initramfs: Updating Intel CPU microcode

  1. Pingback: Updating Intel CPU microcode from Gentoo Linux | Fitzcarraldo's Blog

  2. Pingback: Gentoo Linux installations without initramfs: Updating Intel CPU microcode revisited | Fitzcarraldo's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: