Gentoo Linux: Building/rebuilding a kernel and Intel CPU microcode in an installation without initramfs

In a 2016 post I explained how to update the Intel CPU microcode in a Gentoo Linux Stable Branch installation without an initramfs (I do not use sys-kernel/genkernel to build the kernel in the installation on my Clevo W230SS laptop). The behaviour of the tool sys-apps/iucode_tool for updating the Intel CPU microcode has changed since that post, hence this update.

Although not essential I normally perform the microcode upgrade procedure when I either rebuild or upgrade the Linux kernel, therefore I explain both procedures contiguously here.

These days the grub-mkconfig command edits the file /boot/grub/grub.cfg to add a line to the GRUB menu entries, to load the CPU microcode at boot, but nevertheless I prefer to follow a slightly different method that works reliably for me.

Below is the procedure I follow to build/rebuild the kernel and the Intel CPU microcode. Others may have a different approach, but this has always worked well for me, even if some of the steps are sometimes nugatory.

1. Mount the boot directory if it is on a separate partition

root # mount /dev/sda1 /boot

2. Check which kernel sources are installed and which of those sources is currently selected

root # eselect kernel list

3. Make a back-up of the current kernel configuration file

root # cp /usr/src/linux-`uname -r`/.config /home/fitzcarraldo/kernel-config-`uname -r`

4. Select the kernel sources I want to build

root # eselect kernel set <n>

5. Change to the currently selected kernel sources directory

root # cd /usr/src/linux

6. If wanting to build a new version of the kernel, create a template configuration file

N.B. Do NOT do this if rebuilding the kernel version that is currently in use.

root # cp /usr/src/linux-`uname -r`/.config /usr/src/linux/.config

7. Remove any existing object files

Definitely needed if the ‘make‘ command (see further on) returns an error message mentioning an old version of the compiler. It does no harm to perform this step in any case, so I always do it.

root # make clean

8. If building a new version of the kernel, create a new configuration file

N.B. Do NOT do this if rebuilding the kernel version that is currently in use.

root # make olddefconfig

The command ‘make olddefconfig‘ will edit the existing /usr/src/linux/.config file, keeping all the existing options in the file and setting any new options to their recommended (i.e. default) values.

9. Display a TUI menu of the kernel options in the .config file and make any desired changes

root # make menuconfig

I have configured the following kernel options relating to the early loading of the Intel CPU microcode (see later):

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

10. Build the kernel and modules

root # make && make modules_install
root # make install

11. Rebuild any third-party packages containing kernel modules

These could include packages such as nvidia-drivers, for example.

root # emerge @module-rebuild

In my case, currently the @module-rebuild set only comprises the following two packages:

root # cat /var/lib/module-rebuild/moduledb
a:1:app-emulation/virtualbox-modules-6.1.24
a:1:x11-drivers/nvidia-drivers-470.63.01

12. Rebuild the X Windows Server and X Windows drivers

I always do this even though not always necessary. One less thing to think about (not rebuilding them has sometimes caused me problems).

root # emerge xorg-server xorg-drivers

13. Rebuild NetworkManager if it is installed

I always do this even though not always necessary. One less thing to think about (not rebuilding it has sometimes caused me problems).

root # emerge networkmanager

14. If there is a new version of the Intel CPU microcode, generate it and copy it to the boot directory

Updates to the package sys-firmware/intel-microcode in the last couple of years have not resulted in a change to the version of Intel CPU microcode for the fourth-generation Intel Core i7-4810MQ CPU in my Clevo W230SS laptop, so I assume Intel no longer supports that version of CPU. Nevertheless it does no harm to repeat the procedure.

root # rm /boot/microcode.cpio
root # iucode_tool -S --write-earlyfw=/boot/microcode.cpio /lib/firmware/intel-ucode/*
root # rm /boot/intel-uc.img

(The third command is to stop the grub-mkconfig command (see later) adding intel-uc.img to the initrd line in the grub.cfg file.)

15. If a different version of the kernel has just been built, or if this is the first time upgrading the CPU microcode, create a new grub.cfg file

15.1 First check the contents of /etc/default/grub to make sure it will be OK for the new version of the kernel

root # nano /etc/default/grub

