前言
平时我们写Linux驱动和用户空间交互时,都是通过copy_from_user
把用户空间传过来的数据进行拷贝,为什么要这么做呢?copy_from_user
把用户空间传过来的数据进行拷贝,为什么要这么做呢?
因为用户空间是不能直接内核空间数据的,他们映射的是不同的地址空间,只能先将数据拷贝过来,然后再操作。
如果用户空间需要传几MB的数据给内核,那么原来的拷贝方式显然效率特别低,也不太现实,那怎么办呢?
想想,之所以要拷贝是因为用户空间不能直接访问内核空间,那如果可以直接访问内核空间的buffer,是不是就解决了。
简单来说,就是让一块物理内存拥有两份映射,即拥有两个虚拟地址,一个在内核空间,一个在用户空间。关系如下:

通过mmap
映射就可以实现。
应用层
应用层代码很简单,主要就是通过mmap
系统调用进行映射,然后就可以对返回的地址进行操作。
char * buf; /* 1. 打开文件 */ fd = open("/dev/hello", O_RDWR); if (fd == -1) { printf("can not open file /dev/hello\n"); return -1; } /* 2. mmap * MAP_SHARED : 多个APP都调用mmap映射同一块内存时, 对内存的修改大家都可以看到。 * 就是说多个APP、驱动程序实际上访问的都是同一块内存 * MAP_PRIVATE : 创建一个copy on write的私有映射。 * 当APP对该内存进行修改时,其他程序是看不到这些修改的。 * 就是当APP写内存时, 内核会先创建一个拷贝给这个APP, * 这个拷贝是这个APP私有的, 其他APP、驱动无法访问。 */ buf = mmap(NULL, 1024*8, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
mmap
的第一个参数是想要映射的起始地址,通常设置为NULL
因为用户空间是不能直接内核空间数据的,他们映射的是不同的地址空间,只能先将数据拷贝过来,然后再操作。

mmap
映射就可以实现。🎜🎜🎜🎜🎜应用层🎜🎜 🎜🎜🎜应用层代码很简单,主要就是通过mmap
🎜系统调用🎜进行映射,然后就可以对返回的地址进行操作。🎜int remap_pfn_range( struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot);🎜
mmap
的第一个参数是想要映射的起始地址,通常设置为NULL
,🎜表示由内核来决定该起始地址🎜。🎜第二参数是要映射的内存空间的大小。
第三个参数PROT_READ | PROT_WRITE
表示映射后的空间是PROT_READ | PROT_WRITE
表示映射后的空间是可读可写的。
第四个参数可填MAP_SHARED
或MAP_PRIVATE
可读可写
MAP_SHARED
或MAP_PRIVATE
:🎜MAP_SHARED
:多个APP
都调用mmap
映射同一块内存时, 对内存的修改大家都可以看到。就是说多个APP
、驱动程序实际上访问的都是同一块内存。
MAP_SHARED
:多个APP
都调用mmap
映射同一块内存时, 对内存的修改大家都可以看到。就是说多个APP
、驱动程序实际上访问的都是同一块内存。MAP_PRIVATE
:创建一个copy on write
的私有映射。当APP
对该内存进行修改时,其他程序是看不到这些修改的。就是当APP
写内存时, 内核会先创建一个拷贝给这个APP
,这个拷贝是这个APP
🎜MAP_PRIVATE
:创建一个copy on write
的私有映射。当APP
对该内存进行修改时,其他程序是看不到这些修改的。就是当APP
写内存时, 内核会先创建一个拷贝给这个APP
,这个拷贝是这个APP
私有的, 其他APP、驱动无法访问。驱动层
驱动层主要是实现mmap
接口,而mmap
接口的实现,主要是调用了remap_pfn_range
函数,函数原型如下:
int remap_pfn_range( struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot);
vma
:描述一片映射区域的结构体指针
addr
:要映射的虚拟地址起始地址
pfn
:物理内存所对应的页框号,就是将物理地址除以页大小得到的值
size
:映射的大小
prot
:该内存区域的访问权限
驱动主要步骤:
1、使用kmalloc
或者kzalloc
函数分配一块内存kernel_buf
,因为这样分配的内存物理地址是连续的,mmap
后应用层会对这一个基地址去访问这块内存。
2、实现mmap函数
static int hello_drv_mmap(struct file *file, struct vm_area_struct *vma) { /* 获得物理地址 */ unsigned long phy = virt_to_phys(kernel_buf);//kernel_buf是内核空间分配的一块虚拟地址空间 /* 设置属性:cache, buffer*/ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); /* map */ if(remap_pfn_range(vma, vma->vm_start, phy>>PAGE_SHFIT, vma->vm_end - vma->start, vma->vm_page_prot)){ printk("mmap remap_pfn_range failed\n"); return -ENOBUFS; } return 0; } static struct file_operations my_fops = { .mmap = hello_drv_mmap, };
1、通过virt_to_phys
将虚拟地址转为物理地址,这里的kernel_buf
是内核空间的一块虚拟地址空间
2、设置属性:不使用cache,使用buffer
3、映射:通过remap_pfn_range
函数映射,phy>>PAGE_SHIFT
其实就是按page
映射,除了这个参数,其他的起始地址、大小和权限都可以由用户在系统调用函数中指定。
当应用层调用mmap
后,就会调用到驱动层的mmap
函数,最终应用层的虚拟地址和驱动中的物理地址就建立了映射关系,应用层也就可以直接访问驱动的buffer了。
以上是Linux驱动IO篇——mmap操作的详细内容。更多信息请关注PHP中文网其他相关文章!

维护模式在Linux系统管理中扮演关键角色,帮助进行系统修复、升级和配置变更。1.进入维护模式可以通过GRUB菜单选择或使用命令“sudosystemctlisolaterescue.target”。2.在维护模式下,可以执行文件系统修复和系统更新等操作。3.高级用法包括重置root密码等任务。4.常见错误如无法进入维护模式或挂载文件系统,可通过检查GRUB配置和使用fsck命令修复。

使用Linux维护模式的时机和原因:1)系统启动问题时,2)进行重大系统更新或升级时,3)执行文件系统维护时。维护模式提供安全、控制的环境,确保操作的安全性和效率,减少对用户的影响,并增强系统的安全性。

