openwrt版本:19.07.4
在openwrt目录下执行make menuconfig
选择Kernel modules --->
发现这里存在内核驱动的各种选项:
这个选项表大部分是通过openwrt/package/kernel/linux/modules目录下的.mk文件生成的:
当然在openwrt/package/kernel目录下还有一些第三方的内核驱动以单独目录的形式组织放在这里。通过Makefile的编写,它们也能在Kernel modules --->选项中找到。
我们自己编写的内核驱动应该按照openwrt的组织形式放在openwrt/package/kernel目录下。
在openwrt/package/kernel/目录下创建一个helloworld目录,在helloworld目录里面创建一个Makefile文件,一个src目录。
进入src目录,创建Kconfig、Makefile,helloworld.c文件。
假如openwrt SDK包放在/home/username目录下,执行如下命令。
cd ~/openwrt/package/kernel/
mkdir -p helloworld
cd helloworld
touch Makefile
mkdir -p src
cd src
touch Kconfig
touch Makefile
touch helloworld.c
3.1 编写~/openwrt/package/kernel/helloworld/Makefile文件,如下:
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=helloworld
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/helloworld
SUBMENU:=Other modules
TITLE:=Hello World! My first openwrt module.
FILES:=$(PKG_BUILD_DIR)/helloworld.ko
AUTOLOAD:=$(call AutoLoad,50,helloworld,1)
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(KERNEL_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(BUILDFLAGS)" \
modules
endef
$(eval $(call KernelPackage,helloworld))
3.2 编写~/openwrt/package/kernel/helloworld/src/Makefile文件,如下:
obj-m := helloworld.o
3.3编写~/openwrt/package/kernel/helloworld/src/Kconfig文件,如下:
config HELLOWORLD
tristate "helloworld"
help
nothin
3.4编写~/openwrt/package/kernel/helloworld/src/helloworld.c文件
#include
#include
static int __init helloworld_init(void)
{
printk(KERN_ALERT "Hello World! My first Operwrt module!\n");
return 0;
}
static void __exit helloworld_exit(void)
{
printk(KERN_ALERT "Bye, The World!\n");
}
module_init(helloworld_init);
module_exit(helloworld_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SANZHOUZI");
MODULE_DESCRIPTION("Nothing");
以上代码编写完毕之后,在~/openwrt主目录下执行
make menuconfig
选择
Kernel modules --->
Other modules --->
将会看见多了一个选项
这个选项就是我们刚加上去的helloworld模块
按空格把这个选项设置如下:
退出,保存。
然后执行 make ./package/kernel/helloworld/compile V=99
编译完成之后
在~/openwrt/bin/targets/ramips/mt76x8/packages可以发现一个ipk文件。(注意:这个路径中/ramips/mt76x8,因不同的芯片平台是不同的。笔者用的是MIPS架构的MT7688芯片,所以这里显示这个路径。)
kmod-helloworld_5.4.63-1_mipsel_24kc.ipk
这个就是最终得到的模块ipk包
拷贝这个ipk包到板子上:
用scp工具,板子默认是安装了这个工具,并且要求在root用户下才能给板子拷贝数据。
板子要跟主机在同一个网段。比如板子为192.168.1.1, 主机为192.168.1.40
主机执行sudo scp kmod-helloworld_5.4.63-1_mipsel_24kc.ipk [email protected]:/
回车,输入主机root密码,有可能需要输入板子的密码,视路由器板子的设置而定。
这句话的意思是把这个ipk包放到板子的根目录下。
拷贝完毕之后,下面需要安装ipk包,也就是helloworld模块。
在路由器板子上执行:
opkg install /kmod-helloworld_5.4.63-1_mipsel_24kc.ipk
显示类似下面的安装信息:
Installing kmod-helloworld (5.4.63-1) to root...
Configuring kmod-helloworld.
[ 2034.835085] kmodloader: loading kernel modules from /etc/modules.d/*
[ 2034.928058] Hello World! My first Operwrt module!
[ 2034.942598] kmodloader: done loading kernel modules from /etc/modules.d/*
说明安装成功。
cd /lib/modules/5.4.63中,(5.4.63是linux内核版本)
可以发现,里面多了一个helloworld.ko
由于在开始编写Makefile文件时,我们加入了AUTOLOAD:=$(call AutoLoad,50,helloworld,1)
所以在/etc/modules.d中可以发现多了一个50-helloworld文件
在/etc/modules-boot.d中多了50-helloworld这个链接。
说明在启动系统的时候会自动加载helloworld模块,一个叫kmodloader的程序在启动的时候会加载这个模块。
参考文献:
https://openwrt.org/docs/guide-developer/single.package