OpenWrt: Add Hello World Kernel Module ======================================== This document explains how to create, build, package, install, and test a simple Hello World Linux kernel module in OpenWrt. It follows the same format as the OpenWrt x86 Build & QEMU Run documentation, including tab-sets, panels, and step-based workflow. In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to prepare directory structure for a kernel module package in OpenWrt? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to write a simple Linux kernel module with init/exit callbacks? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to integrate kernel module Kbuild Makefile into the OpenWrt buildroot? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How OpenWrt compiles kernel modules using the kernel build system? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Step 1: Create Directory Structure ` * :ref:`Step 1.1: Technical Notes ` * :ref:`Step 2: Kernel Module Source File ` * :ref:`Step 2.1: Technical Notes ` * :ref:`Step 3: Kernel Module Sub-Makefile ` * :ref:`Step 3.1: Technical Notes ` * :ref:`Step 4: OpenWrt Package Makefile ` * :ref:`Step 4.1: Technical Notes ` * :ref:`Step 5: Build Kernel Module ` * :ref:`Step 5.1: Technical Notes ` * :ref:`Step 6: Copy to VM ` * :ref:`Step 6.1: Technical Notes ` * :ref:`Step 7: Install on VM ` * :ref:`Step 7.1: Technical Notes ` * :ref:`Step 8: Verify Installed Module ` * :ref:`Step 8.1: Technical Notes ` * :ref:`Step 9: Test Kernel Module ` * :ref:`Step 9.1: Technical Notes ` .. _owrt_kmod_step1: .. _owrt_kmod_step1_1: .. tab-set:: .. tab-item:: Step 1: Create Directory Structure Inside OpenWrt build tree: .. code-block:: bash cd openwrt/package mkdir -p custom-kmod/src Structure: :: package/custom-kmod ├── Makefile └── src ├── Makefile └── custom_kmod.c .. tab-item:: Step 1.1: Technical Notes - ``src/`` contains kernel module source and Kbuild Makefile. - Outer Makefile integrates with OpenWrt. - Files are copied into ``$(PKG_BUILD_DIR)`` before compilation. - Kernel modules must be built using Linux Kbuild infrastructure. .. _owrt_kmod_step2: .. _owrt_kmod_step2_1: .. tab-set:: .. tab-item:: Step 2: Kernel Module Source File ``package/custom-kmod/src/custom_kmod.c`` .. code-block:: c #include #include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ahalya"); MODULE_DESCRIPTION("Simple Hello World Kernel Module"); static int __init custom_kmod_init(void) { pr_info("custom-kmod: Hello from kernel module!\n"); return 0; } static void __exit custom_kmod_exit(void) { pr_info("custom-kmod: Goodbye from kernel module!\n"); } module_init(custom_kmod_init); module_exit(custom_kmod_exit); .. tab-item:: Step 2.1: Technical Notes - ``MODULE_LICENSE("GPL")`` avoids taint warnings. - ``custom_kmod_init`` runs at module load. - ``custom_kmod_exit`` runs at module unload. - ``pr_info`` logs to kernel buffer (``dmesg``). .. _owrt_kmod_step3: .. _owrt_kmod_step3_1: .. tab-set:: .. tab-item:: Step 3: Kernel Module Sub-Makefile ``package/custom-kmod/src/Makefile`` .. code-block:: make obj-m := custom_kmod.o .. tab-item:: Step 3.1: Technical Notes - ``obj-m`` declares a loadable kernel module target. - Kbuild produces ``custom_kmod.ko``. .. _owrt_kmod_step4: .. _owrt_kmod_step4_1: .. tab-set:: .. tab-item:: Step 4: OpenWrt Package Makefile ``package/custom-kmod/Makefile`` .. code-block:: make include $(TOPDIR)/rules.mk PKG_NAME:=custom-kmod PKG_RELEASE:=1 include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/package.mk define KernelPackage/custom-kmod SUBMENU:=Other modules TITLE:=Simple Hello World kernel module FILES:=$(PKG_BUILD_DIR)/custom_kmod.ko AUTOLOAD:=$(call AutoLoad,50,custom_kmod) endef define KernelPackage/custom-kmod/description A basic kernel module that prints messages during load/unload. endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef define Build/Compile $(MAKE) -C "$(LINUX_DIR)" \ M="$(PKG_BUILD_DIR)" \ modules endef $(eval $(call KernelPackage,custom-kmod)) .. tab-item:: Step 4.1: Technical Notes - ``kernel.mk`` provides kernel integration helpers. - ``FILES`` selects artifacts to include in package. - ``AUTOLOAD`` generates an autoload entry. - ``Build/Compile`` invokes Kbuild under ``LINUX_DIR``. .. _owrt_kmod_step5: .. _owrt_kmod_step5_1: .. tab-set:: .. tab-item:: Step 5: Build Kernel Module Build: .. code-block:: bash make package/custom-kmod/{clean,compile} V=s Output: :: bin/targets/x86/64/packages/kmod-custom-kmod*.apk .. tab-item:: Step 5.1: Technical Notes - ``clean`` resets the package build directory. - ``compile`` triggers Prepare + Compile phases. - Output naming uses kernel ABI string. .. _owrt_kmod_step6: .. _owrt_kmod_step6_1: .. tab-set:: .. tab-item:: Step 6: Copy to VM .. code-block:: bash scp -P 2223 bin/targets/x86/64/packages/kmod-custom-kmod*.apk root@127.0.0.1:/tmp/ .. tab-item:: Step 6.1: Technical Notes - ``/tmp`` is writable (tmpfs). - Works for QEMU or hardware devices. .. _owrt_kmod_step7: .. _owrt_kmod_step7_1: .. tab-set:: .. tab-item:: Step 7: Install on VM .. code-block:: bash apk add --allow-untrusted /tmp/kmod-custom-kmod*.apk .. tab-item:: Step 7.1: Technical Notes - Installs ``custom_kmod.ko`` into module directory. - Autoload entry created via ``AUTOLOAD`` directive. .. _owrt_kmod_step8: .. _owrt_kmod_step8_1: .. tab-set:: .. tab-item:: Step 8: Verify Installed Module .. code-block:: bash ls /lib/modules/*/ | grep custom_kmod Expected: :: custom_kmod.ko .. tab-item:: Step 8.1: Technical Notes - Confirms file presence, not loaded state. - Use ``lsmod`` to check load status. .. _owrt_kmod_step9: .. _owrt_kmod_step9_1: .. tab-set:: .. tab-item:: Step 9: Test Kernel Module **Load module** .. code-block:: bash insmod custom_kmod.ko Check logs: .. code-block:: bash dmesg | tail Expected: :: custom-kmod: Hello from kernel module! **Unload module** .. code-block:: bash rmmod custom_kmod .. code-block:: bash dmesg | tail Expected: :: custom-kmod: Goodbye from kernel module! .. tab-item:: Step 9.1: Technical Notes - ``insmod`` directly loads module file. - ``rmmod`` unloads and triggers exit callback. - Failures often indicate module still in use.