Automagically build load modules when updating the kernel

I bought a new wireless network card to my parents, and it turned out that there wasn’t support in the generic Ubuntu kernel for it. The last month they haven’t been able to use their computer since the card stopped working after updating the kernel, and hence missing the custom built load module.

After rebuilding the load module I was following the output when installing about 200 updates and saw that after updating the kernel there were some scripts from /etc/kernel/postinst.d running.

I then realized that it should be possible to solve the problem by adding a custom script that would rebuild the load module when updating the kernel.

Step 1 was to create a script in both /etc/kernel/postinst.d and /etc/kernel/header_postinst.d that I named build_wifi_driver:

#!/bin/bash
# We're passed the version of the kernel being installed
inst_kern=$1

cd /root/DPO_RT3070_LinuxSTA_V2.3.0.4_20100604/
make KERNEL_VERSION=$inst_kern
make KERNEL_VERSION=$inst_kern install

The second problem was that the Makefiles for the load module had to be updated to use $(KERNEL_VERSION) instead of $(shell uname -r). I had to update three different Makefiles:

DPO_RT3070_LinuxSTA_V2.3.0.4_20100604/Makefile:

--- DPO_RT3070_LinuxSTA_V2.3.0.4_20100604/Makefile    2009-12-28 13:38:34.000000000 +0100
+++ DPO_RT3070_LinuxSTA_V2.3.0.4_20100604.new/Makefile    2011-01-05 19:17:14.000000000 +0100
@@ -117,11 +117,14 @@
endif

ifeq ($(PLATFORM),PC)
+ifndef KERNEL_VERSION
+    KERNEL_VERSION := $(shell uname -r)
+endif
# Linux 2.6
-LINUX_SRC = /lib/modules/$(shell uname -r)/build
+LINUX_SRC = /lib/modules/$(KERNEL_VERSION)/build
# Linux 2.4 Change to your local setting
#LINUX_SRC = /usr/src/linux-2.4
-LINUX_SRC_MODULE = /lib/modules/$(shell uname -r)/kernel/drivers/net/wireless/
+LINUX_SRC_MODULE = /lib/modules/$(KERNEL_VERSION)/kernel/drivers/net/wireless/
CROSS_COMPILE =
endif

@@ -234,7 +237,7 @@
endif

cp -f os/linux/Makefile.4 $(RT28xx_DIR)/os/linux/Makefile
-    $(MAKE) -C $(RT28xx_DIR)/os/linux/
+    $(MAKE) KERNEL_VERSION=$(KERNEL_VERSION)-C $(RT28xx_DIR)/os/linux/

ifeq ($(OSABL),YES)
cp -f os/linux/Makefile.4.netif $(RT28xx_DIR)/os/linux/Makefile
@@ -279,7 +282,7 @@
ifeq ($(PLATFORM),FREESCALE8377)
$(MAKE) ARCH=powerpc CROSS_COMPILE=$(CROSS_COMPILE) -C  $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules
else
-    $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules
+    $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux KERNEL_VERSION=$(KERNEL_VERSION) modules
endif
endif

DPO_RT3070_LinuxSTA_V2.3.0.4_20100604/os/linux/Makefile.4

--- DPO_RT3070_LinuxSTA_V2.3.0.4_20100604/os/linux/Makefile.4    2009-12-30 02:12:06.000000000 +0100
+++ DPO_RT3070_LinuxSTA_V2.3.0.4_20100604.new/os/linux/Makefile.4    2011-01-05 19:01:56.000000000 +0100
@@ -13,6 +13,9 @@

OBJ := $(MOD_NAME).o

+ifndef KERNEL_VERSION
+KERNEL_VERSION := $(shell uname -r)
+endif

#ifdef CONFIG_STA_SUPPORT
RT28XX_STA_OBJ := \
@@ -200,9 +203,9 @@
cp $(RT28xx_DIR)/$(DAT_FILE_NAME) $(DAT_PATH)/.
install -d $(LINUX_SRC_MODULE)
install -m 644 -c $(addsuffix .o,$(MOD_NAME)) $(LINUX_SRC_MODULE)
-    /sbin/depmod -a ${shell uname -r}
+    /sbin/depmod -a $(KERNEL_VERSION)

uninstall:
#    rm -rf $(DAT_PATH)
rm -rf $(addprefix $(LINUX_SRC_MODULE),$(addsuffix .o,$(MOD_NAME)))
-    /sbin/depmod -a ${shell uname -r}
+    /sbin/depmod -a $(KERNEL_VERSION)

DPO_RT3070_LinuxSTA_V2.3.0.4_20100604/os/linux/Makefile.6

--- DPO_RT3070_LinuxSTA_V2.3.0.4_20100604/os/linux/Makefile.6    2009-12-30 02:12:13.000000000 +0100
+++ DPO_RT3070_LinuxSTA_V2.3.0.4_20100604.new/os/linux/Makefile.6    2011-01-05 19:02:29.000000000 +0100
@@ -12,6 +12,10 @@

obj-m := $(MOD_NAME).o

+ifndef KERNEL_VERSION
+KERNEL_VERSION := $(shell uname -r)
+endif
+

#ifdef CONFIG_STA_SUPPORT
rt$(CHIPSET)sta-objs := \
@@ -198,9 +202,9 @@
cp $(RT28xx_DIR)/$(DAT_FILE_NAME) $(DAT_PATH)/.
install -d $(LINUX_SRC_MODULE)
install -m 644 -c $(addsuffix .ko,$(MOD_NAME)) $(LINUX_SRC_MODULE)
-    /sbin/depmod -a ${shell uname -r}
+    /sbin/depmod -a $(KERNEL_VERSION)

uninstall:
#    rm -rf $(DAT_PATH)
rm -rf $(addprefix $(LINUX_SRC_MODULE),$(addsuffix .ko,$(MOD_NAME)))
-    /sbin/depmod -a ${shell uname -r}
+    /sbin/depmod -a $(KERNEL_VERSION)

I’m no expert when it comes to Makefiles, but these changes solved the issue and the load module now builds automagically every time the kernel was updated.