LinuxGod

LinuxGod.net
Linux大神网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

3.3.mmap完成物理地址映射到用户虚拟地址空间上文件对应硬件外设

2022年12月4日 356点热度

3.3.mmap地址映射方法

明确:mmap就是完成物理地址映射到用户虚拟地址用的

明确:用户3G虚拟地址空间划分:

0x00000000-------------------------------------------------------0xBFFFFFFF

代码段 数据段 BSS段 堆区 MMAP虚拟内存区 栈区

---->

1.回顾mmap系统调用函数

函数原型:

void *mmap(void *addr, size_t length,

int prot, int flags,

int fd, off_t offset);

函数功能:将物理地址空间映射到用户虚拟内存空间上

将物理地址映射到用户虚拟地址

老王课程这么讲:将文件映射到用户虚拟地址空间上

文件对应硬件外设,外设通过物理地址访问

linux系统不允许访问物理地址,利用mmap映射不得了

参数:

addr:给NULLlinux 驱动通知应用层,让linux内核帮你在用户虚拟内存区域找一块

空间内存用来映射物理地址

length:让linux内核帮你找的空闲用户虚拟内存的大小

切记:大小必须是页面大小(4KB)的整数倍

prot:描述内核帮你找的空闲用户虚拟内存的访问权限

一般指定为:PROT_READ|PROT_WRITE

flags:其余属性,一般指定为:MAP_SHARED

fd:硬件外设

linux 驱动通知应用层_开发linux应用--用gtk+和gdk开发linux图形用_dz全站弹出层通知

offset:偏移量,一般给0

返回值:linux内核将空闲的用户虚拟内存的首地址进行返回

这个起始用户虚拟地址同样也是4KB整数倍

参考代码:

void *addr;

int fd = open("a.txt", O_RDWR);

addr = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE,

MAP_SHARED, fd, 0);

说明:将文件a.txt映射到以addr起始的用户虚拟内存上

将来访问映射的用户虚拟内存就是访问文件

//向映射的用户虚拟内存拷贝字符串数据

本质是向文件a.txt写入数据

memcpy(addr, "hello,world", 12);

2.了解mmap系统调用函数所做的工作:

2.1.应用程序调用mmap,首先跑到C库的mmap函数定义

2.2.C库的mmap函数作两件事:

1.保存mmap系统调用号到r7寄存器

2.调用swi/svc指令触发软中断异常

2.3.一旦触发软中断异常,CPU核立马处理软中断异常

2.4.最后进程跑到内核空间继续运行,跑到软中断异常的入口地址

运行,做如下事情:

1.调用软中断异常处理函数,而此函数做两件事:

1.从r7寄存器中取出mmap系统调用号

2.以mmap系统调用号为下标在内核的系统调用表中

找到mmap对应的内核函数sys_mmap,而内核的

sys_mmap做三件事:

1.内核的sys_mmap首先在当前进程的3G虚拟地址空间中

找一块空闲的用户虚拟内存,将来用于和物理地址

做映射

2.一旦找到空闲的用户虚拟内存,并且用户mmap本身

也给用户虚拟内存指定了一堆的属性(大小,权限等)

所以内核用struct vm_area_struct数据结构定义

初始化一个对象来描述空闲的用户虚拟内存的属性

struct vm_area_struct {

unsigned long vm_start; //空间用户虚拟内存的起始地址

//等于mmap的返回值addr

unsigned long vm_end; //结束地址=vm_start+大小

pgprot_t vm_page_prot; //等于mmap传递的PROT_READ|PROT_READ|PROT_WRITE

unsigned long vm_flags; //等于mmap传递的MAP_SHARED

unsigned long vm_pgoff; //等于mmap传递的0

...

};

3.最后内核的sys_mmap调用底层驱动的mmap接口

并且内核sys_mmap将第2步创建的对象的地址

也传递给底层驱动的mmap接口

3.底层驱动mmap执行完毕,进程返回,至此mmap调用结束

3.对应的底层驱动的mmap接口

struct file_operations {

int (*mmap) (struct file *file,

struct vm_area_struct *vma);

dz全站弹出层通知_linux 驱动通知应用层_开发linux应用--用gtk+和gdk开发linux图形用

};

接口功能:永远只能唯一做一件事:将已知的物理地址和已知的

