一、前言

  • 构建自己的内核驱动模块,相关知识可以参考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内核驱动模块相关推荐

  1. 超详细——手把手教你用threejs实现一个酷炫的模型发光扫描效果(三)

    上一篇文章 voidjay,公众号:web前端可视化超详细--手把手教你用threejs实现一个酷炫的模型发光扫描效果(二) 上一篇文章已完成基本效果的实现,本文则完成整个项目的灵魂:发光效果以及模型 ...

  2. k8s核心组件详细介绍教程(配超详细实例演示)

    本文实验环境基于上篇文章手把手从零开始搭建k8s集群超详细教程 本文根据B站课程云原生Java架构师的第一课K8s+Docker+KubeSphere+DevOps学习总结而来 k8s核心组件介绍 1 ...

  3. aspen二元体系共沸组分_超详细 | 手把手教你组分结构预测

    好久不见,读者朋友们,笔者本次介绍USPEX官方案例16-18:大体系定组分稳定结构预测.以德拜温度为目的进行定组分结构预测.计算量惊人的三元体系的变组分结构预测. 01 USPEX官方案例讲解(16 ...

  4. MiKTeX手动更新宏包超详细,东北大学编译原理第三次作业

    官网download miktex之后需要手动更新宏包?? 首先要在bin/x64目录下找到miktex-update.exe,如果你找到了miktex-console.exe,是一样的,双击运行. ...

  5. 超详细手把手教你cordova开发使用指南+自定义插件,jsbridge

    Cordova是什么 使用前端技术 开发跨平台web App的工具 底层原理:HTML+CSS搭建页面, JS和原生交互 交互原理:Cordova插件 环境配置 安卓开发基础环境搭建的文章可以参考一下 ...

  6. 超详细——手把手教你用threejs实现一个酷炫的模型发光扫描效果(一)

    前言 模型特效是大家在3d可视化项目所追求的,但很多人苦于无法实现一个好的模型效果,本次就手把手一步一步教你实现一个酷炫的模型发光扫描特效,帮让你的项目提升一个逼格.话不多说,先上效果: 本文所使用的 ...

  7. 图像去雨:超详细手把手写 pytorch 实现代码(带注释)

    引导 数据集准备 训练数据集代码 测试数据集代码 网络模型代码 训练代码 测试代码 参考文献 其他 数据集准备 使用来自第一个参考文献的公开数据集Rain12600和Rain1400,下载链接.其中训 ...

  8. rtmp测试地址_超详细搭建多码率测试环境(成为流媒体高手必经之路)

    0.引言 关注我的朋友,应该都知道,前面我们讲解了如何搭建srs流媒体服务器,链接如下.由于srs流媒体服务器是不支持多码率测试环境,所以不能在上次的环境上继续演示.那本篇文章就要给出一个新方案,就是 ...

  9. 超详细版本vue+capacitor(自定义capacitor插件)编写移动端应用

    人生苦短,我们要: 我的环境 Node v16.13.0 npm v8.1.0 mac的话需要安装Xcode windows的话需要Java 8 JDK和Android Studio软件 本文以安卓开 ...

最新文章

  1. android 相片裁剪空间,科学网—根据需要的空间范围对目标图层进行空间裁剪 - 孙露的博文...
  2. /etc/fstab 文件解释
  3. jQuery 判断元素是否存在
  4. 才子佳人文学传统的戏拟与嘲仿
  5. 防止properties乱码配置---SpringBoot
  6. 【POJ - 1651】Multiplication Puzzle(区间dp)
  7. Android aidl在Framework的使用
  8. python终端指令大全_使用python模拟命令行终端的示例
  9. java坦克大战源码下载
  10. window覆盖导航栏
  11. FreeEIM在树上一会儿荡秋千
  12. spring boot 2.0之安全
  13. Android版本win7镜像下载,【bochs win7镜像下载】bochs win7镜像精简版 有声可上网版-趣致软件园...
  14. linux内核源码阅读之facebook硬盘加速flashcache之二
  15. Dual Thrust 商品期货 (注释版)
  16. TBSchedule初识
  17. 圆的面积函数定义及调用
  18. 使用 OpenStreetMap 数据搭建离线地图服务
  19. 利用python生成微信h5_Python + Appium 微信公众号 H5 页面自动化测试
  20. 适合练习听力的动画排名

热门文章

  1. C++实现简单UDP通信
  2. win7无法连接打印机拒绝访问_win7系统无法连接共享打印机的解决方法
  3. 15、Linux:IP及端口检查命令
  4. OpenWRT AR9331 mjpg-streamer 网络安装和离线ipk安装
  5. 李万博老师《总裁演说思维》课程笔记(15)
  6. Scss学习--Scss逻辑运算
  7. 初入Ubuntu的Java开发者安装软件手记
  8. 大学计算机二级考试无故缺考,快来看看2019年起自考学历无故缺考的后果
  9. 【How to Design Translation Prompts for ChatGPT: An Empirical Study 论文略读】
  10. python主成分分析(PCA)