• Linux


    LINUX

    http://www.kernel.org/(Linux内核源代码官方网站)

    驱动

    裸机驱动 系统驱动

    设备驱动在Linux操作系统中的层次

    在这里插入图片描述

    Linux系统驱动类型

    字符设备
    块设备
    网络设备

    Linux内核模块的三要素

    入口
    出口
    许可证

    #include 
    #include 
    
    //内核模块入口函数
    static int __init mycdev_init(void)
    {
        //static声明当前函数只能在当前文件中使用
        //int 声明返回值类型为int
       // mycdev_init是函数名,可以更换
       //内核模块中的参数如果无,一定要写一个void
       //#define __init     __section(".init.text")
        //__init的作用是指定入口函数存放在.init.text段中
        return 0;  //一定要返回一个int类型的值,不然编译报错
    }
    //内核模块出口函数
    static void __exit mycdev_exit(void)
    {
        //__exit声明当前的出口函数在.exit.text段
    
    }
    //用于向内核声明当前内核模块的入口函数地址
    module_init(mycdev_init);
    //用于向内核声明当前内核模块的出口函数地址
    module_exit(mycdev_exit);
    //声明当前内核模块遵循GPL协议
    MODULE_LICENSE("GPL");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    makefile

    arch?=arm  #存储编译架构的变量
    modname?=demo #存储模块文件名的变量
    #指定内核顶层目录的路径
    ifeq ($(arch),arm)
    KERNELDIR:=/home/ubuntu/linux-5.10.61/   #编译为ARM架构的内核路径
    else
    KERNELDIR:=/lib/modules/$(shell uname -r)/build   #编译生成x86架构文件的内核路径
    endif
    #指定当前源码所在的路径
    PWD:=$(shell pwd)  #将shell命令pwd的执行结果赋值给变量PWD
    all:
    #make modules表示进行模块化编译
    #make -C $(KERNELDIR)先切换路径到KERNELDIR下,按照这个路径下Makefile的规则进行make
    #M=$(PWD)指定模块化编译的路径
        make -C $(KERNELDIR) M=$(PWD) modules
    clean:
    #编译清除
        make -C $(KERNELDIR) M=$(PWD) clean
    #将指定的.o文件独立链接为模块文件
    obj-m:=$(modname).o
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    insmod
    rmmod
    lsmod
    modinfo
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    printk

    #define KERN_EMERG    KERN_SOH "0"    /* system is unusable */
    #define KERN_ALERT    KERN_SOH "1"    /* action must be taken immediately */
    #define KERN_CRIT    KERN_SOH "2"    /* critical conditions */
    #define KERN_ERR    KERN_SOH "3"    /* error conditions */
    #define KERN_WARNING    KERN_SOH "4"    /* warning conditions */
    #define KERN_NOTICE    KERN_SOH "5"    /* normal but significant condition */
    #define KERN_INFO    KERN_SOH "6"    /* informational */
    #define KERN_DEBUG    KERN_SOH "7"    /* debug-level messages */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    #include 
    #include 
    
    // 内核模块入口函数
    static int __init mycdev_init(void)
    {
        printk(KERN_ERR "模块安装,执行入口函数\n");
        return 0;
    }
    // 内核模块出口函数
    static void __exit mycdev_exit(void)
    {
       printk(KERN_ERR "模块卸载,执行出口函数\n");
    }
    
    module_init(mycdev_init);
    module_exit(mycdev_exit);
    MODULE_LICENSE("GPL");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    dmesg

    在这里插入图片描述

    传参

    module_param(name, type, perm)

    #include 
    #include 
    
    int a=10;
    module_param(a,int,0664);//声明当前变量可以进行命令行传参
    MODULE_PARM_DESC(a,"value is a int");
    // 内核模块入口函数
    static int __init mycdev_init(void)
    {
        printk(KERN_ERR "模块安装,执行入口函数\n");
        printk("a=%d\n",a);
        return 0;
    }
    // 内核模块出口函数
    static void __exit mycdev_exit(void)
    {
       printk(KERN_ERR "模块卸载,执行出口函数\n");
    }
    
    module_init(mycdev_init);
    module_exit(mycdev_exit);
    MODULE_LICENSE("GPL");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    #include 
    #include 
    
    int a=10;
    char b='c';
    char *p="hello world";
    module_param(a,int,0664);//声明当前变量可以进行命令行传参
    MODULE_PARM_DESC(a,"value is a int");
    module_param(b,byte,0664);
    MODULE_PARM_DESC(b,"value is a char");
    module_param(p,charp,0664);
    MODULE_PARM_DESC(p,"value is a charp");
    // 内核模块入口函数
    static int __init mycdev_init(void)
    {
        printk(KERN_ERR "模块安装,执行入口函数\n");
        printk("a=%d\n",a);
        printk("b=%c\n",b);
        printk("p=%s\n",p);
        return 0;
    }
    // 内核模块出口函数
    static void __exit mycdev_exit(void)
    {
       printk(KERN_ERR "模块卸载,执行出口函数\n");
    }
    
    module_init(mycdev_init);
    module_exit(mycdev_exit);
    MODULE_LICENSE("GPL");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    Unity开发过程中的一些小知识点
    Golang基础7-并发编程
    EMC-汽车显示产品EMI问题整改
    c语言范例实例
    【linux】自定义nameserver
    windows10安装redis服务【成功安装】
    多维时序 | MATLAB实现WOA-CNN-BiLSTM-Attention多变量时间序列预测(SE注意力机制)
    【匠心之作】三道题带你简单复习C++和Java
    chatglm2-6b在P40上做LORA微调 | 京东云技术团队
    存档&改造【06】Apex-Fancy-Tree-Select花式树的使用&误删页数据还原(根据时间节点导出导入)
  • 原文地址:https://blog.csdn.net/Yg118/article/details/132612037