计算机内存管理之内存访问

2023-05-16

文章目录

  • 一、设备I/O内存访问
    • ioremap & ioremap_nocache
    • ioremap_cached
    • ioremap_wc & ioremap_wt
    • I/O内存访问流程
  • 二、设备地址映射到用户空间
    • mmap过程
  • 三、devmem原理
    • “/dev/mem”设备
    • devmem命令原理
  • 四、malloc原理
    • malloc的工作原理
    • 缺页中断
    • malloc的free

一、设备I/O内存访问

在linux上电时,并不会为外设地址空间建立页表。
但我们知道,linux访问内存使用的都是虚拟地址,因此如果想访问外设的寄存器(一般包括数据寄存器、控制寄存器与状态寄存器),需要在驱动初始化中将外设所处的物理地址映射为虚拟地址,使用ioremap接口可以实现该功能。

ioremap & ioremap_nocache

ioremap和ioremap_nocache实现相同,使用场景为映射device memory类型内存。同时不使用cache(device memory本身就没有cacheable这个属性),即CPU的读写操作直接操作设备内存。

ioremap_cached

ioremap_cached用来映射memory type为normal memory的设备,同时使用cache,这会提高内存的访问速度,提高系统的性能。

ioremap_wc & ioremap_wt

ioremap_wc用来映射memory type为normal memory的设备,同时不使用cache。

I/O内存访问流程

request_mem_region
ioremap
rw
iounmap
release_mem_region

二、设备地址映射到用户空间

一般情况下,用户空间是不能够直接访问设备的。mmap可实现这个功能。

mmap通过将设备内存映射到用户空间的一段内存上,这样,当用户访问用户空间的这段地址范围时,实际是访问设备内存。这样在每次访问时,节省了用户空间和内核空间的复制过程。

无论是普通文件还是设备文件,读写都是基于系统的虚拟文件系统接口,普通文件为了保护磁盘,避免频繁读写,还引入带缓冲页机制,通过read/write/ioctl访问文件时,都需经历“用户到内核”的内存拷贝过程,然后才将文件内容写入磁盘。

通过mmap方法,将文件(包括设备文件)映射到用户进程虚拟内存空间,代替read/write/ioctl的访问方式,此时内存拷贝过程只有“用户空间到虚拟内存空间”,省去了“用户到内核”的拷贝过程,在数据量大的情况下能显著提升读写效率。因此,mmap也称为“零拷贝”(zero copy)技术。

caddr_t *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

fd为文件描述符,一般由open返回。fd也可指定为-1,并指定flags参数中的MAP_ANON,表示匿名映射。
length指映射的字节数,从offset开始计算;
prot指定访问权限;
start指定文件被映射到用户空间的起始地址,一般设为NULL,由内核指定改地址;
函数返回值为映射到用户空间的地址。

mmap过程

1、在虚拟内存中查找一块VMA
2、将这块VMA进行映射
3、如果设备驱动程序或文件系统的file_operation定义了mmap接口,则调用它;
4、将VMA插入进程的VMA链表中

进程在映射空间的对共享内容的修改不会实时同步写回到磁盘文件中,只有调用munmap()函数释放映射后才会执行同步操作。mmap机制提供msync()函数,用于手动同步修改内容到磁盘源文件。

linux内核使用vm_area_struct结构来表示一个独立的虚拟内存区域,由于每个不同质的虚拟内存区域功能和内部机制都不同,因此一个进程使用多个vm_area_struct结构来分别表示不同类型的虚拟内存区域。各个vm_area_struct结构使用链表或者树形结构链接,方便进程快速访问,如下图所示:
在这里插入图片描述
vm_area_struct结构中包含区域起始和终止地址以及其他相关信息,同时也包含一个vm_ops指针,其内部可引出所有针对这个区域可以使用的系统调用函数。这样,进程对某一虚拟内存区域的任何操作需要用要的信息,都可以从vm_area_struct中获得。mmap函数就是要创建一个新的vm_area_struct结构,并将其与文件的物理磁盘地址相连。

三、devmem原理

“/dev/mem”设备

“/dev/mem”是linux系统的一个虚拟字符设备,无论是标准linux系统还是嵌入式linux系统,都支持该设备。
“/dev/mem”设备是内核所有物理地址空间的全映像,这些地址包括:

物理内存(RAM)空间
物理存储(ROM)空间
cpu总线地址
cpu寄存器地址
外设寄存器地址,GPIO、定时器、ADC

