字符设备驱动

1.字符设备驱动概述

Linux用户空间与内核空间之间的虚拟内存是分开的,用户空间不能直接写入内核空间,如果用户空间和内核空间需要传递数据就需要字符设备驱动。

2.结构体以及函数介绍

(1)字符设备空间结构体:

字符设备驱动字符设备驱动
1 static const struct file_operations chrdev_fops =
2 {
3   .owner = This_MODULE,
4   .read = chrdev_read,
5   .write = chrdev_write,
6   .open = chrdev_open,
7   .release = chrdev_release
8 };

View Code

(2)打开和释放函数:

字符设备驱动字符设备驱动
1 static int chrdev_open(struct inode *inode, struct file *filp)
2 {
3     printk(KERN_INFO "chrdev opened\n");
4
5     return 0;
6 }

View Code

字符设备驱动字符设备驱动
1 static int chrdev_release(struct inode *inode, struct file *filp)
2 {
3     printk(KERN_INFO "chrdev released\n");
4
5     return 0;
6 }

View Code

(3) 读写函数:

字符设备驱动字符设备驱动
1 static ssize_t chrdev_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
2 {
3     printk(KERN_INFO "return EOF\n");
4
5     return 0;
6 }

View Code

字符设备驱动字符设备驱动
1 static ssize_t chrdev_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
2 {
3     printk(KERN_INFO "got %ld bytes\n", count);
4
5     return count;
6 }

View Code

对于这两个方法,filp是文件指针,count是请求的数据传输的大小。buf参数指向保存要写的数据的用户缓冲区,或者指向应该放置新读取数据的空缓冲区。最后,ppos是指向 “long offset type” 对象的指针,该对象指示用户正在访问的文件位置。返回值是一个”signed size type”。这是最基本的函数结构,但是如果这个函数只是一个空壳,并不能实现读写。

就数据传输而言,与这两种设备方法相关的主要问题是需要在内核地址空间和用户地址空间之间传输数据。该操作不能以通常的方式通过指针执行,也不能通过memcpy执行。由于一些原因,用户空间地址不能直接在内核空间中使用。

内核空间地址和用户空间地址之间的一个重要区别是,用户空间中的内存可以交换出去。当内核访问一个用户空间指针时,相关的页面可能不会出现在内存中,并且会生成一个页面错误。即使在CPU在内核空间执行时,也能正确地处理页面错误。

另外,有趣的是,Linux 2.0的x86端口为用户空间和内核空间使用了完全不同的内存映射。因此,用户空间指针根本不能从内核空间取消引用。如果目标设备是一个扩展板而不是RAM,那么同样的问题就会出现,因为驱动程序必须在用户缓冲区和内核空间之间(也可能在内核空间和I/O内存之间)复制数据。

在Linux中,跨空间副本是通过中定义的特殊函数来执行的。这种复制可以通过通用(类似于memcpy)的函数执行,也可以通过针对特定数据大小(char、short、int、long)进行优化的函数执行。

scull中的读写代码需要将整个数据段复制到用户地址空间或从用户地址空间复制数据段。该功能由以下内核函数提供,这些函数复制任意的字节数组,并位于每次读写实现的核心:

字符设备驱动字符设备驱动
1 unsigned long copy_to_user(void *to, const void *from, unsigned long count);

View Code

字符设备驱动字符设备驱动
1 unsigned long copy_from_user(void *to, const void *from, unsigned long count);

View Code

参考链接:https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch03s08.html

