Linux 读写进程物理内存

Linux读写物理内存的实践环节 一、基础知识 1.打开设备文件: mem是一个字符设备文件,是计算机主存的一个映像。通常只有root用户对其有读写权限。因此只有root用户能进行这些操作。 如果要打开设备文件/dev/mem,需要系统调用open()函数,作用是打开一个文件或设备,其函数原型为: int open(const char *path, int flags); 返回值:如果操作成功则 阅读详情

研究Linux内存管理过程中,走了不少弯路,内存管理在Linux内核中是很重要,且很复杂的一部分,这里记录我对Linux内存管理结构的了解。

首先对涉及内存的几个术语解释:

虚拟地址空间:

        这是系统视图的地址空间,也是我们使用内存主要用到的地址空间

物理地址空间:

        CPU视图的地址空间,MMU会将虚拟地址转换为物理地址来访问内存。

MMU:

         内存管理单元,主要负责对内存管理(地址转换、访问控制等)

 

Linux内存映射原理:

     首先我们只能使用虚拟地址,但访问内存只能通过物理地址,所以虚拟地址首先会通过MMU转换为物理地址,然后经过总线就可以寻址到内存了,核心是 虚拟地址转 物理地址。

Linux使用4级页表来转换物理地址,每级页表存储虚拟内存地址的部分偏移,这里可以理解为索引吧,以下为4级页表解释

PGD 全局页目录

PUD 上层页面目录

PMD 中间页目录

PTE 页表项(页表项即为物理地址了)

下图说明了一个虚拟地址,被拆分了以下部分,每个部分对应于页表的偏移,当我们访问内存时,就是根据这些信息来获取内存的物理地址的。

 

 

 

当我们在程序内部使用变量内容时,如下:

int main(int argc,char *argv[])
{
    int *ptr=(int*)malloc(sizeof(unsigned int));
    *ptr=1992;
    while(1)
    {
        printf("pid %ld vaddr %ld value %d\n",getpid(),ptr,*ptr);
        sleep(2);
    }
    return 0;
}

这里指针变量存储了该内存对应的虚拟地址,当我们访问时该内存是,首先根据当前进程的实例(task_struct->mm),获取到进程的pgd,然后依次获取 pud、pmd、pte。

虚拟地址和物理地址之间的关联即通过页表的方式进行映射。

在内核中我们可以通过编写内核驱动的方式来访问任意进程的内存(内核中没有任何限制),内核读写任意进程内存核心实现代码如下:

static int vaddrtopaddr(struct task_struct *p,unsigned long vaddr)
{
	struct mm_struct *mm=p->mm;
	pgd_t *pgd;
    pud_t *pud;
    pmd_t *pmd;
    pte_t *pte;
	unsigned long kks;
    unsigned long paddr = 0;
    unsigned long page_addr = 0;
    unsigned long page_offset = 0;
    
	pgd =pgd_offset(mm,vaddr);
    if (pgd_none(*pgd)) {
        printk("not mapped in pgd\n");
        return -1;
    }
 
    pud = pud_offset((p4d_t*)pgd, vaddr);
    printk("pud_val = 0x%lx\n", pud_val(*pud));
    if (pud_none(*pud)) {
        printk("not mapped in pud\n");
        return -1;
    }
 
    pmd = pmd_offset(pud, vaddr);
    if (pmd_none(*pmd)) {
        printk("not mapped in pmd\n");
        return -1;
    }
 
    pte = pte_offset_kernel(pmd, vaddr);
    if (pte_none(*pte)) {
        printk("not mapped in pte\n");
        return -1;
    }
	//页框地址 页的物理地址
	page_addr = pte_val(*pte) & PAGE_MASK;
    page_offset = vaddr & ~PAGE_MASK; //虚拟地址在物理地址中的偏移

	paddr = page_addr | page_offset; //内存的物理地址
	unsigned long _pageaddr=pte_page(*pte); //拿到物理地址对应的内存结构实例 page,这是Linux的物理内存管理结构,每个page结构实例表示一块物理内存

    //kmap要的是page结构的虚拟地址
    unsigned long vptr=kmap(_pageaddr); //将该物理地址映射到内核的虚拟地址空间中,这样才能访问该物理内存。
	if(vptr<=0)
	{
		printk("vptr is null");
	}
	else
	{
		printk("vptr 0x%lx vaddr value 0x%lx\n",vptr,vptr+page_offset);
		unsigned int *vint=(unsigned int*)(vptr+page_offset);
		printk("int val %d\n",*vint);
		*vint=2021;
	}
	kunmap(page_addr);
	return 1; 

}

