Trying a new kernel and compiling network driver from it

Jun 14, 2023

In celebration of the release of Debian 12, I downloaded and tried it out on a VM (virtual machine). Unfortunately, my network driver won't compile under Linux kernel version 6.1. I thought they were just kidding when they said kernel version <= 5.17. So I held off upgrading my server to Debian 12. A short while back, I read this post about getting i96 board from Orange Pi to work. That got me thinking. Are kernel and OS separated? The board in question could run Debian 11 Bullseye on kernel 3.10, which was very old.

Debian 10

Because I couldn't find the ISO for Debian 11 that is currently on my server to replicate the server environment on a VM, I used Debian 10 ISO. Lucky enough! It came with kernel 4.19. While installing, I tried using a mirror server from Vietnam to speed up downloading packages. It worked! So good that I changed mirrors on my server, my laptop OS to Vietnam to. As previously, I downloaded packages from the sources, which are from the US so they were slow.

I upgraded Debian 10 to 11 by changing all instances of buster in /etc/apt/source.list to bullseye and use apt full-upgrade. Debian 11 gave me kernel 5.10, same as my server. I added the backport repository to the apt source list, because they have new softwares and kernels there:

deb http://debian.xtdv.net/debian/ bullseye-backports main

Next, I searched for a new kernel by filtering apt list:

apt list linux-image* | less

It came up with tons of results so it could get confusing. Fortunately, the kernel the OS used probably looks like linux-image-5.10.0-23-amd64 so using this, I could track down the kernel I need, like linux-image-6.1.0-0.deb11.7-amd64. I did try one with cloud in it, and it shrunk the font on screen. After installing, it would generate a new config file for the boot loader, GRUB. The next restart, it will reboot to the new kernel. And it did. Here was the result of uname -a:

Linux debian 6.1.0-0.deb11.7-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.20-2~bpo11+1 (2023-04-23) x86_64 GNU/Linux

* *

I also tried upgrading to Debian 12 while holding the linux-image-amd64 from upgrading, to see if it was possible to get to Debian 12 without using kernel 6.1. It also worked.

Lubuntu 22.04

I replicated the experiment on a fresh Lubuntu 22.04.2 VM. It was a bit different. The package I was looking for was linux-image-5.15.0-73-generic. The newest kernel they got was linux-image-5.19.0-43-generic so I tried linux-image-6.1.0-1013-oem. It booted back in after installing and restarting the VM.

Compiling driver

Back to Debian 11 with kernel 6.1, I tried compiling driver again after installing linux-headers-6.1.0-0.deb11.7-amd64. It didn't work and it gave errors:

/home/bach/r8152-2.16.3/r8152.c: In function 'sg_en_store':

/home/bach/r8152-2.16.3/r8152.c:20462:2: error: implicit declaration of function 'netif_set_gso_max_size'; did you mean 'netif_set_tso_max_size'? [-Werror=implicit-function-declaration]

20462 | netif_set_gso_max_size(netdev, tso_size);

| ^~~~~~~~~~~~~~~~~~~~~~

| netif_set_tso_max_size

/home/bach/r8152-2.16.3/r8152.c: In function 'rtl8152_probe':

/home/bach/r8152-2.16.3/r8152.c:20704:3: error: too many arguments to function 'netif_napi_add'

20704 | netif_napi_add(netdev, &tp->napi, r8152_poll, 256);

| ^~~~~~~~~~~~~~

In file included from /home/bach/r8152-2.16.3/r8152.c:16:

/usr/src/linux-headers-6.1.0-0.deb11.7-common/include/linux/netdevice.h:2569:1: note: declared here

2569 | netif_napi_add(struct net_device *dev, struct napi_struct *napi,

| ^~~~~~~~~~~~~~

/home/bach/r8152-2.16.3/r8152.c:20706:3: error: too many arguments to function 'netif_napi_add'

20706 | netif_napi_add(netdev, &tp->napi, r8152_poll, 64);

| ^~~~~~~~~~~~~~

In file included from /home/bach/r8152-2.16.3/r8152.c:16:

/usr/src/linux-headers-6.1.0-0.deb11.7-common/include/linux/netdevice.h:2569:1: note: declared here

2569 | netif_napi_add(struct net_device *dev, struct napi_struct *napi,

| ^~~~~~~~~~~~~~

cc1: some warnings being treated as errors

For the first error, I changed the function according to the tip. For the following errors, I consulted the wisdom of the Internet and found this patch, so I changed the function again. I recompiled again and it got through. Using modinfo r8152.ko yielded result that it was compiled using kernel 6.1:

vermagic: 6.1.0-0.deb11.7-amd64 SMP preempt mod_unload modversions

Compiling driver (new version 2.17.1)

After the release of Debian 12, Realtek issued an update on their RTL8156 source driver. I downloaded it and compiled against kernel version 6.1 and installed it. It worked, without any errors from the old version. There was also a driver already in the kernel so I tested both drivers. The in-tree kernel module required firmwares to be installed, you can find it in firmware-realtek package in bullseye-backports repository. However, Debian didn't recognize the network USB, so I have to force driver by hand using this command as root (not sudo, it didn't work):

echo 0bda 8156 > /sys/bus/usb/drivers/r8152/new_id

Then it recognized the USB. By using iperf3, I measured performance between 2 drivers. While they were able to saturate the 1Gbps bandwidth, the in-tree module took 10% more CPU usage compared to the Realtek driver. The in-tree module also required a hacky workaround for the server to recognize, so I opted for the Realtek one.