用户空间的虚拟地址如何转换得到实际的物理地址

2023-05-16

思路:

进程号是一个进程在用户空间的唯一标示,所以,根据pid可以从内核中得到一个进程的所有信息,

另外就是知道虚拟地址就可以通过内核物理地址映射到虚拟地址的逆运算就可以还原他的实际物理地址

以上便是虚拟地址转换成所对应的实际物理地址的思路。

大致的代码编写流程:

首先根据pid我们可以得到这个进程的task_struct,进而通过task_struct得到mm,通过mm得到pgd。
好了,现在我们有pgd和virtualaddress.
通过pgd和virtualaddress我们可以得到页表pte.
 
有了pte和virtualaddress,我们就可以计算物理地址了
phyaddress=(pte_val(pte)&PAGE_MASK)|(virtualladdress&~PAGE_MASK)


代码:

#include <linux/sched.h> 
#include <linux/mm.h> 
#include <asm/pgtable.h> 
#include <asm/page.h> 
 
static int v2p(int pid, unsigned long va) 
{ 
    unsigned long pa = 0; 
    struct task_struct *pcb_tmp; 
    pgd_t *pgd_tmp = NULL; 
    pud_t *pud_tmp = NULL; 
    pmd_t *pmd_tmp = NULL; 
    pte_t *pte_tmp = NULL; 
 
    printk(KERN_INFO"PAGE_OFFSET = 0x%lx\n",PAGE_OFFSET); 
    printk(KERN_INFO"PGDIR_SHIFT = %d\n",PGDIR_SHIFT); 
    printk(KERN_INFO"PUD_SHIFT = %d\n",PUD_SHIFT); 
    printk(KERN_INFO"PMD_SHIFT = %d\n",PMD_SHIFT); 
    printk(KERN_INFO"PAGE_SHIFT = %d\n",PAGE_SHIFT); 
 
    printk(KERN_INFO"PTRS_PER_PGD = %d\n",PTRS_PER_PGD); 
    printk(KERN_INFO"PTRS_PER_PUD = %d\n",PTRS_PER_PUD); 
    printk(KERN_INFO"PTRS_PER_PMD = %d\n",PTRS_PER_PMD); 
    printk(KERN_INFO"PTRS_PER_PTE = %d\n",PTRS_PER_PTE); 
 
    printk(KERN_INFO"PAGE_MASK = 0x%lx\n",PAGE_MASK); 
 /* 查询当前进程下的虚拟地址 */
 //   pcb_tmp = current; 
/* 查询指定进程的下的虚拟地址 */
     pcb_tmp = find_task_by_vpid (pid); // 较新一点的内核版本使用这个函数
// pcb_tmp = find_task_by_pid (pid);    // 旧版本的内核版本使用这个函数
    printk(KERN_INFO"pgd = 0x%p\n",pcb_tmp->mm->pgd); 
    if(!find_vma(pcb_tmp->mm,va)){ 
                    printk(KERN_INFO"virt_addr 0x%lx not available.\n",va); 
                    return 0; 
    } 
    pgd_tmp = pgd_offset(pcb_tmp->mm,va); 
    printk(KERN_INFO"pgd_tmp = 0x%p\n",pgd_tmp); 
    printk(KERN_INFO"pgd_val(*pgd_tmp) = 0x%lx\n",pgd_val(*pgd_tmp)); 
    if(pgd_none(*pgd_tmp)){ 
                    printk(KERN_INFO"Not mapped in pgd.\n");                 
                    return 0; 
    } 
    pud_tmp = pud_offset(pgd_tmp,va); 
    printk(KERN_INFO"pud_tmp = 0x%p\n",pud_tmp); 
    printk(KERN_INFO"pud_val(*pud_tmp) = 0x%lx\n",pud_val(*pud_tmp)); 
    if(pud_none(*pud_tmp)){ 
                    printk(KERN_INFO"Not mapped in pud.\n"); 
                    return 0; 
    } 
    pmd_tmp = pmd_offset(pud_tmp,va); 
    printk(KERN_INFO"pmd_tmp = 0x%p\n",pmd_tmp); 
    printk(KERN_INFO"pmd_val(*pmd_tmp) = 0x%lx\n",pmd_val(*pmd_tmp)); 
    if(pmd_none(*pmd_tmp)){ 
                    printk(KERN_INFO"Not mapped in pmd.\n"); 
                    return 0; 
    } 
 
    pte_tmp = pte_offset_kernel(pmd_tmp,va); 
 
    printk(KERN_INFO"pte_tmp = 0x%p\n",pte_tmp); 
    printk(KERN_INFO"pte_val(*pte_tmp) = 0x%lx\n",pte_val(*pte_tmp)); 
    if(pte_none(*pte_tmp)){ 
                    printk(KERN_INFO"Not mapped in pte.\n"); 
                    return 0; 
    } 
    if(!pte_present(*pte_tmp)){ 
                    printk(KERN_INFO"pte not in RAM.\n"); 
                    return 0; 
    } 
    pa = (pte_val(*pte_tmp) & PAGE_MASK) |(va & ~PAGE_MASK); 
    printk(KERN_INFO"virt_addr 0x%lx in RAM is 0x%lx .\n",va,pa); 
    printk(KERN_INFO"contect in 0x%lx is 0x%lx\n",pa, 
                    *(unsigned long *)((char *)pa + PAGE_OFFSET)); 
                           
}

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

