嵌入式——初步了解驱动注册新旧接口源码分析

5.3.5.字符设备驱动注册代码分析1
5.3.5.1、老接口分析

register_chrdev     默认此设备号为0
    __register_chrdev               并且传入子设备号的起始为0,最大子设备数为256
        __register_chrdev_region    注册主次设备号的
        cdev_alloc
        cdev->owner = fops->owner; //这两行赋值就等效于cdev_init函数完成的任务
        cdev->ops = fops;
        cdev_add        注册驱动

5.3.5.2、新接口分析

register_chrdev_region
    __register_chrdev_region
cdev_alloc
cdev_init
cdev_add
alloc_chrdev_region
    __register_chrdev_region    传入major=0;进行内核自动分配的处理。
cdev_alloc
cdev_init
cdev_add

再对比旧新接口,在本质上做的任务其实是一样的。

struct char_device_struct  //整个设备驱动,驱动加设备号,这个是直接放在内核管理数组里面的struct char_device_struct *next;//链表用来连接子设备
    unsigned int major;主设备号
    unsigned int baseminor;次设备号的起始标号
    int minorct;最小的次设备号数
    char name[64];名字,也就我们对驱动命名不能超过64个字节
    struct cdev *cdev;   指向表示驱动的结构体
    这个结构体就表示一个主次设备驱动,
}*chrdevs[CHRDEV_MAJOR_HASH_SIZE];  

chrdevs这个结构体指针数组就是内核用来管理设备驱动的数组,各个驱动用char_device_struct表示,并将其首地址放到chrdevs数组中。CHRDEV_MAJOR_HASH_SIZE这个大小255也就证明前面cat /proc/devices中从0到255,一个内核支持256个设备驱动。

struct cdev {   //只表示设备驱动,未含设备号
    struct kobject kobj; 计数 用来表示该设备驱动被使用了几次,使用一次加1,使用完一次减一,每次减法都与0进行对比,来查看是否还人使用该设备驱动,如果没有则可以释放申请来的驱动内存,因为之前是使用内核申请堆内存来存放的,因此引入计数来表示是否要进行是否内存
    struct module *owner;表示代表一个内核模块
    const struct file_operations *ops;基本是一些函数指针指向驱动中实现的一些函数open...
    struct list_head list;链表
    dev_t dev;主次设备号,可以用三个宏来拆分合并  MKDEV,MAJOR,MINOR;
    unsigned int count;子设备的数量
};

__register_chrdev_region。传入主设备号,次设备号起始,次设备号数量,名字。作用就是注册设备号,返回一个structchar_device_struct*。表示内部申请堆内存存放结构体,返回首地址。
分析内部
cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);果然申请了堆内存来存放结构体
处理了如果由内核分配major==0时的处理,然后再合并。内部就是完成对char_device_struct结构体元素的赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值