OpenWrt添加自定义kernel内核模块并编译
前言提示
Makefile的语法规则极其严格,任何错误都会导致报错。
比如在Makefile文件中,缩进必须使用TAB键而不是4个空格,检查发现空格会直接报错。使用VS code编辑器请务必确认TAB按键的设定。
添加自定义内核和编译openwrt一样,可能遇到各类错误。请保持良好心态,耐心解决问题。
新建模块目录
进入package/kernel目录,该目录下储存着内核模块
cd package/kernel
新建一个自定义目录,名字为你要添加的内核模块,这里用hello_kernel演示
mkdir hello_kernel
创建顶层Makefile文件
cd hello_kernel
vim Makefile
文件内容:
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=hello_kernel
include $(INCLUDE_DIR)/package.mk
PKG_AUTOLOAD:=hello_kernel
RSTRIP:=:
define KernelPackage/hello_kernel
SECTION:=myapps
CATEGORY:=myapps
TITLE:=hello kernel
FILES:=$(PKG_BUILD_DIR)/hello_kernel.ko
DEPENDS:=+kmod-ipt-conntrack
KCONFIG:=
AUTOLOAD:=$(call AutoLoad,0,$(PKG_AUTOLOAD))
endef
define KernelPackage/hello_kernel/description
hello kernel
endef
MAKE_OPTS:= \
$(KERNEL_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
$(EXTRA_KCONFIG)
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) \
modules
endef
$(eval $(call KernelPackage,hello_kernel))
SECTION:=myapps
CATEGORY:=myapps
这两行定义了该模块在配置菜单中的位置,这里是在顶部创建了一个独立的菜单myapps,如图所示:
如果需要放在传统的菜单目录里面(Kernel Modules),第一句改成
SUBMENU:=Other modules
创建源代码目录,编写模块源代码
新建源码目录
mkdir src
新建源代码文件
vim hello_kernel.c
源代码内容:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Derry");
MODULE_DESCRIPTION("hello kernel");
static int num=0;
// 接收参数num,模块加载时指定num=xxx,可以设置该值
module_param(num, int, S_IRUGO);
// 模块加载时调用
static int __init hello_init(void)
{
printk("hello kernel\n");
printk("num = %d\n", num);
return 0;
}
// 模块卸载时调用
static void hello_exit(void)
{
printk("module exit\n");
return;
}
// 注册加载和卸载函数
module_init(hello_init);
module_exit(hello_exit);
创建源代码编译Makefile
注意:目前在src目录下
vim Makefile
文件内容:
obj-m := hello_kernel.o
整体模块文件结构一览
在menuconfig菜单中选中模块
进入配置菜单,将内核模块选中变为*
单独编译内核模块
make package/kernel/hello_kernel/compile V=s
出现如下说明编译完成:
整体固件编译
单独编译测试通过后,可以整体编译固件,菜单选为* 即可
make -j1 V=s
效果测试
刷好固件后,在开机的串口打印中可以搜索到我们自定义的模块输出: