• 添加驱动模块到内核的两种方法


    添加驱动模块到内核的两种方法

    1. 放在内核源代码树中

    步骤总结:

    1. 新建文件夹
    2. 编写Makefile、编写Kconfig
    3. 修改上层Kconfig
    4. 执行make menuconfig
    5. 执行make zImage 或 make modules
    1.1 源码放入文件夹

    例如:添加一个按键字符设备模块

    • 在内核目录下的 drivers/char 目录下新建文件夹 mykey

    • 在 drivers/char/ 下的 Makefile 中添加一行

      obj-m += mykey/
      这行指令告诉模块构建系统,在编译模块时需要进入 mykey/ 子目录中
          
      有可能的选择是,驱动程序的编译取决于一个特殊的配置选项,例如 CONFIG_MYKEY ,则指令要替换成
      obj-$(CONFIG_MYKEY) += mykey/
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 最后,在 drivers/char/mykey/ 目录下添加一个 Makefile,其中需要有下面这行指令

      obj-m += mykey.o
      表示进入 mykey/ 子目录后,要将 mykey.c 编译成 mykey.o,但最终会生成 mykey.ko 文件
      
      如果加了编译选项,则指令如下
      obj-$(CONFIG_MYKEY) += mykey.o
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 另外,如果后续你的按键程序需要使用到其他的源文件,可以将 mykey/ 目录下的 Makefile 做如下修改

      obj-$(CONFIG_MYKEY) += mykey.o
      mykey-objs := mykey_main.o other.o
      表示 mykey_main.c 和 other.c 会一起被编译和链接进 mykey.ko 文件
      
      • 1
      • 2
      • 3
    1.2 源码放入设备总目录下

    如果只有一两个源文件,则可以选择不新建文件夹,直接将 mykey.c 放入到 drivers/char/ 目录下,在 drivers/char/ 目录下的 Makefile 中添加如下指令即可

    obj-m += mykey.o
        
    如果配置了编译选项,则指令为
    obj-$(CONFIG_MYKEY) += mykey.o
        
    如果有多个源文件,则指令为
    obj-$(CONFIG_MYKEY) += mykey.o
    mykey-objs := mykey_main.o other.o
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    即将原本 drivers/char/mykey/Makefile 的内容全部写到 drivers/char/Makefile 中。

    1.3 管理配置选项
    • 在 drivers/char/mykey/ 目录下新建一个 Kconfig 文件(如果没有独立目录,则直接在 drivers/char/Kconfig 中添加)

    • 添加如下内容(实例)

      config MYKEY
      	tristate "This is config of mykey"
      	default n
      	help 
      	  If you chose Y, support this key function, 
      	  this key will be compiledinto the kernel.
      	  you can also chose M, then this driver will 
      	  be built as a module named mykey.ko.
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    1. 第一行定义了该选项所代表的配置目标(注意 CONFIG_ 前缀不必写上)

    2. 第二行声明选项类型为 “tristate” ,它有三个选项N Y M,Y表示可以编译进内核,M表示作为模块编译,N表示不操作。

    3. 第三行是默认的选项类型

    4. help 表示为该选项提供帮助文档

    5. 除了上述选项外,还有其他选项,比如 depends 指令,规定了该选项的依赖选项,表示必须将依赖选项设置,才可以选择本选项

      depends on MENU_KEY

    6. 在 drivers/char/Kconfig 文件中添加

      source “drivers/char/mykey/Kconfig”

    执行 make menuconfig 后结果如下
    在这里插入图片描述

    如果 Kconfig 的内容改成这样(带菜单)

    menu "Config my key"
    
    config MYKEY    
    	tristate "This is config of mykey"    
    	default n    
    	help       
    		If you chose Y, support this key function,       
    		this key will be compiledinto the kernel.      
    		you can also chose M, then this driver will       
    		be built as a module named mykey.ko.
    
    endmenu
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    make menuconfig 找到 MYKEY(可以看到多出一个菜单来)
    在这里插入图片描述

    按 “h” 进入 help
    在这里插入图片描述
    make menuconfig 之前看一眼内核根目录下的 .config 文件, CONFIG_MYKEY 还未定义

    在这里插入图片描述
    我们使用 make menuconfig 将 CONFIG_MYKEY 选项选择为 M 后,看一下内核目录下的 .config 文件
    在这里插入图片描述

    别忘了在 drivers/char/mykey/Makefile 中添加内容

    obj-$(CONFIG_MYKEY) += mykey.o
    
    • 1

    make modules 后观察 drivers/char/mykey/ 目录下的文件,多出了许多文件,其中包括 key.ko
    在这里插入图片描述

    如果要编译进内核中, CONFIG_MYKEY 选项选择为 Y ,然后执行 make zImage,会发现生成的zImage镜像大小增加了一些,但是不会在 drivers/char/mykey/ 下生成 key.ko ,不过会生成 key.o

    PS:obj-y(对应 make zImage))是指将模块编译进内核(zImage)

    obj-m(对应 make modules)是指编译模块生成 ko 文件


    2. 放在内核代码外

    如果我们希望编写的模块可以被动态的加载到内核中,即使用 insmod、modprobe 命令,则不能将模块代码直接放入内核源码树中了。

    只需在自己编写的模块目录中新建一个 Makefile 文件,由于是在内核源码外围,所以我们需要告诉 make 工具如何找到内核源代码文件和基础的 Makefile 文件

    为什么需要找到内核源码和基础 Makefile 文件?

    答:因为驱动代码中使用到了内核提供的函数、头文件等等,编译成最终的 ko 文件也是要遵循内核的编译方法

    Makefile 中一定要包含以下指令

    make -C 内核所在路径 M=$PWD modules
        
    obj-m += mykey.o
    
    • 1
    • 2
    • 3

    一般的 Makefile 的写法如下:

    KERN_DIR = /home/内核路径
    
    all:
    	make -C $(KERN_DIR) M=`pwd` modules
    
    clean:
    	make -C $(KERN_DIR) M=`pwd` modules clean
    
    obj-m += mykey.o
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    执行make后,生成mykey.ko文件,使用动态加载命令插入进内核

    insmod mykey.ko
    
    • 1

  • 相关阅读:
    leetcode字符串必刷题——反转字符串、反转字符串 II、反转字符串中的单词、找出字符串中第一个匹配项的下标、重复的子字符串
    TASK04分组|joyfulpandas
    怎样下载微信视频号视频?分享十种方法给你~
    前后端分离之权限管理
    Vue配置代理学习笔记
    代码优化个人经验总结(以代码解耦模块化 减少代码量为目标 提高可维护性降低bug率)
    【Java】Vector 与 ArrayList 集合区别
    关于package和import
    WPF 图片头像自由剪切器实时截图细节放大器
    【LeetCode:2530. 执行 K 次操作后的最大分数 | 堆】
  • 原文地址:https://blog.csdn.net/HuangChen666/article/details/133576722