“/dev/mem”设备通常与“mmap”结合使用,可将指定内存映射到用户空间。
类似的还有/dev/kmem设备,kernel看到的虚拟内存的全镜像。可以用来访问kernel的内容。

devmem命令原理

应用程序通过mmap函数实现对/dev/mem驱动中mmap方法的使用,映射了设备的内存到用户空间,实现对这些物理地址的读写操作。
类似的有devkmem命令,通过mmap函数实现对/dev/kmem驱动中mmap方法的使用,映射了设备的内核空间到用户空间,实现对这些物理地址的读写操作。

四、malloc原理

malloc的工作原理

可执行文件加载到内存中的时候,就给栈和堆划分了固定大小的空间。使用vm_area_struct结构体指明了一个连续区域的头地址和尾地址。

malloc函数分配内存主要是使用brk和mmap系统调用

brk():		小于128k
	在堆段分配malloc的内存,将堆顶的指针brk往上推;
mmap():		大于128k
	是在堆和栈之间(文件映射区域)找分配一块空闲的虚拟内存,

malloc系统调用后,并没有实际分配物理内存。
这时候读虚拟内存地址,返回值是0;
第一次写的时候,发生缺页中断,才会实际分配物理内存,建立虚拟内存与物理内存的映射关系。

缺页中断

malloc的空间没有实际分配的情况下,在写的时候会报缺页中断。实际上:
进程线性地址空间里的页面不必常驻内存,在执行一条指令时,如果发现他要访问的页没有在内存中(即存在位为0),那么停止该指令的执行,并产生一个页不存在的异常,对应的故障处理程序可通过从外存加载该页的方法来排除故障,之后,原先引起的异常的指令就可以继续执行,而不再产生异常。

当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作:

1、检查要访问的虚拟地址是否合法
2、查找/分配一个物理页
3、填充物理页内容(读取磁盘,或者直接置0,或者啥也不干)
4、建立映射关系(虚拟地址到物理地址)

重新执行发生缺页中断的那条指令
如果第3步,需要读取磁盘,那么这次缺页中断就是majflt,否则就是minflt。

如何查看进程发生缺页中断的次数:
ps -o majflt,minflt -C program

majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误。
这两个数值表示一个进程自启动以来所发生的缺页中断的次数。

malloc的free

