zoukankan      html  css  js  c++  java
  • 4. read()、write() 相关函数解析

    我们在前面讲到了file_operations,其是一个函数指针的集合,用于存放我们定义的用于操作设备的函数的指针,如果我们不定义,它默认保留为NULL。其中有最重要的几个函数,分别是open()、read()、write()、ioctl(),下面分别对其进行解析

    一、 打开和关闭设备函数a -- 打开设备

    int (*open) (struct inode *, struct file );
    在操作设备前必须先调用open函数打开文件,可以干一些需要的初始化操作。当然,如果不实现这个函数的话,驱动会默认设备的打开永远成功。打开成功时open返回0。b -- 关闭设备
    int (
    release) (struct inode *, struct file *);
    当设备文件被关闭时内核会调用这个操作,当然这也可以不实现,函数默认为NULL。关闭设备永远成功。这两个函数已经讲过,这里不再赘述,主要看下面几个函数

    二、read()、write() 函数

    现在把 read()、write() 两个函数放一起讲,因为两个函数非密不可分的,先看一下两个函数的定义
    a -- read() 函数

    b -- write() 函数

    两个函数的作用分别是 从设备中获取数据及发送数据给设备,应用程序中与之对应的也有 write() 函数及 read() 函数:

    我们知道,应用程序工作在用户空间,而驱动工作在内核空间,二者不能直接通信的,那我们用何种方法进行通信呢?下面介绍一下内核中的memcpy---copy_from_user和copy_to_user,虽然说内核中不能使用C库提供的函数,但是内核也有一个memcpy的函数,用法跟C库中的一样。

    可以看到两个函数均是调用了_memcpy() 函数:

    既然拷贝的功能__memcpy函数就可以实现,为什么还要封装成copy_to_user和copy_from_user。
    因为_memcpy有缺陷,比如当我们在引用层调用函数是传入的不是字符串,而是一个不能访问否则修改的地址。那样就会造成系统崩溃。
    出于上面的原因,内核和用户态之间交互的数据时必须要先对数据进行检测,如果数据是安全的,才可以进行数据交互。
    上面的函数就是memcpy的改进版,在memcpy功能的基础上加上的检查传入参数的功能,防止有些人有意或者无意的传入无效的参数。

    现在我们可以审视一下这两个函数了:

    用法:和memcpy的参数一样,但它根据传参方向的不同分开了两个函数。
    "to"是相对于内核态来说的。所以,to函数的意思是从from指针指向的数据将n个字节的数据传到to指针指向的数据。
    "from"也是相对于内核来说的。所以,from函数的意思是从from指针指向的数据将n个字节的数据传到to指针指向的数据。
    返回值:函数的返回值是指定要读取的n个字节中还剩下多少字节还没有被拷贝。
    注意:一般的,如果返回值不为0时,调用copy_to_user的函数会返回错误号-EFAULT表示操作出错。当然也可以自己决定。到这里open、close、read、write四个函数已经学完,
    下面我们来看一下四个函数使用时,到底经历了一个怎样的过程:注:箭头方向是从调用的一方指向受作用的一方
    代理****

  • 相关阅读:
    SpringCloud Zipkin快速开始
    Spring-Cloud-Gateway Predicate谓词(断言)使用与自定义
    Gateway Redis令牌桶请求限流过滤器
    SpringBoot集成logback日志组件
    Java使用Aspose-Words实现Word转换Pdf
    JAVA通过Map拼接SQL语句(Insert Update语句)
    使用Java反射机制将Bean对象转换成Map(驼峰命名方式 — 下划线命名方式)
    mybatis执行原生sql
    windows环境下elasticsearch安装教程(超详细)
    购物车的原理及Java实现(仿京东实现原理)
  • 原文地址:https://www.cnblogs.com/Ocean-Star/p/9249889.html
Copyright © 2011-2022 走看看