Building latest Linux kernels
September 11, 2022Recently I bought a new video card that came out only a few months ago, but to use it I required a much newer kernel than what Debian stable provided. These are my notes for how I went about building the latest kernel and installing the latest firmware. It is something that sounds intimidating but is really not hard at all.
Installing local system pre-reqs for compiling
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison dwarves
Downloading the latest kernel
Navigate to https://www.kernel.org/, the latest kernel can be downloaded on the front page as a tarball.
Building the latest kernel
Navigate to the extracted folder of your respective kernel version downloaded.
cd linux-5.19.8
Copy the current kernel configuration from the kernel you’re currently running, to this directory. This is done to save significant effort, as since we know our system is currently running fine with the existing kernel config, the same config likely can be re-used in the new kernel instead of establishing it from scratch.
cp -v /boot/config-$(uname -r) .config
The kernel config file is the instructions to the build process on what to build and what to exclude. If you want to make a slim kernel and were confident in what specific kernel features you require, this file is where those features can be specified as being included and excluded.
Instead of editing this file manually (not a good idea) run make menuconfig
which will allow you to check/uncheck kernel features. The menuconfig has a Help
to learn more about the options. Also be sure to Save
your configuration when done.
Start building the kernel by running make
, as one would typically do when building from source:
make
This will take some time (a couple hours on a modest computer in 2022).
Once completed, install the required modules with:
sudo make modules_install
Finally, install the kernel with the usual make install
:
sudo make install
This will install the linux image and initrd (initial ram disk) into /boot
Updating intiramfs and GRUB bootloader
Update your initramfs
sudo update-initramfs -c -k 5.19.8
From the manpages: the update-initramfs script manages your initramfs images on your local box. It keeps track of the existing initramfs archives in /boot. There are three modes of operation create, update or delete. The initramfs is a gzipped cpio archive. At boot time, the kernel unpacks that archive into RAM disk, mounts and uses it as initial root file system. All finding of the root device happens in this early userspace.
So in the command above, -c flag is creating a new initramfs with -k kernel version 5.19.8
Update the grub bootloader show that your latest kernel is the default (you can still select previous kernels in the boot menu)
sudo update-grub
Install latest firmware
Since you are running the latest kernel now, it is smart to also run the latest firmware which resides in /lib/firmware.
Linux firmware is a package distributed alongside the Linux kernel that contains firmware binary blobs necessary for partial or full functionality of certain hardware devices. These binary blobs are usually proprietary because some hardware manufacturers do not release source code necessary to build the firmware itself. Modern graphics cards from AMD and NVIDIA almost certainly require binary blobs to be loaded for the hardware to operate correctly. (taken from here)
As an aside, note the loading of firmware from /lib/firmware directory is actually a kernel config option.
Device Drivers --->
Generic Driver Options --->
Firmware loader --->
-*- Firmware loading facility
() Build named firmware blobs into the kernel binary
(/lib/firmware) Firmware blobs root directory
The latest linux-firmware can be downloaded as a .tar.gz from https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/
Untar this and copy all the contents to /lib/firmware (of course replacing the below date with the your downloads date)
sudo tar -xvf linux-firmware-20220815.tar.gz -C /lib/firmware/ --overwrite
Linux headers for kernel modules
Generally the linux headers in a apt-managed system are found in /usr/src/linux-headers-xyz-amd64
(and installed separately from the kernel image, with apt install linux-headers-xyz-amd64
)
However since your kernel was custom built, things work a little different. Navigate to /lib/modules/5.19.8
and observe it contains two symbolic links source
and build
which will point to the source file of the kernel you downloaded. Thus it’s important not to delete/remove your kernel source download. Actually all kernels on the local box will have respective directories in /lib/modules
, and contain symbolic links either to /usr/src/linux-headers-xyz-amd64
(if it was installed with apt), or to your custom kernels (for manual kernel builds).
Rescue disks
When dabbling with custom kernels, especially if messing with the config to get a slim kernel, it’s possible to get an unbootable system… for this reason I reccomend having a bootable live distribution so you can mount your drives and repair any problematic files.
I found the slackware live CD (https://download.liveslak.org/) to be of use.
Make bootable ISO from the download….
isohybrid ./slackware64-live-15.0.iso
From the manpages: The isohybrid utility modifies an ISO 9660 image generated with mkisofs, genisoimage, or compatible utilities, to be bootable as a CD-ROM or as a hard disk.
Copy to a USB key (be sure you have the right /dev path by running fdisk -l
first !!!)
sudo dd if=./slackware64-live-15.0.iso of=/dev/sda bs=8192k
(Optional video card stuff)
If you’re like me and went on this custom kernel adventure for a video card, there’s a few useful commands you can run.
Run lspci -k | grep -A 3 -E "(VGA|3D)"
if you want to see which kernel driver your video card is running, and what modules are available for that hardware.
Also you can run sudo lshw -c video
- note if you have *-display UNCLAIMED
this means you have a driver issue (probably not supported). In the case of checking if there is particular driver support for your card (in the case of ATI) you can look at linux-5.19.8/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
and see if your hardware ID is in the source.
You can run hwinfo --pci
and search for your card in the results to get the Vendor and Device hex id’s of the hardware you’re running.
For instance,
Vendor: pci 0x1002 "ATI Technologies Inc"
Device: pci 0x743f
Also if you’re having driver issues do a quick ripgrep in linux-5.19.8/drivers
for your device ID to see if it is mentioned anywhere in the source files.
Additional links
https://developer.ibm.com/articles/l-initrd/
https://wiki.debian.org/initramfs
https://manpages.debian.org/buster/initramfs-tools/update-initramfs.8.en.html