OpenWrt: Adding Patches to a Kernel Module ========================================================== This document explains how to apply patches to a Linux kernel module inside the OpenWrt build system, compile it using Kbuild, package it as a ``kmod-kernel-hello-world`` module, install it on an OpenWrt image (e.g., QEMU), and test the patched behavior. In this section, you are going to learn: .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to organize and structure a patched OpenWrt kernel module? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to patch kernel module source files using OpenWrt’s Build/Patch system? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to compile a kernel module using Kbuild inside OpenWrt? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to package and install a patched kernel module in OpenWrt? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to test kernel module load/unload behavior after patching? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section: * :ref:`Step 1: Directory Layout ` * :ref:`Step 1.1: Technical Notes ` * :ref:`Step 2: Kernel Module Source File ` * :ref:`Step 2.1: Technical Notes ` * :ref:`Step 3: Kbuild Makefile ` * :ref:`Step 3.1: Technical Notes ` * :ref:`Step 4: Patch File ` * :ref:`Step 4.1: Technical Notes ` * :ref:`Step 5: OpenWrt Kernel Package Makefile ` * :ref:`Step 5.1: Technical Notes ` * :ref:`Step 6: Build Kernel Module ` * :ref:`Step 6.1: Technical Notes ` * :ref:`Step 7: Copy to VM ` * :ref:`Step 7.1: Technical Notes ` * :ref:`Step 8: Install ` * :ref:`Step 8.1: Technical Notes ` * :ref:`Step 9: Test Patched Kernel Module ` * :ref:`Step 9.1: Technical Notes ` .. _owrt_khmod_step1: .. _owrt_khmod_step1_1: .. tab-set:: .. tab-item:: Step 1: Directory Layout :: package/my/kernel-hello-world/ ├── Makefile ├── patches/ │ └── 0001-change-printk.patch └── src/ ├── hello_world.c └── Makefile .. tab-item:: Step 1.1: Technical Notes - ``patches/`` stores patch files applied during Build/Prepare. - ``src/`` contains kernel module source and Kbuild Makefile. - Top-level ``Makefile`` defines OpenWrt kernel package. - Patch application occurs inside ``$(PKG_BUILD_DIR)``. .. _owrt_khmod_step2: .. _owrt_khmod_step2_1: .. tab-set:: .. tab-item:: Step 2: Kernel Module Source File ``src/hello_world.c`` .. code-block:: c #include #include #include static int __init hello_world_init(void) { pr_info("hello_world: loaded (base message)\n"); return 0; } static void __exit hello_world_exit(void) { pr_info("hello_world: unloaded (goodbye)\n"); } module_init(hello_world_init); module_exit(hello_world_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("you"); MODULE_DESCRIPTION("Minimal Hello-style kernel module (hello_world)"); .. tab-item:: Step 2.1: Technical Notes - ``hello_world_init`` runs at module load. - ``hello_world_exit`` runs at unload. - ``pr_info`` logs to kernel buffer via ``dmesg``. - Minimal code suitable for patch demo. .. _owrt_khmod_step3: .. _owrt_khmod_step3_1: .. tab-set:: .. tab-item:: Step 3: Kbuild Makefile ``src/Makefile`` .. code-block:: make obj-m += hello_world.o .. tab-item:: Step 3.1: Technical Notes - Kbuild builds ``hello_world.ko``. - Kernel build invocation: :: $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules .. _owrt_khmod_step4: .. _owrt_khmod_step4_1: .. tab-set:: .. tab-item:: Step 4: Patch File ``patches/0001-change-printk.patch`` .. code-block:: diff --- a/hello_world.c +++ b/hello_world.c @@ -6,7 +6,7 @@ static int __init hello_world_init(void) { - pr_info("hello_world: loaded (base message)\n"); + pr_info("hello_world: loaded — patched message from OpenWrt package\n"); return 0; } .. tab-item:: Step 4.1: Technical Notes - Patch modifies printed message. - Applied automatically via ``Build/Patch``. - Same flow as userland patching. .. _owrt_khmod_step5: .. _owrt_khmod_step5_1: .. tab-set:: .. tab-item:: Step 5: Kernel Package Makefile ``package/kernel-hello-world/Makefile`` .. code-block:: make include $(TOPDIR)/rules.mk PKG_NAME:=kernel-hello-world PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/package.mk define KernelPackage/kernel-hello-world SUBMENU:=Other modules TITLE:=Minimal hello-style kernel module (hello_world) FILES:=$(PKG_BUILD_DIR)/hello_world.ko AUTOLOAD:=$(call AutoLoad,50,hello_world) endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ $(call Build/Patch,$(PKG_BUILD_DIR)) endef define Build/Compile $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules endef define KernelPackage/kernel-hello-world/install $(INSTALL_DIR) $(1)/lib/modules $(INSTALL_BIN) $(PKG_BUILD_DIR)/hello_world.ko $(1)/lib/modules/ endef $(eval $(call KernelPackage,kernel-hello-world)) .. tab-item:: Step 5.1: Technical Notes - ``kernel.mk`` provides kernel build logic. - ``AUTOLOAD`` creates autoload entry. - ``Build/Prepare`` copies + patches. - ``Build/Compile`` invokes Kbuild. .. _owrt_khmod_step6: .. _owrt_khmod_step6_1: .. tab-set:: .. tab-item:: Step 6: Build Kernel Module Build: .. code-block:: bash make package/my/kernel-hello-world/compile V=s Output: :: bin/targets/x86/64/packages/kmod-kernel-hello-world*.apk .. tab-item:: Step 6.1: Technical Notes - ``V=s`` gives verbose logs. - Output name includes kernel ABI. .. _owrt_khmod_step7: .. _owrt_khmod_step7_1: .. tab-set:: .. tab-item:: Step 7: Copy to VM .. code-block:: bash scp -P bin/targets/x86/64/packages/kmod-kernel-hello-world*.apk \ root@127.0.0.1:/tmp/ .. tab-item:: Step 7.1: Technical Notes - ``/tmp`` is writable. - ```` depends on hostfwd configuration. .. _owrt_khmod_step8: .. _owrt_khmod_step8_1: .. tab-set:: .. tab-item:: Step 8: Install .. code-block:: bash apk add --allow-untrusted /tmp/kmod-kernel-hello-world*.apk .. tab-item:: Step 8.1: Technical Notes - Installs module under ``/lib/modules//``. - ``AUTOLOAD`` adds autoload entry. - ``--allow-untrusted`` needed for local builds. .. _owrt_khmod_step9: .. _owrt_khmod_step9_1: .. tab-set:: .. tab-item:: Step 9: Test Patched Kernel Module Load module: .. code-block:: bash modprobe hello_world View kernel log: .. code-block:: bash dmesg | tail -20 Expected: :: hello_world: loaded — patched message from OpenWrt package .. tab-item:: Step 9.1: Technical Notes - ``modprobe`` resolves module path automatically. - Patched log confirms patch + build correctness.