用户虚拟地址做映射,类似:媒婆

由于用户虚拟地址在用户空间,所以将来访问操作

都是在应用程序完成,而不是在内核驱动完成

访问映射的用户虚拟地址就是在访问物理地址

file:跟fd亲戚关系

vma:指向内核sys_mmap创建的一个对象,此对象来描述空闲的

用户虚拟内存的各种属性,将来底层驱动mmap接口利用

此指针可以获取到用户虚拟内存的属性:

vma->vm_start //获取起始用户虚拟地址

vma->vm_end

vma->vm_flags

vma->vm_page_prot

...

问:底层驱动的mmap接口到底如何最终完成映射呢?

因为已知物理地址可以看手册获取到

已知的用户虚拟地址通过vma指针能够获取到

如何将两者关联在一起呢?

万事俱备只欠东风

答:只需调用以下函数完成关联映射:

int remap_pfn_range(struct vm_area_struct *vma,

unsigned long addr,

unsigned long pfn,

unsigned long size,

linux 驱动通知应用层_dz全站弹出层通知_开发linux应用--用gtk+和gdk开发linux图形用

pgprot_t prot);

函数功能:完成最终的地址映射

vma:传递内核sys_mmap创建的对象地址

也就是传递驱动mmap接口的第二个参数

addr:传递空闲的用户虚拟内存的首地址

也就是传递vma->vm_start

pfn:传递起始的物理地址>>12

切记:此物理地址大小必须是4KB(0x1000)整数倍

例如:

0xC001C000>>12:合法

0xC001C004>>12:不合法

size:传递映射的用户虚拟内存的大小

也就是传递:vma->vm_end - vma->vm_start

prot:传递用户虚拟内存的访问权限

也就是传递:vma->vm_page_prot

案例:利用mmap实现开关灯操作

参考代码:day09/1.0

dz全站弹出层通知_开发linux应用--用gtk+和gdk开发linux图形用_linux 驱动通知应用层

linux 驱动通知应用层_开发linux应用--用gtk+和gdk开发linux图形用_dz全站弹出层通知

linux 驱动通知应用层_dz全站弹出层通知_开发linux应用--用gtk+和gdk开发linux图形用

4.世纪大PK:read,write,ioctl和mmap对比

什么时候用:read,write,ioctl

什么时候用: mmap

4.1.read,write,ioctl数据操作流程

对设备读操作:read,ioctl

开发linux应用--用gtk+和gdk开发linux图形用_linux 驱动通知应用层_dz全站弹出层通知

数据流:硬件寄存器----->内核缓冲区------->用户缓冲区

gpio_get_value copy_to_user

对设备写操作:write,ioctl

数据流:用户缓冲区----->内核缓冲区------->硬件寄存器

copy_from_user gpio_set_value

结论:read,writelinux 驱动通知应用层,ioctl数据操作势必要经过两次数据拷贝:

用户-内核->硬件

硬件->内核->用户

4.2.mmap数据操作流程:

对设备读操作: 应用程序直接以指针形式读取寄存器

data = *gpiocout;

对设备写操作: 应用程序直接以指针的形式写入寄存器

