转自:http://blog.csdn.net/kongkongkkk/article/details/74366200

如果让你编写一个程序,来获取虚拟地址对应的物理地址。。你会试着操作MMU吗。。→_→*

    1. Linux文件目录中的/proc记录着当前进程的信息,称其为虚拟文件系统。在/proc下有一个链接目录名为self,这意味着哪一个进程打开了它,self中存储的信息就是所链接进程的。self中有一个名为pagemap的文件,专门用来记录所链接进程的物理页号信息。这样通过/proc/pid/pagemap文件,允许一个用户态的进程查看到每个虚拟页映射到的物理页

    2. /proc/pid/pagemap中的每一项都包含了一个64位的值,这个值内容如下所示。每一项的映射方式不同于真正的虚拟地址映射,其文件中遵循独立的对应关系,即虚拟地址相对于0x0经过的页面数是对应项在文件中的偏移量

      * /proc/pid/pagemap.  This file lets a userspace process find out which
      physical frame each virtual page is mapped to. It contains one 64-bit
      value for each virtual page, containing the following data (from
      fs/proc/task_mmu.c, above pagemap_read): * Bits 0-54 page frame number (PFN) if present//present为1时,bit0-54表示物理页号
      * Bits 0-4 swap type if swapped
      * Bits 5-54 swap offset if swapped
      * Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
      * Bit 56 page exclusively mapped (since 4.2)
      * Bits 57-60 zero
      * Bit 61 page is file-page or shared-anon (since 3.5)
      * Bit 62 page swapped
      * Bit 63 page present//如果为1,表示当前物理页在内存中;为0,表示当前物理页不在内存中
    3. 1在计算物理地址时,只需要

找到虚拟地址的对应项,再通过对应项中的bit63判断此物理页是否在内存中,若在内存中则对应项中的物理页号加上偏移地址,就能得到物理地址

  1. 通过程序获取物理地址并验证写时拷贝技术


    #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdint.h> //计算虚拟地址对应的地址,传入虚拟地址vaddr,通过paddr传出物理地址
    void mem_addr(unsigned long vaddr, unsigned long *paddr)
    {
    int pageSize = getpagesize();//调用此函数获取系统设定的页面大小 unsigned long v_pageIndex = vaddr / pageSize;//计算此虚拟地址相对于0x0的经过的页面数
    unsigned long v_offset = v_pageIndex * sizeof(uint64_t);//计算在/proc/pid/page_map文件中的偏移量
    unsigned long page_offset = vaddr % pageSize;//计算虚拟地址在页面中的偏移量
    uint64_t item = 0;//存储对应项的值 int fd = open("/proc/self/pagemap", O_RDONLY);。。以只读方式打开/proc/pid/page_map
    if(fd == -1)//判断是否打开失败
    {
    printf("open /proc/self/pagemap error\n");
    return;
    } if(lseek(fd, v_offset, SEEK_SET) == -1)//将游标移动到相应位置,即对应项的起始地址且判断是否移动失败
    {
    printf("sleek error\n");
    return;
    } if(read(fd, &item, sizeof(uint64_t)) != sizeof(uint64_t))//读取对应项的值,并存入item中,且判断读取数据位数是否正确
    {
    printf("read item error\n");
    return;
    } if((((uint64_t)1 << 63) & item) == 0)//判断present是否为0
    {
    printf("page present is 0\n");
    return ;
    } uint64_t phy_pageIndex = (((uint64_t)1 << 55) - 1) & item;//计算物理页号,即取item的bit0-54 *paddr = (phy_pageIndex * pageSize) + page_offset;//再加上页内偏移量就得到了物理地址
    } const int a = 100;//全局常量 int main()
    {
    int b = 100;//局部变量
    static c = 100;//局部静态变量
    const int d = 100;//局部常量
    char *str = "Hello World!"; unsigned long phy = 0;//物理地址 char *p = (char*)malloc(100);//动态内存 int pid = fork();//创建子进程
    if(pid == 0)
    {
    //p[0] = '1';//子进程中修改动态内存
    mem_addr((unsigned long)&a, &phy);
    printf("pid = %d, virtual addr = %x , physical addr = %x\n", getpid(), &a, phy);
    }
    else
    {
    mem_addr((unsigned long)&a, &phy);
    printf("pid = %d, virtual addr = %x , physical addr = %x\n", getpid(), &a, phy);
    } sleep(100);
    free(p);
    waitpid();
    return 0;
    }
  2. 测试结果如下:

    • 全局常量:符合写时拷贝技术

    • 局部变量:不符合写时拷贝技术。原因分析,有可能是物理页上的其他数据被改动,导致拷贝出一个新物理页面

    • 局部静态变量:不符合写时拷贝技术。原因分析,有可能是物理页上的其他数据被改动,导致拷贝出一个新物理页面

    • 局部常量:不符合写时拷贝技术。原因分析,有可能是物理页上的其他数据被改动,导致拷贝出一个新物理页面

    • 字符串:符合写时拷贝技术

    • 动态内存:符合写时拷贝技术
      子进程不修改动态内存

      子进程修改动态内存