Original: https://www.cnblogs.com/vivianwenwen/p/12665738.html
Author: 温昀
Title: 字符设备驱动

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585245/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Rabbitmq安装与部署

    安装包otp_src_22.3.tar.gz,下载到部署服务器tar -zxvf解压 mv otp_src_22.3 ./erlang变更文件夹名字 可能需要安装的依赖包 yum …

    Linux 2023年5月27日
    0102
  • 1.2

    数字信号为什么不能远程传播?高频率->传的短 容易被干扰 答案是可以的。 数字信号传输编码的目的:保证数据传送的可靠性 数据传输的关键指标: 延迟和吞吐量 posted @2…

    Linux 2023年6月6日
    098
  • 配置phpstorm支持less自动编译css

    安装node.js 安装less npm install less -g 安装css压缩插件less-plugin-clean-css(此步骤非必选) npm install le…

    Linux 2023年6月13日
    096
  • Log4j 日志框架

    Log4j(Log for java)是 Apache 的一个开源项目,通过使用 Log4j,可以控制日志信息输送的目的地是控制台或文件等,也可以控制每一条日志的输出格式。通过定义…

    Linux 2023年6月8日
    0142
  • Vue3

    setup 函数时,它将接受两个参数:(props、context(包含attrs、slots、emit)) setup函数是处于 生命周期函数 beforeCreate 和 Cr…

    Linux 2023年6月13日
    089
  • cpp-base

    1.cin&cout 2.两种注释方式 //注释方法1,’//’。用于单行注释 /* 注释方法2, 用于多行注释 */ 特别&a…

    Linux 2023年6月7日
    0107
  • [云原生]Kubernetes-数据存储(第8章)

    一、基本存储 1.1 EmptyDir 1.2 HostPath 1.3 NFS 二、高级存储 2.1 PV 2.2 PVC 2.3 生命周期 三、配置存储 3.1 ConfigM…

    Linux 2023年6月13日
    077
  • Django中信号的使用

    信号种类及用法 Django中提供了”信号调度”,用于在框架执行操作时解耦. 一些动作发生的时候,系统会根据信号定义的函数执行相应的操作 Django中内置…

    Linux 2023年6月14日
    0103
  • DOS 解决不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接用–拓展—》批处理访问服务器共享文件夹,BAT命令连接局域网机子并打开文件夹

    解决不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接用–拓展—》批处理访问服务器共享文件夹,BAT命令连接局域网机子并打开文件夹 问题描述:…

    Linux 2023年6月13日
    084
  • css或html中添加空格

    posted @2022-08-03 16:31 七窍玲珑心 阅读(8 ) 评论() 编辑 Original: https://www.cnblogs.com/lzh93/p/16…

    Linux 2023年6月13日
    0116
  • powershell配置自动补全

    powershell配置自动补全 一、需求: 看到老师上课用mac命令行有自动补全功能,发现真的爽。但是自己的windows powershell不能使用自动补全功能。有了需求,就…

    Linux 2023年6月13日
    0137
  • 学习一下 JVM (二) — 学习一下 JVM 中对象、String 相关知识

    一、JDK 8 版本下 JVM 对象的分配、布局、访问(简单了解下) 1、对象的创建过程 (1)前言Java 是一门面向对象的编程语言,程序运行过程中在任意时刻都可能有对象被创建。…

    Linux 2023年6月11日
    0112
  • Android recovery支持adb shell

    Android recovery支持adb shell 近期开发过程注意到recovery不支持adb shell。为了便于调试方便,决定添加此功能。 刚開始我们採用的是user版…

    Linux 2023年5月28日
    0105
  • 安卓开发封装处理Retrofit协程请求中的异常

    上篇文章讲解了怎么使用 Kotlin的协程配合 Retrofit发起网络请求,使用也是非常方便,但是在处理请求异常还不是很人性化。这篇文章,我们将处理异常的代码进行封装,以便对异常…

    Linux 2023年6月8日
    0111
  • centos挂载windows共享目录

    背景 在linux环境下访问远程windows的共享目录,将windows上的目录挂载到linux目录下。如下图: 一、windows上新建共享文件夹 windows设置共享目录 …

    Linux 2023年6月6日
    0108
  • Linux系统僵尸进程详解

    大安好,我是良许。 在本文中,我们将讨论什么是僵尸进程,如何创建僵尸进程,以及如何终止僵尸进程。 [En] In this article, we will discuss wha…

    Linux 2023年5月27日
    0106
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球