前面知道,通过移动brk申请的内存,存放在进程的堆区域中。
free是由运行库实现,它只是在已分配的堆块前面加一个可用标志,并不实际释放内存,不论是物理内存还是进程的堆空间。
在下次的malloc时,这块空间可能被重用。
如果进程的堆空间出现较多的碎片(这是逻辑地址中的碎片),运行库的堆管理例程会移动/合并碎片,此时可能会出现物理内存的释放/重新分配。
而对于brk指针,只有它指向的那片内存被free的时候才会下移。比如先malloc了一个A,然后malloc了一个B。free掉A之后,brk是不会下移的;free掉B的时候brk才会下移。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机内存管理之内存访问 的相关文章

  • 【VBA编程】Sub过程

    过程就是做一件事的经过 xff0c 由不同的操作按先后顺序排列 组合起来 VBA的基本过程有Function过程和Sub过程 过程保存在模块里 Excel对象 xff08 或窗体对象 xff09 也能保存过程 为了避免发生错误 xff0c
  • 【VBA编程】自定义函数,Function过程

    Function过程也称为函数过程 编写一个Function过程 xff0c 就是编写了一个函数 函数可以完成很多复杂的计算 xff0c 如想求A列的和 xff0c 可以使用SUM函数 xff1b Function过程同Sub过程一样 xf
  • 查看网站的技术架构

    想要快速查看网站使用的架构 xff0c 可以在浏览器中添加Wappalyzer插件 以火狐浏览器为例 火狐浏览器 更多工具 61 gt 面向开发者扩展 61 gt 查找Wappalyzer 61 添加 xff0c 即可 红框中即 Wappa
  • Linux服务器查看日志的几种方法

    1 进入日志文件所在的文件目录 xff0c 比如 xff1a cd opt tomcat7 logs 2 通过命令打开日志 xff0c 分析需求场景打开需要的日志 比如 xff1a tail f catalina out 3 常用命令一 x
  • Postman设置网络代理

    1 什么是网络代理 xff1f 在一个基本的网络会话中 xff0c 一个客户端发送一个请求到服务器 xff0c 服务器返回一个响应 xff1b 一个代理服务是一个应用程序或者系统 作为一个中介在你的电脑和互联网之间 客户端和服务器 xff0
  • Postman中的authorization

    1 概述 Authorization是验证是否拥有从服务器访问所需数据的权限 当发送请求时 xff0c 通常必须包含参数 xff0c 以确保请求具有访问和返回所需数据的权限 Postman提供了授权类型 xff0c 可以轻松地在Postma
  • 无法将非静态数据成员声明为 inline

    示例代码 xff1a span class token macro property span class token directive hash span span class token directive keyword inclu
  • C++中类的成员函数(方法)

    文章目录 成员函数 xff08 方法 xff09 示例1 xff1a 在结构体中引入成员函数示例2 xff1a 类示例3 xff1a 类内定义成员函数示例4 xff1a 类内声明 43 类外定义显示内敛的成员函数示例5 xff1a 类内声明
  • visual studio 2019 安装卸载问题

    1 visual studio 2019 安装 问题1 xff1a 如何安装visual studio 2019 企业版 可参考 xff1a http www winwin7 com soft 9019 html xiazai 问题2 xf
  • GDAL图像重采样

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • C#入门基础教程

    文章目录 C 基础入门基本用法 xff08 理解面向对象编程 xff09 示例1 xff1a 创建线类 关键字数据类型数值类型布尔与文本类型引用类型指针类型示例2 xff1a 数值类型示例3 xff1a 文本类型示例4 xff1a Obje
  • 1. 在VS2019上配置PIE.NET-SDK插件式环境(c#)

    1 开发环境部署 确保Win10系统安装Visual Studio2019安装PIESDK Net V6 3 Windows X64 exe 2 创建工程 1 选Windows窗口应用 xff0c 不然后面找不到 Net framwork
  • std::string、const char*、QString之间相互转换

    字符串转换 std string 转 const char std string str 61 34 string 34 const char cstr 61 str c str const char 转 std string span c
  • Cannot convert a symbolic Tensor (simple_rnn/strided_slice:0) to a numpy array. 报错 (解决方法)

    1 报错 问题 xff1a xff08 来自 Python深度学习 P164 165 xff09 在运行以下代码的时候 xff0c 报错 xff1a Cannot convert a symbolic Tensor simple rnn s
  • 图像几何校正

    几何校正中混淆的概念 名词描述几何校正几何畸变会给基于遥感图像的定量分析 变化检测 图像融合 地图测量或更新等处理带来误差 xff08 主要指二维平面坐标 xff09 xff0c 所以需要针对图像的几何畸变进行校正 xff0c 也就是几何校
  • 解决VS2015 安装失败问题,如安装包损坏或丢失

    搜索包路径选择下面这个路径
  • 1.ODBC连接Postgresql

    SQLDriverConnect SQLDriverConnect 是 SQLConnect 的替代方法 它支持需要比 SQLConnect 中的三个参数更多的连接信息的数据源 对话框来提示用户输入所有连接信息 xff0c 以及系统信息中未
  • ImportError: DLL load failed while importing Qsci

    pyqt5报错 xff1b ImportError span class token operator span DLL load failed span class token keyword while span importing Q
  • 关于编译QGIS3.22.12配置的python库

    注意 xff1a 安装了多个python环境的很容易编译出错 xff1b 其中3 22需要配置python3 9的环境 在编译QGIS过程中的报错 报错1 xff1a No module named span class token cha

随机推荐

  • Qt中设置删除提示框

    Qt中设置删除提示框 QMessageBox StandardButton sButton 61 QMessageBox question NULL QObject tr 34 提示 34 QObject tr 34 该数据是否删除 34
  • 你真的对图像格式了解么?

    图像是人类视觉的基础 xff0c 是自然景物的客观反映 xff0c 是人类认识世界和人类本身的重要源泉 图 是物体反射或透射光的分布 xff0c 像 是人的视觉系统所接受的图在人脑中所形成的印象或认识 xff0c 照片 绘画 剪贴画 地图
  • 配置Qt中pro、pri文件

    002helloWorld pro span class token macro property span class token directive hash span span class token directive keywor
  • 构建一个字符串类

    文章目录 1 构建字符串数据 2 创建那些函数给外界调用 1 构造函数以及设计构造函数初值 2 类内带有指针 考虑3个特殊重要函数 3 考虑辅助函数 3 定义具体函数 1 设计构造函数内容
  • PostgreSQL查询

    PostgreSQL 数据库连接 QT xff1a 建立到数据库的连接 QSqlDatabase db 61 QSqlDatabase addDatabase 34 QPSQL 34 db setHostName 34 localhost
  • Conda install 报错:An HTTP error occurred when trying to retrieve this URL. HTTP errors are often...

    1 问题描述 xff1a 准备在Anaconda prompt执行以下命令 xff1a conda install c stellargraph stellargraph 报错 xff1a An HTTP error occurred wh
  • svn原理----revert,回滚

    一 子命令Svn revert 取消所有的本地编辑 下面我们来看一下子命令Svn revert例子 xff1a 丢弃对一个文件的修改 xff1a Svn revert foo c Reverted foo c 如果你希望恢复一整个目录的文件
  • Qt 自定义控件提升,头文件找不到的问题

    Qt 自定义控件提升 xff0c 头文件找不到的问题 在附加包含目录添加 xff1a
  • 分析int(*p)[4] = a

    面试题 xff1a 二级指针 include lt iostream gt int main int a 3 4 61 0 1 2 3 4 5 6 7 8 9 10 11 int p 4 61 a std cout lt lt p 43 1
  • af::convolve在CUDA中局限性

    使用在Cuda出现访问冲突问题 xff08 opengcl正常 xff09 xff1a af convolve I I kernel 报错 xff1a 0x00007FFC6443ADAC af dll 处 位于 XXXX exe 中 引发
  • 2016

    2016 最近 xff0c 许多朋友兴起总结2016了 xff0c 看得我心痒 xff0c 心热 我自己不禁也总结起来了 别人的总结要么是 2016XXXX 要么是 2016OOOO 我苦思2秒 xff0c 却想不起一个标题来 xff0c
  • gdb反汇编disassemble

    GDB Command Reference disassemble command gdb反汇编可用disassemble disass命令 用法如下 xff1a disassemble disassemble Function 指定要反汇
  • S.M.A.R.T. 参数(smartctl)计算硬盘精确健康值

    参考 xff1a Acronis Drive Monitor Disk Health Calculation 文章目录 1 背景2 smartctl a dev sda3 计算健康值3 1 关键参数3 1 1 公式说明3 2 2 计算举例
  • python脚本——通过telnet连接设备

    文章目录 一 说明二 代码三 用法总结 一 说明 通过telnetlib库 xff0c telnet到设备上并做一些测试 包括重启设备 等待重启完成 其它测试操作等 二 代码 span class token comment usr bin
  • lspci 命令详解及常用命令

    文章目录 一 说明二 参数说明三 用法举例 一 说明 lspci是查看设备上pcie设备信息的命令 该命令的不同参数配合 xff0c 在查看pcie设备和定位pcie问题时很有用 包括查看pcie设备中断号 查看配置空间内容 修改配置空间寄
  • 中断模式和polling模式 && 硬件中断和软件中断

    文章目录 一 总结在前二 中断2 1 硬件中断与软件中断2 1 1 对比2 1 2 硬件中断2 1 3 软件中断 三 polling 一 总结在前 S NOInterruptPolling1中断模式下 xff0c 设备通知CPU有业务需要被
  • dma_alloc_coherent 申请内存用法和问题总结

    文章目录 1 dma alloc coherent用法2 问题3 解决方法方法一 xff0c 走CMA空间配置3 1 内核配置 96 96 CONFIG CMA 96 96 3 2 修改cma起始地址3 3 设置cma空间 xff08 大小
  • hadoop之HDFS:通过Java API访问HDFS

    HDFS是一个分布式文件系统 xff0c 可以通过Java API接口对HDFS进行操作 xff0c 下面记录实现Java API的过程和出现的一些问题及解决方案 环境搭建 导入jar包 common包中的jar文件导入 hadoop 2
  • sonic开发——修改内核配置

    参考 xff1a https github com Azure sonic linux kernel sonic 中的内核配置修改不需要编译menuconfig xff0c 而是直接修改 patch kconfig exclusions和p
  • 计算机内存管理之内存访问

    文章目录 一 设备I O内存访问ioremap amp ioremap nocacheioremap cachedioremap wc amp ioremap wtI O内存访问流程 二 设备地址映射到用户空间mmap过程 三 devmem