完整代码 Git

C# 异步编程详解(Task,async/await) 同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。异步的好处在于非阻塞(调用线程不会暂停执行去等待子线程完成),因此我们把一些不需要立即使用结果、较耗时的任务设为异步执行,可以提高程序的运行效率。 阅读详情

相关推荐

从SVF文件到高效验证:Formality中set_svf命令的隐藏技巧与实战解析

本文深入解析Formality中set_svf命令的高级应用技巧,涵盖SVF文件生成策略、多文件加载优化及验证效率提升方法。通过-append和-ordered选项的实战应用,帮助工程师解决芯片验证中的常见问题,实现验证通过率与运行效率的双重提升。

mqtt6iot的博客 819

Linux下直接读写物理地址内存

虚拟 转 物理地址  virt_to_phys( *addr ); 物理 转 虚拟地址  phys_to_virt( *addr ); ------------------------------------------------- Linux内核里提供的/dev/mem驱动,为我们读写内存物理地址,提供了一个渠道。下面讲述2种利用mem设备文件进行物理地址读写的方法,一种是设备驱动的方法

fz835304205的专栏 1万+

保姆级教程:用Python仿真OFDM系统(附抗多径干扰优化方案)

本文提供了一份详细的Python仿真OFDM通信系统教程。通过NumPy和Matplotlib,从二进制比特流开始,逐步构建完整的OFDM系统模型,涵盖IFFT、循环前缀等核心概念。重点探讨了如何对抗多径干扰,并提供了优化方案,通过误码率曲线直观对比性能,适合通信工程学习和物理层开发实践。

weixin_29230649的博客 232

万字长文教你使用安卓内核驱动进行内存读写

万字长文教你使用安卓内核驱动进行内存读写

平平无奇一博客 1万+

基于FPGA的数据采集系统(一)

整体系统设计 本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下: 图1:FPGA数据采集系统框图 从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D..

phflovelt的博客 2万+

ECMWF等大气数据批量下载(Python API)详细步骤

ECMWF等大气数据批量下载(Python API) 遥感方向做热红外温度反演,不可避免的要用到大气廓线数据,大气数据具有实时性,比如2018年9月1日的早上8点的影像,为了提高反演精度就需要用到时间上与其相差尽可能接近的大气数据,用于消除大气的影响,如果数据量较少我们可以查看影像的时间和空间范围进行下载,但是如果处理某个较大区域时可能涉及到大量的影像,如果一景一景对应查找去下载会很麻烦,因此针对大量数据的自动批量下载很有必要。本文根据 https://cds.climate.copernicus.eu/#

liuxiaojiangtobeno1的博客 1万+

linux读写进程内存函数,Linux内核深度解析-进程管理-读书笔记

进程Linux内核把进程称为任务(task),进程的虚拟地址空间分为用户虚拟地址空间和内核虚拟地址空间,所有进程共享内核虚拟地址空间,每个进程有独立的用户虚拟地址空间。进程有两种特殊形式:没有用户虚拟地址空间的进程称为内核线程,共享用户虚拟地址空间的进程称为用户线程,通常在不会引起混淆的情况下把用户线程简称为线程。共享同一个用户虚拟地址空间的所有用户线程组成一个线程组。命名空间Linux的命名空间...

weixin_36039533的博客 440

FPGA实战:MIG IP核AXI接口DDR3读写优化指南

