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

How to prepare directory structure for a kernel module package in OpenWrt?

How to write a simple Linux kernel module with init/exit callbacks?

How to integrate kernel module Kbuild Makefile into the OpenWrt buildroot?

How OpenWrt compiles kernel modules using the kernel build system?

Inside OpenWrt build tree:

cd openwrt/package
mkdir -p custom-kmod/src

Structure:

package/custom-kmod
 ├── Makefile
 └── src
     ├── Makefile
     └── custom_kmod.c
  • 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.

package/custom-kmod/src/custom_kmod.c

#include <linux/init.h>
#include <linux/module.h>

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);
  • 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).

package/custom-kmod/src/Makefile

obj-m := custom_kmod.o
  • obj-m declares a loadable kernel module target.

  • Kbuild produces custom_kmod.ko.

package/custom-kmod/Makefile

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))
  • 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.

Build:

make package/custom-kmod/{clean,compile} V=s

Output:

bin/targets/x86/64/packages/kmod-custom-kmod*.apk
  • clean resets the package build directory.

  • compile triggers Prepare + Compile phases.

  • Output naming uses kernel ABI string.

scp -P 2223 bin/targets/x86/64/packages/kmod-custom-kmod*.apk root@127.0.0.1:/tmp/
  • /tmp is writable (tmpfs).

  • Works for QEMU or hardware devices.

apk add --allow-untrusted /tmp/kmod-custom-kmod*.apk
  • Installs custom_kmod.ko into module directory.

  • Autoload entry created via AUTOLOAD directive.

ls /lib/modules/*/ | grep custom_kmod

Expected:

custom_kmod.ko
  • Confirms file presence, not loaded state.

  • Use lsmod to check load status.

Load module

insmod custom_kmod.ko

Check logs:

dmesg | tail

Expected:

custom-kmod: Hello from kernel module!

Unload module

rmmod custom_kmod
dmesg | tail

Expected:

custom-kmod: Goodbye from kernel module!
  • insmod directly loads module file.

  • rmmod unloads and triggers exit callback.

  • Failures often indicate module still in use.