• 编译内核模块生成ko驱动文件


    1.加载内核简介

    Linux内核的整体架构本就非常庞大,其包含的组件也非常多。而我们怎样把需要的部分都包含在内核中呢?一种方法是把所有需要的功能都编译到Linux内核中。这会导致两个问题,一是生成的内核会很大,二是如果我们要在现有的内核中新增或删除功能,将不得不重新编译内核。

    Linux提供了这样的机制,这种机制被称为模块(Module)。可使得编译出的内核本身并不需要包含所有功能,而在这些功能需要被使用的时候,其对应的代码被动态地加载到内核中。
    模块本身不被编译入内核映像,从而控制了内核的大小。·模块一旦被加载,它就和内核中的其他部分完全一样。

    在这里插入图片描述

    2.第一个hello world文件

    文件树

    一般要单独编译成模块需要在内核以外的目录新建文件夹进行编译。

    1. ├── hello.c
    2. ├── Makefile

    hello.c

    1. #include
    2. #include
    3. static int __init hello_init(void)
    4. {
    5. printk(KERN_INFO "Hello World enter\n");
    6. return 0;
    7. }
    8. module_init(hello_init);
    9. static void __exit hello_exit(void)
    10. {
    11. printk(KERN_INFO "Hello World exit\n ");
    12. }
    13. module_exit(hello_exit);
    14. MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
    15. MODULE_LICENSE("GPL v2");
    16. MODULE_DESCRIPTION("A simple Hello World Module");
    17. MODULE_ALIAS("a simplest module");

    模块加载:insmod或modprobe命令加载内核模块时,模块的加载函数module_init会自动被

    内核执行。

    insmod加载模块失败原因:

    编译模块的内核与开发板内核不匹配,使用uname-r查看内核版本。

    有些模块会有依赖关系,当insmod加载ko失败时,可以用modprobe加载ko,modprobe可以解决模块之间的依赖关系。

    模块卸载:rmmod命令卸载某模块时,模块卸载函数module_exit在模块卸载的时候执行。

    makefile:

    1. KVERS = $(shell uname -r)
    2. #shell中输出uname -r会获得内核版本号,这里将版本号存到变量KVERS
    3. # Kernel modules
    4. #将后面的东东编译为“内核模块”, obj-y 编译进内核,obj-n 不编译。
    5. obj-m += hello.o
    6. # 开启EXTRA_CFLAGS=-g-O0,可以得到包含调试信息的hello.ko模块。
    7. #EXTRA_CFLAGS=-g -O0
    8. #-C 表示让 make 命令进入指定的内核源代码目录
    9. build: kernel_modules
    10. kernel_modules:
    11. make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
    12. clean:
    13. make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

    :=”表示:它的右边如果为变量,那么该变量在这条语句之前就要定义好,而不能在使用这条语句之后定义的变量。

    “=”表示:当它右边如果变量时,这个变量可以在这条语句之前或者之后使用。
    “?=”表示:当它左边的变量在这条语句之前没有定义过,则执行本条语句,如果已经定义了,则什么都不做。

    Obj - $(CONFIG_选项名) += xxx.o 

    /*当CONFIG_选项名=n时,表示对应目录下的xxx.c不参与编译

    当CONFIG_选项名=y时,表示对应目录下的xxx.c将被编译进内核

    当CONFIG_选项名=m时,表示对应目录下的xxx.c将被编译成一个.ko模块*/

    3.编译命令

    1. make
    2. #make的提示信息中,CC是编译,LD是链接
    3. modinfo hello.ko#获得模块的信息
    4. sudo insmod hello.ko #或者是insmod ./hello.ko
    5. #加载时输出“Hello World enter”
    6. lsmod #获得系统中已加载的所有模块以及模块间的依赖关系
    7. sudo rmmod hello
    8. #卸载时输出“Hello World exit”。
    9. lsmod #获得系统中已加载的所有模块以及模块间的依赖关系

  • 相关阅读:
    Linux 生成复杂密码并且检查密码强度
    fastadmin如何本地安装
    Elasticsearch实践:ELK+Kafka+Beats对日志收集平台的实现
    Qt QFrame详解
    抓取内网windows密码和利用hash横向及相关问题
    详细介绍 Oracle中的Materialized Views(物化视图/快照)
    线性表(顺序表,单链表,双链表,循环链表,静态链表)
    记录 ubuntu 硬盘分区跟格式化(fdisk命令)
    第十四届蓝桥杯模拟赛(第三期)Excel表
    动态改标题
  • 原文地址:https://blog.csdn.net/weixin_49303682/article/details/127643995