本文详细解析了FPGA中MIG IP核AXI接口的DDR3读写优化策略,涵盖关键参数配置、突发传输技巧及时序收敛方案。通过AXI接口优化和突发长度选择,可实现高达12.8GB/s的理论带宽,提升DDR3访问效率。文章还提供了Vivado配置实例和调试技巧,助力开发者解决FPGA内存控制中的实际问题。

weixin_29168393的博客 546

linux 进程 物理内存,Linux高物理内存(Physical Memory)占用率现象

最近项目联调发现各种OutOfMemory,然后大家很容易的就把原因归结到High Physical Memory上去,因为在shell中运行top指令可以看到free的内存很少(64G的内存只有1G空闲)但是习惯了Windows的内存机制,很容易对Linux的内存机制产生误解。再细看上面图片中,应用进程占用的内存并不高,几近30G左右,而剩下的30G去哪了?Linux核把它分配给了cached缓...

weixin_33240461的博客 1448

Cadence学习之路:什么是PCB工艺的正片与负片

正片??负片??Flash焊盘的创建与使用

qq_46757048的博客 4245

基于MATLAB实现语音信号MFCC特征提取(附完整代码)

你有没有想过你的智能手机是如何理解语音指令的?或者 Alexa 和 Siri 等语音助手如何处理您的命令?这种卓越能力背后的机制在很大程度上归功于一种称为 Mel 频率倒谱系数 (MFCC) 的方法。语音识别技术允许机器解释人类语音,将口语转换为计算机可以操纵的格式。这项技术对于开发交互式和响应式 AI 至关重要,例如声控助手、自动化客户服务系统和实时翻译服务。MFCC 代表 Mel 频率倒谱系数。这是用于自动语音和说话人识别的功能。

baidu_34971492的博客 1313

Linux 物理内存、虚拟内存

物理内存和虚拟内存电脑里内存分内存条(这里我们叫物理内存)和硬盘,内存条保存程序运行时数据,也称为物理内存,硬盘持久保存数据。在进程的执行过程当中,Linux会根据内核需要,分配一片内存区域,进程会将这片区域当成工作区。然后按照要求去执行这些操作。那么虚拟内存是什么?程序运行会启动一个进程,进程里有程序段、全局数据、栈和堆,这些都会加载到内存里,每一部分都有对应的内存地址,进程就是一直在处理这些地址中数据。然而在Linux下,进程不能直接读写物理内存地址(它不能直接读取内存条对应的地址)。进程中能访问的地址

小楼一夜听春雨,深巷明朝卖杏花 1188

【WorkBuddy从入门到精通实战教程】使用手册 第 2 章 WorkBuddy的下载、安装、登录与更新

摘要:WorkBuddy官方下载地址为https://www.codebuddy.cn/work/,支持Mac和Windows系统,需根据设备自动匹配版本。安装时需核对发布者信息,Mac用户需拖入应用程序文件夹。登录支持微信扫码或手机号,公司电脑安装需IT授权。更新通过个人中心检查,遇到安装包损坏、登录失败或文件读写问题时,建议重新下载、检查网络/权限或联系官方支持。重要文件建议定期备份,避免直接操作原文件。(149字)

企鹅码农的专属播客,分享10多年的实战案例和经验解读,包含YOLO、RT-DETR、AI等各个工作领域。 1846

java获取进程id 读写内存_java 获取进程ID 物理内存 cpu使用百分比(linux环境)

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.math.BigDecimal;import org.apache.log4j.Logger;import sun.management.ManagementFactory;import com....

weixin_28702613的博客 372

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

linux进程的smaps文件详解(查看进程占用的实际物理内存)

如图所示分别代表可执行文件映射后的只读可执行段(代码)、只读段(写死的字符串)跟读写段(数据段\=BSS端) size:表示该段占用的虚拟内存的大小 Rss:表示该段实际占用的物理内存的大小 Pss:如果此段是共享库的代码段,那么会跟别的进程共享,平摊下来的物理内存 Shared_Clean:跟别的进程共享的,干净的页面,一般是共享库代码段 Shared_Dirty:跟别的进程进程共享的,但...

qq_21331015的博客 3957

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【Linux】深入理解 Linux 虚拟内存管理