Linux中不可或缺的命令包括:1.ls:列出目录内容;2.cd:改变工作目录;3.mkdir:创建新目录;4.rm:删除文件或目录;5.cp:复制文件或目录;6.mv:移动或重命名文件或目录。这些命令通过与内核交互执行操作,帮助用户高效管理文件和系统。

在Linux中,文件和目录管理使用ls、cd、mkdir、rm、cp、mv命令,权限管理使用chmod、chown、chgrp命令。1.文件和目录管理命令如ls-l列出详细信息,mkdir-p递归创建目录。2.权限管理命令如chmod755file设置文件权限,chownuserfile改变文件所有者,chgrpgroupfile改变文件所属组。这些命令基于文件系统结构和用户、组系统,通过系统调用和元数据实现操作和控制。

MaintenancemodeInuxisAspecialBootenvironmentforforcalsystemmaintenancetasks.itallowsadMinistratorStoperFormTaskSlikerSettingPassingPassingPasswords,RepairingFilesystems,andRecoveringFrombootFailuresFailuresFailuresInamInimAlenimalenimalenrenmentrent.ToEnterMainterMainterMaintErmaintErmaintEncemememodeBoode,Interlecttheboo

Linux的核心组件包括内核、文件系统、Shell、用户空间与内核空间、设备驱动程序以及性能优化和最佳实践。1)内核是系统的核心,管理硬件、内存和进程。2)文件系统组织数据,支持多种类型如ext4、Btrfs和XFS。3)Shell是用户与系统交互的命令中心,支持脚本编写。4)用户空间与内核空间分离,确保系统稳定性。5)设备驱动程序连接硬件与操作系统。6)性能优化包括调整系统配置和遵循最佳实践。

Linux系统的五个基本组件是:1.内核,2.系统库,3.系统实用程序,4.图形用户界面,5.应用程序。内核管理硬件资源,系统库提供预编译函数,系统实用程序用于系统管理,GUI提供可视化交互,应用程序利用这些组件实现功能。

Linux的维护模式可以通过GRUB菜单进入,具体步骤为:1)在GRUB菜单中选择内核并按'e'编辑,2)在'linux'行末添加'single'或'1',3)按Ctrl X启动。维护模式提供了一个安全环境,适用于系统修复、重置密码和系统升级等任务。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

WebStorm Mac版
好用的JavaScript开发工具

Dreamweaver CS6
视觉化网页开发工具