Gentoo Linux: Building/rebuilding a kernel and Intel CPU microcode in an installation without initramfs
October 26, 2021 Leave a comment
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 [...]