【Linux】深入理解 Linux 虚拟内存管理

技术杠精的博客 2061

一步一图带你深入理解 Linux 虚拟内存管理

图解 Linux 虚拟内存管理

bin的技术小屋 1796

Linux--内存空间挂载到目录

/dev/shm是linux下的一块共享内存结构。默认大小是真实内存的一半。它用来存储进程间通讯时的一些共享数据结构。在物理内存足够时,会在内存中进行数据交换,如果物理内存缺乏时,会用swap进行数据交换. 支持动态在线调整.在我们需要时可以增加或缩减它的大小。 如果你的程序、代码,需...

2519

Linux内核源码分析 (B.0)从 Linux 内核角度探秘 JDK NIO 文件读写本质

首先人们提出地址这个概念的目的就是用来方便定位现实世界中某一个具体事物的真实地理位置,它是一种用于定位的概念模型。举一个生活中的例子,比如大家在日常生活中给亲朋好友邮寄一些本地特产时,都会填写收件人地址以及寄件人地址。以及在日常网上购物时,都会在相应电商 APP 中填写自己的收获地址。image.png随后快递小哥就会根据我们填写的收货地址找到我们的真实住所,将我们网购的商品送达到我们的手里。

嵌入式点灯砖家的博客 1254

Linux管道 有名管道(FIFO)工作机制全解:从理论到实践

有名管道

2401_87244387的博客 1032

mmap映射区和shm共享内存的区别总结

linux中的两种共享内存。一种是我们的IPC通信System V版本的共享内存,另外的一种就是我们今天提到的存储映射I/O(mmap函数) 在说mmap之前我们先说一下普通的读写文件的原理,进程调用read或是write后会陷入内核,因为这两个函数都是系统调用,进入系统调用后,内核开始读写文件,假设内核在读取文件,内核首先把文件读入自己的内核空间,读完之后进程在内核回归用户态,内核把读入内核内存的数据再copy进入进程的用户态内存空间。实际上我们同一份文件内容相当于读了两次,先读入内核空间,再从内核空间

qq13955的博客 328

为Java虚拟机分配堆内存大于机器物理内存会怎么样?

对于第一阶段的内存申请,由于申请的是虚拟内存,实际上64 位操作系统,进程可以使用 128 TB 大小的虚拟内存空间,所以进程申请一个远大于本机物理内存是没问题的,只要不读写这个虚拟内存,操作系统就不会分配物理内存。另外,当内存使用存在压力的时候,会开始触发内存回收行为,会把这些不常访问的内存先写到磁盘中,然后释放这些内存,给其他更需要的进程使用。我们先使用如下命令关闭Swap,然后为虚拟机分配堆的大小为6G,实际上可用的物理内存是5.8G,所以不出意外的,内存分配失败了。可以看到,程序运行成功。

weixin_29733795的博客 90

【内存管理】进程的虚拟地址和内核中的虚拟地址有什么关系?

那么到底什么是虚拟内存地址 ? Linux 内核为啥要引入虚拟内存而不直接使用物理内存 ? 虚拟内存空间到底长啥样? 内核如何管理虚拟内存? 什么又是物理内存地址 ?如何访问物理内存? 本文笔者就来为大家详细一一解答上述几个问题,让我们马上开始吧~~~~

诸葛一帆丶的博客 967

linux memory swap,【Linux】Swap与Memory

背景介绍Memory指机器物理内存,读写速度低于CPU一个量级,但是高于磁盘不止一个量级。所以,程序和数据如果在内存的话,会有非常快的读写速度。但是,内存的造价是要高于磁盘的,且内存的断电丢失数据也是不能把所有数据和程序都保存在内存中的原因。既然不能全部使用内存,那数据还有程序不可能一直霸占在内存中。当内存没有可用的,就必须要把内存中不经常运行的程序踢出去。但是踢到哪里去,这时候swap就出现了。...

weixin_29084231的博客 471
上一篇: Java线程同步方式记录
下一篇: Linux 进程调度分析
IT回忆录
博客等级 码龄16年 42粉丝 100原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值