*gpiocout &= ~(1 硬件

硬件->用户

4.3.终极结论:

1.如果用户对硬件操作访问的数据量比较小,read,write,ioctl

的两次数据拷贝对系统性能肯定有影响,但是这种影响几乎

可以忽略不计,如果操作的数据量比较大,两次数据拷贝

性能的影响是致命的,例如:摄像头linux更改ip地址,LCD显示屏,声卡等

2.如果访问操作的数据量比较大linux 发邮件,用read,write,ioctl势必

影响系统的性能,务必采用mmap,将两次数据拷贝变成一次

提供系统的性能效率

3.由于mmap在使用的时候,分配的用户虚拟内存必须是4KB的

整数倍,如果操作的数据量比较小,此时还用mmap

即使提高了系统的性能(几乎体会不到),反而是浪费了

宝贵的内存资源

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: mmap 内存映射 对象关系映射 空间数据 虚拟内存
最后更新:2022年12月4日

Linux大神网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

Linux大神网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
Linux默认的最大文件描述符数量是1024 关于LinuxQt安装教程及配置的回答及解决办法的 MySQL8.0的f配置文件是管理MySQL服务器的重要文件 局域网聊天软件简单介绍TOP1内网通传书 ARM嵌入式Linux系统开发详解.rar 一说unix/linux中对于文件操作的这几个函数 如何利用linux来开发属于自己的嵌入式Linux操作系统 腦/網絡>操作系統/系統-alternate-i386.iso(EXT)这几个版本有什么区别 精通unixshell脚本编程之文件描述符数ulimitulimit-n ubuntu离线安装软件 鸿蒙OS环境搭建过程中遇到的问题及解决方案 写入数据覆盖的分析与执行 解读Rainbond集群的安装和运维的原理,便于用户搭建Rainbond Linux基础知识:文件描述符、文件指针、索引节点 如何解决Linux下的无线网卡驱动的问题? linux 文件描述符 (师)-unused-fdKernel:2.6.14CPUarchitecture Linux系统下如何搭建SVN服务器,详细说明各配置项的功能 修改软件源文件、UI界面设置换源操作|Ubuntu Ubuntu14.04.2为例进行说明,其它Ubuntu版本与此类似 Linux图形界面用户和Windows用户来说获取系统硬件信息都不算问题 Ubuntu下换内核的过程及详细分析内核操作分析
ubuntu离线安装软件 鸿蒙OS环境搭建过程中遇到的问题及解决方案精通unixshell脚本编程之文件描述符数ulimitulimit-n腦/網絡>操作系統/系統-alternate-i386.iso(EXT)这几个版本有什么区别如何利用linux来开发属于自己的嵌入式Linux操作系统一说unix/linux中对于文件操作的这几个函数ARM嵌入式Linux系统开发详解.rar局域网聊天软件简单介绍TOP1内网通传书MySQL8.0的f配置文件是管理MySQL服务器的重要文件关于LinuxQt安装教程及配置的回答及解决办法的Linux默认的最大文件描述符数量是1024C语言教程-Qt.12安装教程05-27Linux有7个运行级别(关机,停机模式、DellG3)(Linux基础知识)文件压缩、打包命令解析的Linux操作系统怎样执行?LinuxDNS服务器,如何安装、配置和维护它?AMD2950x+技嘉x399免驱USB网卡,我的无线网卡linux解压gz文件命令 蓝易云香港五网CN2网络压缩比率的测试环境Linux系统中用于管理和控制系统服务的强大工具介绍围绕API创建封装器的开源项目正变得越来越流行主频93.75MHz的MIPS64NECVR4300处理器在N64上运行
手动删除400多万个小文件,rm-删除执行不动 盘点一下目前主流的国产操作系统,你知道几个? 1.安装JDK安装目录要求安装和配置是否成功 LinuxTCP协议栈的内部机制和优化技术介绍 2.5创建和配置虚拟机2.5.1创建虚拟机双击桌面的VMwarePlayer 虚拟机安装Ubuntu操作系统-Ubuntu空间20G镜像下载 通过命令lsblk结果可判断sda3是个逻辑卷LV为根目录/ 阿里云>社区>主题地图S>查看存储推荐 如何查看linux查找文件夹命令(图)查看文件内容 如何在Ubuntu22.04上安装VSFTPD以设置服务服务器? STM32USB转串口指令的情况SSCom用起来不错了 Linux上你真的需要Homebrew包管理器吗?怎么办? 设置需要执行的脚本新增调度任务可用两种方法介绍 一下美国Linux服务器的系统优化优化方法方法 Linux上的防火墙和地址命令使用WinSCP 3.3.mmap完成物理地址映射到用户虚拟地址空间上文件对应硬件外设 #java#javac-version有版本输出说明安装成功案例 netstat命令各个端口-u:指明显示显示UDP端口及进程服务 linux基础命令注意:Linux命令区分大小写,小心输入内容 软件介绍deepinlinux最新正版是深度推出的开源操作系统
标签聚合
命令模式 操作 sudo 软件 linux服务器 文件 linux系统 命令 文件目录 虚拟机
书籍
课程
技术群
技术干货大合集↓
  • 2023年6月 / 26篇
  • 2023年5月 / 93篇
  • 2023年4月 / 90篇
  • 2023年3月 / 129篇
  • 2023年2月 / 84篇
  • 2023年1月 / 161篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.