• Linux内核register_chrdev挂载驱动详解


      通过内核源码树编译得到的xxx.ko驱动下载到sd卡中,启动内核进入系统用insmod xxx.ko安装驱动,该命令会调用

    module_init(chrdev_init)中指定的chrdev_init函数,在该函数里我们调用register_chrdev来进行注册,注册会申请以下三个结构体

    char_device_struct,驱动程序描述符cdev,probe结构体来对应一个驱动程序

    1  char_device_struct:

         一个驱动程序有一个设备号范围,在该设备号范围的设备文件都会使用该驱动程序,将对应该驱动程序的char_device_struct

         根据主设备号的hash值插入chrdevs数组,这是纵向插入,在其横向链表的插入过程中我们根据其设备号范围的大小将其小

         在前大在后进行插入,结构体中cdev指向驱动程序描述符cdev

    2  驱动程序描述符cdev

        cdev中ops指向我们传入的file_operations结构体,

    3  probe结构体 (用来根据设备号查找cdev)

        内核中有段内存被cdev_map指向又来存储probe结构体的指针,与char_device_struct的存储方式相同,

        probe中data指向cdev

      通过 /proc/devices目录以及lsmod命令可以查看注册情况。

    注册完成后创建设备文件:

        mknod /dev/testchar c 250 0  只要改设备号在该驱动对应的设备号范围就会调用该驱动

    下面分析mknod /dev/testchar c 250 0

      系统调用会调用vfs_mknod(nd.path.dentry->d_inode,dentry,mode,new_decode_dev(dev));第一个参数为目录dev的inode

      第二个参数为新建的testchar的目录项,该函数又会调用dev目录的inode的mknod方法找到该方法为ramfs_mknod

      得到设备文件的inode且inode->i_fop = &def_chr_fops; inode->i_rdev = rdev;这样我们就完成了设备文件的创建

    下面open("/dev/testchar", O_RDWR)分析打开设备文件的过程:

      SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode)

      ————do_sys_open(AT_FDCWD, filename, flags, mode);

           ————struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);

              ————do_last

                  ————finish_open

                      ————nameidata_to_filp

                          ————__dentry_open

          ————fd_install

    __dentry_open中我们将设备文件的节点的 i_fop赋给file结构体的 f_op 并执行其 open方法,我们创建设备文件时知道

    设备文件的 inode->i_fop = &def_chr_fops,执行open即chrdev_open,该函数中我们根据inode->i_rdev即设备号在cdev_map

    中查找对应的设备驱动程序描述符cdev并赋值给inode->i_cdev,将cdev中的ops赋给filp->f_op并执行其open方法

    fd_install将文件描述符与file结构体绑定,此后IO文件操作将会调用驱动程序

    使用新接口 register_chrdev_region/alloc_chrdev_region 注册分析:

    操作   register_chrdev_region  cdev_init  cdev_add

    新接口和老接口注册方式差不多

    register_chrdev_region  注册 char_device_struct

    cdev_init    初始化驱动程序描述符 cdev

    cdev_add    向 cdev_map 注册 probe结构体

  • 相关阅读:
    Java关键字new和newInstance的区别
    关于能提高Java代码可重用性的三个措施
    Java编程技巧—— JDBC编程总结
    Java高质量代码之数组与集合
    ab的压力测试(转)
    利用DOCKER实现云桌面的开发环境初步设想
    时间和日期
    内存流-操作文件的方式操作内存
    获取文件描述符
    流定位
  • 原文地址:https://www.cnblogs.com/genshu123/p/11834634.html
Copyright © 2020-2023  润新知