Linux驱动学习笔记

分几个部分记录一些自己以前不知道的点:

Linux驱动源码部分:

1.Linux头文件位置是在Linux源码目录下里的。类似#include<linux/module.h>头文件,它是在include/linux/module.h
2.ubuntu的内核源码是在/usr/src的目录下

Linux内核配置部分:

1.Linux编译器通过.config文件确认哪些代码编译进内核,哪些被裁减掉,而menuconfig是生成.config的一个工具,menuconfig实现的代码在源码"scripts"目录下。
2.在menuconfig中,界面输入“/”,输入查找关键词,输入“回车”即可搜索。
3.使用“空格”键选择具体驱动配置,有三种状态
– “M”编译成模块(需要在编译文件里面特殊定义,后面介绍)
– “空”不编译状态
– “星号”编译进内核
4.菜单项的项目内容从Kconfig文件来,菜单项的选择值从.config文件来。menuconfig读取Kconfig文件的项目内容,menuconfig读取/写入.config文件的选择值。
具体可参考博客:https://blog.csdn.net/oqqhutu12345678/article/details/71124359
5.Kconfig文件分析
linux源码顶层有一个Kconfig文件
在这里插入图片描述
这个Kconfig文件中的source代表着读取Linux源码中的其他Kconfig文件。
举个例子,顶层Kconfig文件中,source “drivers/Kconfig”
然后打开drivers/Kconfig文件可以看到,他的第一行是menu “Device Drivers”,这就是Device Drivers的菜单类,对应make menuconfig中的下图部分。
在这里插入图片描述
然后在dirvers/Kconfig文件中,source “drivers/block/Kconfig”,调用了drivers文件夹下的文件夹中的一个Kconfig文件,相当于你menuconfig中点入Device Drivers,出现Block devices这一列。
在这里插入图片描述
6.在Kconfig中,模块定义为tristate表示三态,即可以选择“M”编译成模块或“空”不编译状态或“*”编译进内核。定义为bool只有两态,缺少了“M”状态。

Linux设备注册与驱动注册部分:

1.Linux系统中含有一个总线的概念,包括spi总线,platform总线等等,在总线上挂载了很多的设备,其中platform总线被称为虚拟总线,上面挂载了设备以及相关驱动,具体如下图所示。需要注意的是,在注册platform_driver代码的初始化中,存在probe函数,如果设备和驱动的name字段相同,那么将调用probe函数。
在这里插入图片描述
2.注册platform_driver驱动代码:
首先定义了模块初始化module_init()以及module_exit()函数,作为模块的入口以及出口。

然后定义了初始化和卸载函数hello_init()以及hello_exit(),在hello_init()中调用了注册函数platform_driver_register(),在hello_exit()中调用了移除注册函数platform_driver_unregister()(platform_driver_register以及unregister()在头文件platform_device.h中有定义)

之后由于platform_driver_register()函数中需要参数platform_driver的结构体(这个在头文件platform_device.h中也有定义),所以需要定义这个结构体,platform_driver结构体有一个device_driver的结构体参数(在device.h中有定义),这个变量一般只需定义name以及owner,其中name为驱动名称,owner一般填THIS_MODULE。

最后是定义了platform_driver结构体中所需的probe变量,这个是driver的初始化代码。

3.注册platform_device设备代码
首先定义了模块初始化module_init()以及module_exit()函数,作为模块的入口以及出口。

然后定义了初始化和卸载函数hello_init()以及hello_exit(),在hello_init()中调用了注册函数platform_device_register(),在hello_exit()中调用了移除注册函数platform_device_unregister()(platform_device_register以及unregister()在头文件platform_device.h中有定义)

之后由于platform_device_register()中需要参数platform_device的结构体(这个在头文件platform_device.h中也有定义),所以需要定义这个结构体,这个结构体中一般只需要定义name以及id,name为设备名称,如果只有一个设备的话设备id一般为-1。同时,在platform_device结构体中有一个device结构体的变量(这个在头文件device.h中有定义),由于在unregister()中会调用一个release函数因此在platform_device结构体中还需要定义一个release函数,这个函数在这个device结构体的release变量中的。

4.驱动获取注册设备的id号代码
首先,整体代码与之前的platform_driver中大致是一样的,但需要注意注册driver的name要和注册device的name保持一致,这样就会进入初始化probe函数,在probe里就可以获得到注册设备的信息。

5.注册miscdevice设备代码:
首先定义了模块初始化module_init()以及module_exit()函数,作为模块的入口以及出口。

然后定义了初始化和卸载函数led_init()以及led_exit(),在led_init()中调用了注册函数misc_register(),在led_exit()中调用了移除注册函数misc_deregister()(misc_register以及deregister()在头文件miscdevice.h中有定义)

之后由于misc_register()中需要参数miscdevice的结构体(这个在头文件miscdevice.h中也有定义),所以需要定义这个结构体,这个结构体中一般只需要定义minor,name以及fops,name为设备名称,minor为设备号,一般定义为MISC_DYNAMIC_MINOR(随机取值,让系统分配设备号),fops结构体在linux/fs.h中有定义,是指向一个设备节点文件

最后需要定义一下fops的结构体,参数很多,根据需求选择,必选的参数是owner,open,以及release,owner一般填THIS_MODULE,open变量需要定义打开文件的操作函数,release变量需要定义关闭文件的操作函数,此外还有文件使用参数unlock_ioctl,这个是对GPIO的操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
·Linux设备驱动程序学习(1)-字符设备驱动程序 ·Linux设备驱动程序学习(0)-设备驱动介绍& Hello, world!模块 ·Linux设备驱动程序学习(2)-调试技术 ·Linux设备驱动程序学习(3)-并发和竞态 ·Linux设备驱动程序学习(4)-高级字符驱动程序操作[(1)ioctl and llseek] ·Linux设备驱动程序学习(5)-高级字符驱动程序操作[(2)阻塞型I/O和休眠] ·Linux设备驱动程序学习(6)-高级字符驱动程序操作[(3)设备文件的访问控制] ·Linux设备驱动程序学习(7)-内核的数据类型 ·Linux设备驱动程序学习(9)-与硬件通信 ·Linux设备驱动程序学习(8)-分配内存 ·Linux设备驱动程序学习(10)-时间、延迟及延缓操作 ·Linux设备驱动程序学习(11)-中断处理 ·Linux设备驱动程序学习(3-补)-Linux中的循环缓冲区 ·Linux设备驱动程序学习(12)-Linux设备模型(底层原理简介) ·Linux设备驱动程序学习(13)-Linux设备模型(总线、设备、驱动程序和类) ·Linux设备驱动程序学习(14)-Linux设备模型(各环节的整合) ·Linux设备驱动程序学习(15)-Linux设备模型(热插拔、mdev 与 firmware) ·Linux设备驱动程序学习(16)-USB 驱动程序(一) ·Linux设备驱动程序学习(17)-USB 驱动程序(二) ·Linux设备驱动程序学习(18)-USB 驱动程序(三) ·Linux设备驱动程序学习(19)-USB 驱动程序(四)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值