20230615整理(字符设备驱动的内部实现)

1.1 字符设备:

        以字节流的形式进行访问,而且只能顺序访问的设备叫做字符设备(比如键盘、鼠标)

        (块设备:有固定访问大小,可以不按顺序访问的设备,比如U盘、硬盘)

        针对字符设备编写的驱动叫做字符设备驱动

1.2 当设备驱动注册进内核,内核会分配给当前驱动一个编号,即设备号

        设备号=主设备号<<20 | 次设备号 (主设备号左移20个字符,按位或上次设备号)

      当注册驱动后得到驱动对应的设备号,基于这个设备号在文件系统中创建了一个文件,完成了设备文件和设备驱动的关联,当在用户空间操作设备时,也就可以访问到设备驱动了。

1.3  字符设备驱动在内核中的注册和注销API

        1>    int register_chardev(major,"mycdev",&fops)

                功能:实现字符设备驱动向内核的注册。这个函数申请了256个设备的资源,次设备号的范围:0~255

                major:注册的驱动的主设备号,如果major==0,内核自动分配一个主设备号;

                                                                  如果major>0,由驱动开发者静态指定一个主设备号

                "mycdev":注册的字符设备驱动的名字

                fops:操作方法结构体指针

                返回值:如果major==0,成功返回注册的驱动的主设备号,失败返回<0的错误码

                              如果major>0,成功返回0,失败返回<0的错误码

        2>        void unregister_chrdev(major,"mycdev")

                     功能:实现字符设备驱动的注销

        3>        为字符设备驱动创建设备文件

                  sudo mknod /dev/mycdev c major 0

                  /dev/mycdev:创建的设备文件的名字及路径

                major:主设备号

                0:次设备号(0~255均可)

字符设备驱动的内部实现

2.1 字符设备驱动内部实现原理图:

 open函数通过路径打开文件时,虚拟文件系统层的sys_open根据路径找到文件的inode结构体

在struct——inode结构体中有成员i_rev(设备号)和共用体union,union中有结构体参数struct_cdev

struct_cdev中有设备号和struct file_operations结构体,struct file_operations结构体中,open就是操作方法之一

2.2 字符设备驱动分步注册流程及API

        1> 为字符设备驱动对象申请空间

                无参函数:cdev_alloc();成功返回申请空间首地址,失败返回NULL

        2> 字符设备驱动对象的初始化

                void cdev_init(cdev,&fops)

                cdev:字符设备驱动对象指针         fops:操作方法结构体指针

        3> 申请设备号,有两种情况

                i> major>0,静态指定设备号

                        register_chrdev_region(MKDEV(major,minor),n,"myled")

                        功能:静态指定设备号

                        MKDEV:要申请的设备号

                        n:要申请的设备资源的数量(次设备号数量)

                        "myled":驱动名称

                        返回值:成功返回0,失败返回错误码

                ii> major==0,动态申请一定范围的设备号

                        alloc_chrdev_region(&devno,minor,n,"myled")

                        功能:动态申请一定范围的设备号

                        &devno:申请的设备号在这个变量中

                        minor:次设备号的起始值

                        n:申请的设备资源的数量(次设备号数量)

                        “myled”:驱动名称

        4> 将字符设备驱动对象注册进内核

                 cdev_add(cdev,MKDEV(major,minor),n)

                        cdev:字符设备启动对象指针

                        MKDEV:申请的设备号

                        n:次设备数量

                        返回值:成功返回0,失败返回错误码

        5> 字符设备驱动对象的注销

                cdev_del(cdev)

                        cdev:字符设备驱动对象指针

                        返回值:无

        6> 释放申请的设备号

                unregister_chrdev_region(MKDEV(major,minor),n)

                MKDEV:申请的设备号

                n:设备的数量

        7> 释放对象空间

                kfree(cdev)                cdev:对象空间首地址

                

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值