超详细!手把手演示编译OpenWrt内核驱动模块
一、前言
- 构建自己的内核驱动模块,相关知识可以参考OpenWrt软件编译构建系统文章:https://dongshao.blog.csdn.net/article/details/102545618。
- 下面我们自己以一个自己设计的hello-kernel内核驱动模块为例,一步一步地构建出自己的驱动模块。
二、目录结构
- 通常新增一 个内核驱动模块的主要步骤如下:
- 在OPenWrt源码的package/kernel目录下增加一个目录(例如hello-kernel)。
- 在hello目录下添加src目录,src目录存放模块源码和源码编译Makefile和配置文件Kconfig。
- 在hello-kernel顶层目录下增加Makefile。此Makefile中包含编译脚本和安装脚本。
- 我们软件的目录为名为hello-kernel,放置在OpenWrt源码的package/kernel目录下:
三、src目录设计
- 这个目录下存放着驱动模块的源代码hello-kernel.c、hello-kernel.c的Makefile文件、配置文件Kconfig。
Makefile文件
- 这个Makefile文件的格式都是固定的,不论是编译什么内核模块都是一样。只需要写入obj-${CONFIG_HELLO-KERNEL},然后再后面+=驱动模块名称的.o文件名即可。
- 此处我们的驱动模块Makefile如下所示:
Kconfig文件
- 这个配置文件是必须有的。
config HELLO-KERNELtristate "Test kernel driver"helpThis is an Kernel Driver Testif unsure ,delete it ,just for fun
hello-kernel.c代码设计
- 此处我们只是来演示如何编译一个OpenWrt的内核驱动模块,所以驱动模块没有太多功能。单纯的知识在加载驱动模块和卸载驱动模块的时候打印一下信息,代码如下:
#include <linux/init.h> #include <linux/module.h>static int __init hello_init(void) {printk(KERN_INFO "Hello World enter\n");return 0; } module_init(hello_init);static void __exit hello_exit(void) {printk(KERN_INFO "Hello World exit\n "); } module_exit(hello_exit);MODULE_AUTHOR("dongshao-CSDN"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("A simple Hello World Module"); MODULE_ALIAS("a simplest module");
四、顶级Makefile设计
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mkPKG_NAME:=hello-kernel
PKG_RELEASE:=1include $(INCLUDE_DIR)/package.mkEXTRA_CFLAGS:= \$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \MAKE_OPTS:=ARCH="$(LINUX_KARCH)" \CROSS_COMPILE="$(TARGET_CROSS)" \SUBDIRS="$(PKG_BUILD_DIR)" \EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \$(EXTRA_KCONFIG)define KernelPackage/hello-kernelSUBMENU:=Other modulesTITLE:=Hello kernel drive FILES:=$(PKG_BUILD_DIR)/hello-kernel.koAUTOLOAD:=$(call AutoProbe,81,hello-kernel)
endefdefine Build/Preparemkdir -p $(PKG_BUILD_DIR)/$(CP) -R ./src/* $(PKG_BUILD_DIR)/
endefdefine Build/Compile$(MAKE) -C "$(LINUX_DIR)" \$(MAKE_OPTS) CONFIG_HELLO-KERNEL=m \modules
endef
$(eval $(call KernelPackage,hello-kernel))
Makefile解析
- 第一步:首先包含rules.mk和kernel.mk文件。接着将驱动模块的名称定义为“hello-kernel”,并设置版本编号为“1”。
- 第二步:接着是编译时的一些选项,保持默认即可。
- 第三步:在软件包定义中的一些变量赋值:
- SUBMENU:我们内核模块放置于“Other modules”。我们在make menuconfig时,可以在Kernel modules/other modules菜单下找到这个模块。
- TITLE:标题,驱动模块的简短描述。
- FILES:生成的驱动模块的存放位置。此处为设置为在编译目录下(就是编译过程中的临时目录build_dir)。
- AUTOLOAD:代表是否在系统启动时自动装载到内核中,后面括号内有3个参数(参数1不变,参数2为驱动模块的装载顺序(可以省略这个参数,省略后系统自动分配状态顺序),参数3代表驱动模块名称)。
- DEPENDS:如果驱动模块还需要依赖,则此变量设置为依赖文件名(此处没有依赖所以就未设置)。
- 第四步:“Build/Prepare”定义了如何准备编译本软件包,这里创建了编译目录(OKG_BUILD_DIR就是编译过程中的临时目录build_dir),然后将src目录下的所有文件复制到编译目录下
- 第五步:编译源代码选项,在大多数情况下应该不用定义而使用默认值,下面我们加入了“CONFIG_HELLO-KERNEL=m”这一选项,MAKE_OPTS变量就是第二步图中定义的变量。
- 最后KernelPackage,将驱动模块的名称作为参数传递给KernelPackage。
五、编译驱动模块
- 第一步:打开Ubuntu,将我们的hello-kernel目录放入OpenWrt源码目录的package/kernel目录下。
- 第二步:输入“make menuconfig”进入选项菜单。
- 第三步:在OpenWrt源码顶级目录下输入下面的命令编译驱动模块。
make package/kernel/hello-kernel/compile V=s
- 第四步: 编译完成之后会在下面的目录中看到我们的内核模块(因为我们的OpenWrt内核是4.4.92版本的,所以在这个目录下)。
附加知识
- 内核的模块必须要与模块内核版本相同的系统中才可以运行,此处我们的OpenWrt源码为4.4.92版本,所以在编译完成之后生成的.ko文件也只能在4.4.92内核版本的OpenWrt中运行。
- 下面可以输入下面的命令来查看我们的OpenWr的内核版本,可以看到为4.4.92。
六、内核模块的使用
- 第一步:将我们的内核模块.ko文件发送到OpenWrt系统中。
- 第二步:输入insmod命令加载我们的内核模块,然后使用dmesg -c命令打印一下内核的输出信息。
- 第三步:输入下面命令将我们的内核模块卸载。
七、编译过程中出现的问题
问题一
- 出现下面的问题,是因为Makefile没有涉及好(空格、缩进没有做好)。
- 解决办法,将文件设置为在Unix环境下书写,并且每一行的末尾不能有多余的空格。
- 我是小董,V公众点击"笔记白嫖"解锁更多OpenWrt资料内容。
超详细!手把手演示编译OpenWrt内核驱动模块相关推荐
- 超详细——手把手教你用threejs实现一个酷炫的模型发光扫描效果(三)
上一篇文章 voidjay,公众号:web前端可视化超详细--手把手教你用threejs实现一个酷炫的模型发光扫描效果(二) 上一篇文章已完成基本效果的实现,本文则完成整个项目的灵魂:发光效果以及模型 ...
- k8s核心组件详细介绍教程(配超详细实例演示)
本文实验环境基于上篇文章手把手从零开始搭建k8s集群超详细教程 本文根据B站课程云原生Java架构师的第一课K8s+Docker+KubeSphere+DevOps学习总结而来 k8s核心组件介绍 1 ...
- aspen二元体系共沸组分_超详细 | 手把手教你组分结构预测
好久不见,读者朋友们,笔者本次介绍USPEX官方案例16-18:大体系定组分稳定结构预测.以德拜温度为目的进行定组分结构预测.计算量惊人的三元体系的变组分结构预测. 01 USPEX官方案例讲解(16 ...
- MiKTeX手动更新宏包超详细,东北大学编译原理第三次作业
官网download miktex之后需要手动更新宏包?? 首先要在bin/x64目录下找到miktex-update.exe,如果你找到了miktex-console.exe,是一样的,双击运行. ...
- 超详细手把手教你cordova开发使用指南+自定义插件,jsbridge
Cordova是什么 使用前端技术 开发跨平台web App的工具 底层原理:HTML+CSS搭建页面, JS和原生交互 交互原理:Cordova插件 环境配置 安卓开发基础环境搭建的文章可以参考一下 ...
- 超详细——手把手教你用threejs实现一个酷炫的模型发光扫描效果(一)
前言 模型特效是大家在3d可视化项目所追求的,但很多人苦于无法实现一个好的模型效果,本次就手把手一步一步教你实现一个酷炫的模型发光扫描特效,帮让你的项目提升一个逼格.话不多说,先上效果: 本文所使用的 ...
- 图像去雨:超详细手把手写 pytorch 实现代码(带注释)
引导 数据集准备 训练数据集代码 测试数据集代码 网络模型代码 训练代码 测试代码 参考文献 其他 数据集准备 使用来自第一个参考文献的公开数据集Rain12600和Rain1400,下载链接.其中训 ...
- rtmp测试地址_超详细搭建多码率测试环境(成为流媒体高手必经之路)
0.引言 关注我的朋友,应该都知道,前面我们讲解了如何搭建srs流媒体服务器,链接如下.由于srs流媒体服务器是不支持多码率测试环境,所以不能在上次的环境上继续演示.那本篇文章就要给出一个新方案,就是 ...
- 超详细版本vue+capacitor(自定义capacitor插件)编写移动端应用
人生苦短,我们要: 我的环境 Node v16.13.0 npm v8.1.0 mac的话需要安装Xcode windows的话需要Java 8 JDK和Android Studio软件 本文以安卓开 ...
最新文章
- android 相片裁剪空间,科学网—根据需要的空间范围对目标图层进行空间裁剪 - 孙露的博文...
- /etc/fstab 文件解释
- jQuery 判断元素是否存在
- 才子佳人文学传统的戏拟与嘲仿
- 防止properties乱码配置---SpringBoot
- 【POJ - 1651】Multiplication Puzzle(区间dp)
- Android aidl在Framework的使用
- python终端指令大全_使用python模拟命令行终端的示例
- java坦克大战源码下载
- window覆盖导航栏
- FreeEIM在树上一会儿荡秋千
- spring boot 2.0之安全
- Android版本win7镜像下载,【bochs win7镜像下载】bochs win7镜像精简版 有声可上网版-趣致软件园...
- linux内核源码阅读之facebook硬盘加速flashcache之二
- Dual Thrust 商品期货 (注释版)
- TBSchedule初识
- 圆的面积函数定义及调用
- 使用 OpenStreetMap 数据搭建离线地图服务
- 利用python生成微信h5_Python + Appium 微信公众号 H5 页面自动化测试
- 适合练习听力的动画排名
热门文章
- C++实现简单UDP通信
- win7无法连接打印机拒绝访问_win7系统无法连接共享打印机的解决方法
- 15、Linux:IP及端口检查命令
- OpenWRT AR9331 mjpg-streamer 网络安装和离线ipk安装
- 李万博老师《总裁演说思维》课程笔记(15)
- Scss学习--Scss逻辑运算
- 初入Ubuntu的Java开发者安装软件手记
- 大学计算机二级考试无故缺考,快来看看2019年起自考学历无故缺考的后果
- 【How to Design Translation Prompts for ChatGPT: An Empirical Study 论文略读】
- python主成分分析(PCA)