Modify the contents of /etc/default/grub if necessary for the kernel that has just been built.

15.2 Generate a new grub.cfg file

root # grub-mkconfig -o /boot/grub/grub.cfg

15.3 Check the new grub.cfg file includes the loading of the CPU microcode

root # nano /boot/grub/grub.cfg

The last line for each menu entry (i.e. the line before the closing curly bracket of the menu entry) should contain only ‘initrd /microcode.cpio‘, as shown in the example file excerpt below:

[...]
### 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 5.10.61-gentoo ...'
linux	/vmlinuz-5.10.61-gentoo root=/dev/sda5 ro  locale=en_GB i965.modeset=1 rcutree.rcu_idle_gp_delay=1 acpi_enforce_resources=lax reboot=force raid=noautodetect resume=/dev/sda2
echo	'Loading initial ramdisk ...'
initrd	/microcode.cpio
}
submenu 'Advanced options for Gentoo GNU/Linux' $menuentry_id_option 'gnulinux-advanced-525a90f1-8ad2-44a3-ade3-20f18a0a9595' {
menuentry 'Gentoo GNU/Linux, with Linux 5.10.61-gentoo' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.10.61-gentoo-advanced-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 5.10.61-gentoo ...'
linux	/vmlinuz-5.10.61-gentoo root=/dev/sda5 ro  locale=en_GB i965.modeset=1 rcutree.rcu_idle_gp_delay=1 acpi_enforce_resources=lax reboot=force raid=noautodetect resume=/dev/sda2
echo	'Loading initial ramdisk ...'
initrd	/microcode.cpio
}
menuentry 'Gentoo GNU/Linux, with Linux 5.10.61-gentoo (recovery mode)' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.10.61-gentoo-recovery-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 5.10.61-gentoo ...'
linux	/vmlinuz-5.10.61-gentoo root=/dev/sda5 ro single
echo	'Loading initial ramdisk ...'
initrd	/microcode.cpio
}
}

### END /etc/grub.d/10_linux ###
[...]

16. Reboot

17. Rebuild VirtualBox if it is installed

root # emerge virtualbox

18. Check the current version of the Intel CPU microcode

Either:

root # dmesg | grep microcode

or:

root # grep microcode /proc/cpuinfo

For example:

root # dmesg | grep microcode
[    0.000000] microcode: microcode updated early to revision 0x28, date = 2019-11-12
[    0.335631] microcode: sig=0x306c3, pf=0x10, revision=0x28
[    0.335730] microcode: Microcode Update Driver: v2.2.
root # grep microcode /proc/cpuinfo
microcode       : 0x28
microcode       : 0x28
microcode       : 0x28
microcode       : 0x28
microcode       : 0x28
microcode       : 0x28
microcode       : 0x28
microcode       : 0x28

19. Edit /var/lib/portage/world and add (or change) the specific kernel sources package version

I do this in order to ensure the command ‘emerge --depclean‘ does not remove a specific kernel’s source code during a world update. I want Portage always to install the latest (stable) version of gentoo-sources but not to delete the version of gentoo-sources that corresponds to the kernel my installation is currently using.

For example, let’s say I have just replaced a kernel built from gentoo-sources:4.19.57 with a kernel built from gentoo-sources:4.19.66. My world file would initially contain the following:

[...]
sys-kernel/gentoo-sources
sys-kernel/gentoo-sources:4.19.57
[...]

If, following a successful reboot with kernel 4.19.66, I want to delete the files for kernel 4.19.17 in /boot/ (System.map-4.19.17-gentoo, config-4.19.17-gentoo and vmlinuz-4.19.17-gentoo) and to edit the file /boot/grub/grub.cfg to remove the menu entries for kernel 4.19.57, I would change the world file’s contents to:

[...]
sys-kernel/gentoo-sources
sys-kernel/gentoo-sources:4.19.66
[...]

On the other hand, if, following a successful reboot, I want to keep the files for both kernel 4.19.17 and kernel 4.19.66, I would change the world file’s contents to:

[...]
sys-kernel/gentoo-sources
sys-kernel/gentoo-sources:4.19.57
sys-kernel/gentoo-sources:4.19.66
[...]

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

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.