*其实想要知道虚拟地址对应的物理地址,通过这样的方式也可以得到物理地址而不用操作MMU。。。*

版权声明:本文为博主kongkongkkk原创文章,未经博主允许不得转载。

Linux下如何在进程中获取虚拟地址对应的物理地址【转】的更多相关文章

  1. linux 下查看某个进程中线程运行在哪个CPU上

    运行程序,使用命令top查看指定的进程的PID: 然后使用命令: top -H -p PID 按f键,并使用上下切换,利用空格键选中nTH,P: 按esc键,P所在的列就是线程运行的CPU号:

  2. Linux 下 expect 脚本语言中交互处理常用命令

    Linux 下 expect 脚本语言中交互处理常用命令 1. #!/usr/bin/expect 告诉操作系统脚本里的代码使用那一个 shell 来执行.这里的 expect 其实和 Linux 下 ...

  3. Linux下查看某个进程打开的文件数-losf工具常用参数介绍

    Linux下查看某个进程打开的文件数-losf工具常用参数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在linux操作系统中,一切皆文件.通过文件不仅仅可以访问常规数据,还 ...

  4. 解决linux下tomcat停止进程任存在问题

    解决linux下tomcat停止进程任存在问题 在Linux下(之所以强调linux下,是因为在windows下正常),执行tomcat ./shutdown.sh 后,虽然tomcat服务不能正常访 ...

  5. linux下实现监控进程网络带宽

    嗯,近期都在网易游戏实习,所以貌似有段时间没有上来写点东西了... 来网易游戏实习最基本的目的事实上就是想知道在游戏公司里面工作都是些什么内容,毕竟自己曾经也没有接触过游戏公司.. 还比較的好奇.. ...

  6. windows和linux下关闭Tomcat进程

    windows和linux下解决Tomcat进程 windows下启动Tomcat报错,8080端口号被占用,报错信息如下 两种解决方法,一种是关闭了这个端口号,另外一种是修改Tomcat下的serv ...

  7. windows下数据库文件使用脚本同步到linux下的mysql数据库中

    1.背景 windows server 2008 下 每天会有 *.sql数据文件 需要上传到linux 中的mysql数据库中 而运维人员是在 windows server 下使用 xshell 连 ...

  8. linux下,一个运行中的程序,究竟占用了多少内存

    linux下,一个运行中的程序,究竟占用了多少内存 1. 在linux下,查看一个运行中的程序, 占用了多少内存, 一般的命令有 (1). ps aux: 其中  VSZ(或VSS)列 表示,程序占用 ...

  9. windows和linux下杀死Tomcat进程,解决端口占用

    windows和linux下解决Tomcat进程 windows下启动Tomcat报错,8080端口号被占用,报错信息如下 两种解决方法,一种是关闭了这个端口号,另外一种是修改Tomcat下的serv ...

随机推荐

  1. 牛客OI赛制测试赛3 解题报告

    前话: 话说考试描述:普及难度. 于是想在这场比赛上涨点信心. 考出来的结果:Point:480     Rank:40 然而同机房的最好成绩是 510. 没考好啊!有点炸心态,D题一些细节没有注意, ...

  2. 洛谷 P1685 游览 解题报告

    P1685 游览 题目描述 顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了! 你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开.可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!! ...

  3. CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )

    CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...

  4. Linux使用vim进行多文件查找和替换的方法

    vim是Linux系统下常用的文本编辑,通过使用多种shell命令能够实现多文件的查找和替换,那么具体会使用到那些命令呢?下面小编就给大家介绍下Linux系统vim多文件查找和替换的方法. 在linu ...

  5. PHP 性能分析第一篇: Intro to Xhprof & Xhgui

    [前言]这是国外知名博主 Davey Shafik所撰写的 PHP 应用性能分析系列的第一篇,阅读第二篇可深入了解 xhgui,第三篇则关注于性能调优实践. 原文链接如下: https://blog. ...

  6. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  7. CH3101 阶乘分解

    题目链接 分解\(n!\)的质因数,输出相应的\(p_i\)和\(c_i\). 其中\(1\leq n\leq 10^6\).   考虑每一个质因子 \(p\) 在 \(n!\) 中出现的次数.显然, ...

  8. git<Commit和Push的区别>

    git作为支持分布式版本管理的工具,它管理的库(repository)分为本地库.远程库. git commit操作的是本地库,git push操作的是远程库. git commit是将本地修改过的文 ...

  9. SSH框架测试

    1.struts的测试:目的是能否正确显示页面. 流程如图: 2.spring测试:目的是能否得到bean 3.Hibernate测试:目的是能否跟数据库操作,测试事务 事务测试: 这个要向数据库中保 ...

  10. 模拟退火算法 R语言

    0 引言 模拟退火算法是用来解决TSP问题被提出的,用于组合优化. 1 原理 一种通用的概率算法,用来在一个打的搜索空间内寻找命题的最优解.它的原理就是通过迭代更新当前值来得到最优解.模拟退火通常使用 ...