驱动2-Linux设备模块

  1. linux内核模块开发
  2. 字符设备驱动
  3. 内核中并发和竞态的解决方法
  4. IO模型
  5. 设备树
  6. GPIO子系统,内核定时器
  7. 中断子系统
  8. platform总线驱动
  9. i2c总线驱动
  10. spi总线驱动
  11. 块设备驱动
  12. 网卡设备驱动
  13. camera驱动

目录

第一章 Linux设备模块

一、内核模块的三要素

二、内核模块的编写

三、驱动模块的编写

        1. 内部编译:

        2.外部编译

四、编写进行测试



一、内核模块的三要素

        

         入口:在入口中分配资源

        出口:在出口中释放资源

        许可证:遵从GPL协议

二、内核模块的编写

#include <linux/init.h>
#include <linux/module.h>

//入口
static int __init demo_init(void)
{
    //static:限定作用域
    //int:返回值类型
    //__init:(给编译器使用)
    //#define __init __section(".init.text") 
    //内核的链接脚本vmlinux.lds==> = ALIGN(8); .init.text 
    //将demo_init函数放在.init.text段中
    //demo_init:驱动的入口函数的名字(随便写)
    //(void):不能传递参数
    return 0;
}
//出口
static void __exit demo_exit(void)
{
    //__exit:告诉编译器将demo_exit函数放在.exit.text段中

}
//将入口函数的地址告诉给内核
module_init(demo_init);
//将出口函数的地址告诉给内核
module_exit(demo_exit);
//许可证
MODULE_LICENSE("GPL");

三、驱动模块的编写

        1. 内部编译:

​                 Kconfig .config Makefile

        2.外部编译

#KERNELDIR:= /home/linux/linux-5.10.61   #在开发板上安装
KERNELDIR:= /lib/modules/$(shell uname -r)/build #在ubuntu上安装
PWD:=$(shell pwd)
all:
 make -C $(KERNELDIR) M=$(PWD) modules
 @#从当前目录切换到内核的顶层目录下
 @#读取内核顶层目录下的Makefile文件
 @#执行make
 @#make M=$(PWD) modules
 @#make modules:模块化编译的命令,M指定只编译当前目录下的目录
clean:
 make -C $(KERNELDIR) M=$(PWD) clean
 @#清除编译的中间文件

obj-m:=demo.o
#指定编译的模块名是demo 
=  :在给var2赋值的时候会将var1最后一次赋值的结果赋值给var2
    var1=123
    var2=$(var1)
    var1=456
    all:
        @echo $(var2) #456

:= :立即赋值
    var1=123
    var2:=$(var1)
    var1=456
    all:
        @echo $(var2) #123

+= :附加赋值
 var1=123
    var1 +=456
    all:
        @echo $(var1) #123 456

?= :询问赋值
 #var1=123
    var1?=456 #询问var1之前是否被赋值给,如果被赋值给本次赋值不成立,否则成立
    all:
        @echo $(var1)

通用的makefile

arch?=x86
modname?=demo

ifeq ($(arch),arm)
KERNELDIR:= /home/linux/linux-5.10.61
else  
KERNELDIR:= /lib/modules/$(shell uname -r)/build 
endif

PWD:=$(shell pwd)
all:
 make -C $(KERNELDIR) M=$(PWD) modules

clean:
 make -C $(KERNELDIR) M=$(PWD) clean

obj-m:=$(modname).o

 编译之后:       

        sudo insmod demo.ko //安装模块

        lsmod //查看模块

        sudo rmmod demo //卸载模块

四、编写进行测试

        

#include <linux/init.h>
#include <linux/module.h>

static int __init mycdev_init(void)
{
    //1.打印级别是3,大于终端的4级别,消息应该会在终端上回显
    printk(KERN_ERR "hello DC22021 everyone!\n");
    //2使用的默认消息级别是4,终端级别也是4,所以消息不会在终端上回显
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    
    return 0;
}
static void __exit mycdev_exit(void)
{
    //1.打印级别是3,大于终端的4级别,消息应该会在终端上回显
    printk(KERN_ERR "bye DC22021 everyone!\n");
    //2使用的默认消息级别是4,终端级别也是4,所以消息不会在终端上回显
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

 写好之后按照上面的程序依次进行编译、安装 然后:

需要在ubuntu中打开虚拟终端,

打开:ctrl+alt+(fn)+{F2 ~ F6} ===>用户名:linux 密码:

安装卸载驱动看现象:

在init和exit中只显示了第一句话

退出:ctrl+alt+(fn)+F1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MrWang.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值