用户空间的虚拟地址如何转换得到实际的物理地址 的相关文章

随机推荐

  • SM2 签名预处理操作

    如果觉得写得不错 xff0c 烦请微信搜索公众号 34 郑州行疆户外 34 了解程序员的户外业余喜好 转载 xff1a https www xuebuyuan com 1473900 html 一般情况下 xff0c 计算数字签名时应执行以
  • dataset中shuffle()、repeat()、batch()用法

    import numpy as np import tensorflow as tf np random seed 0 x 61 np random sample 11 2 make a dataset from a numpy array
  • Linux内核模块编程,多源码Makefile编写

    https mp csdn net console editor html 107838044 在学习内核模块编程的时候遇到了一些由于Makefile书写不正确导致的问题 一个 c源文件的Makefile按照网上的大部分资料介绍那样是没有问
  • 分组加密, 算法模式(ECB CBC CFB OFB)

    如果觉得写得不错 xff0c 烦请微信搜索公众号 34 郑州行疆户外 34 了解程序员的户外业余喜好 块加密 块加密 xff0c 英文Block Cyper xff0c 又称分组加密 xff0c 是一种常见的对称加密 xff0c 具有代表性
  • Linux UIO机制--用户空间I / O操作方法

    目录 前言 关于UIO UIO 的工作原理 前言 于许多类型的设备 xff0c 创建Linux内核驱动程序是过分的 真正需要的只是某种方式来处理中断并提供对设备存储空间的访问 控制设备的逻辑不必一定要在内核之内 xff0c 因为设备不需要利
  • Linux UIO驱动实例介绍

    接上一篇介绍UIO机制 https blog csdn net hpu11 article details 109395820 uio驱动详解 为了用最简单的例子说明问题 xff0c 我们在我们uio驱动的内核部分只映射了一块1024字节的
  • Mosquitto服务安装与使用---入门操作介绍

    关于Mosquitto配置的资料网上还是有几篇的 xff0c 但是看来看去 xff0c 基本上都是基于Linux 基于Window的凤毛麟角 xff0c 看上去貌似配置的东西相差不大 xff0c 实操过程中真的烦透了 xff0c 配置就是不
  • Windows 11 系统下载,正式版尚未发布

    下载链接方式 xff1a 关注 郑州行疆户外 程序员自己的订阅号 xff0c 回复 win11 xff0c 获取win11系统下载链接 一 发布 今年5月的Build大会 xff0c 微软便正式明确新一代操作系统为Windows 11 xf
  • Windows 11 系统下载安装 教程

    关 注 郑州行疆户外 订阅号 xff0c 回复 win11 xff0c 获取win11系统下载链接 xff0c 安装教程 说明 Windows11系统安装教程 xff0c 这里使用VM虚拟机演示具体安装教程 xff0c 如果是新手 xff0
  • Windows 11 TPM2.0问题及解决方法

    关注 郑州行疆户外 订阅号 回复 win11 xff0c 下载 windows11系统 回复 问题 xff0c 查看 windows11安装过程中遇到的问题及其解决方法 随着2021年6月24日 xff0c 微软正式发布会上确定windon
  • linux的dma驱动

    硬件平台 xff1a TI的3530 内核 xff1a linux 2 6 36 功能 xff1a 将fpga的数据从内存的一个地方复制到内存另一个地方 初学dma感到很是吃力 xff0c 编写的内核驱动代码仔细看了一个星期 xff0c 才
  • linux内核的并发与竞态

    并发与竞态是指多个任务单元同时访问同一个资源 xff0c 就会出现并发 xff0c 竞态的现象 其中多个任务单元包括中断 xff0c 进程 线程 xff0c 甚至多个多处理器 xff1b 同一资源既包含硬件资源 xff0c 也包括软件数据
  • UDP通信

    头文件 xff1a 1 pragma once 2 3 include lt stdio h gt 4 include lt unistd h gt 5 include lt string h gt 6 include lt stdlib
  • 交叉编译找不到stdio.h头文件,make menuconfig问题解决办法

    今天测试交叉编译器总出现问题 xff0c fatal error stdio h No such file or directory 后来根据指导使用编译命令 xff1a arm linux gcc src c I 头文件路径 能编译通过
  • 原子上下文,进程上下文,中断上下文的详细解析

    内核空间和用户空间是现代操作系统的两种工作模式 xff0c 内核模块运行在内核空间 xff0c 而用户态应用程序运行在用户空间 它们代表不同的级别 xff0c 而对系统资源具有不同的访问权限 内核模块运行在最高级别 xff08 内核态 xf
  • server,gtk,tslib

    一 首先先说下framebuffer xserver tslib gtk和桌面这五者之间的联系 xff0c 1 framebuffer 即linux系统的一块内存区域 xff0c 往这块区域写东西屏幕就会有所显示 对应的设备文件是dev f
  • 修改启动logo,禁止光标

    linux内核下使用的图片文件类型是pnm和PPm格式的 xff0c 所以在开始介绍修改linux内核启动LOGO之前 xff0c 1 先需要介绍一下怎么样设计自己开始logo的ppm图片 xff0c 首先选择一张png格式的图片 xff0
  • 移植gtk,这个配置有点早,可以了解一下他的工作流程

    最近一直GTK xff0c 感觉好晕 整整耗了我近三天才勉强在网络资料和他人帮助情况下完成 所以记录一下 xff0c 不然我记性太差 xff0c 很可能下班之前就忘了 xff01 以后也好有个参考 首先注意一个问题 xff1a GTK在编译
  • error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]

    这个错误多为编写linux驱动程序时出现的错误 xff0c 正常情况下是以警告出现的 xff0c 一般有两种情况 xff1a 1 在函数体内 xff0c 定义变量代码前边出现非定义的变量 此变量在其他地方已经定义了 xff0c 编译时就会出
  • 用户空间的虚拟地址如何转换得到实际的物理地址

    思路 xff1a 进程号是一个进程在用户空间的唯一标示 xff0c 所以 xff0c 根据pid可以从内核中得到一个进程的所有信息 xff0c 另外就是知道虚拟地址就可以通过内核物理地址映射到虚拟地址的逆运算就可以还原他的实际物理地址 以上