把内存地址转化成物理地址

标签: Linux内核分析与应用  linux

动手实践-把内存地址转化成物理地址

创建vaddr2paddr.c文件

#include<linux/init.h>
#include<linux/module.h>
#include<linux/mm.h>
#include<linux/mm_types.h>
#include<linux/sched.h>
#include<linux/export.h>

static unsigned long cr0,cr3;
static unsigned long vaddr=0;

static void get_pgtable_macro(void)
{
    cr0=read_cr0();
    cr3=read_cr3_pa();
    
    printk("cr0=0x%lx,cr3=0x%lx\n",cr0,cr3);

    printk("PGDIR_SHIFT=%d\n",PGDIR_SHIFT);
    printk("P4D_SHIFT=%d\n",P4D_SHIFT);
    printk("PUD_SHIFT=%d\n",PUD_SHIFT);
    printk("PMD_SHIFT=%d\n",PMD_SHIFT);
    printk("PAGE_SHIFT=%d\n",PAGE_SHIFT);
    
    printk("PTRS_PER_PGD=%d\n",PTRS_PER_PGD);
    printk("PTRS_PER_P4D=%d\n",PTRS_PER_P4D);
    printk("PTRS_PER_PUD=%d\n",PTRS_PER_PUD);
    printk("PTRS_PER_PMD=%d\n",PTRS_PER_PMD);
    printk("PTRS_PER_PTE=%d\n",PTRS_PER_PTE);
    printk("PAGE_MASK=0x%lx\n",PAGE_MASK);
}


static unsigned long vaddr2paddr(unsigned long vaddr)
{
    pgd_t *pgd;
    p4d_t *p4d;
    pud_t *pud;
    pmd_t *pmd;
    pte_t *pte;
    
    unsigned long paddr=0;
    unsigned long page_addr=0;
    unsigned long page_offset=0;
    pgd=pgd_offset(current->mm,vaddr);
    printk("pgd_offset=ox%lx,pgd_index=%lu\n",pgd_val(*pgd),pgd_index(vaddr));
    if(pgd_none(*pgd))
    {
        printk("not mapped in pgd\n");
        return -1;
    }

    p4d=p4d_offset(pgd,vaddr);
    printk("p4d_offset=ox%lx,p4d_index=%lu\n",p4d_val(*p4d),p4d_index(vaddr));
    if(p4d_none(*p4d))
    {
        printk("not mapped in p4d\n");
        return -1;
    }

    pud=pud_offset(p4d,vaddr);
    printk("pud_offset=ox%lx,pud_index=%lu\n",pud_val(*pud),pud_index(vaddr));
    if(pud_none(*pud))
    {
        printk("not mapped in pud\n");
        return -1;
    }

    pmd=pmd_offset(pud,vaddr);
    printk("pmd_offset=ox%lx,pmd_index=%lu\n",pmd_val(*pmd),pmd_index(vaddr));
    if(pmd_none(*pmd))
    {
        printk("not mapped in pmd\n");
        return -1;
    }

    pte=pte_offset_kernel(pmd,vaddr);
    printk("pte_offset=ox%lx,pte_index=%lu\n",pte_val(*pte),pte_index(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;
    printk("page_addr=0x%lx,page_offset=0x%lx\n",page_addr,page_offset);
    printk("vaddr=0x%lx,paddr=0x%lx\n",vaddr,paddr);

    return paddr;
}

static int __init v2p_init(void)
{
    unsigned long vaddr=0;
    printk("vaddr to paddr module is running..\n");
    get_pgtable_macro();
    printk("\n");
    vaddr=__get_free_page(GFP_KERNEL);
    if(vaddr==0)
    {
        printk("__get_free_page failed..\n");
        return 0;
    }

    sprintf((char *)vaddr,"hello world from kernel");
    printk("get_page_vaddr=0x%lx\n",vaddr);
    vaddr2paddr(vaddr);
    return 0;
}

static void __exit v2p_exit(void)
{
    printk("vaddr to paddr module is leaving..\n");
    free_page(vaddr);
}

module_init(v2p_init);
module_exit(v2p_exit);

创建Makefile文件

obj-m:=vaddr2paddr.o
	
CURRENT_PAHT:=$(shell pwd)
LINUX_KERNEL:=$(shell uname -r)
LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)

all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) modules
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) clean

输出日志文件内容
在这里插入图片描述

版权声明:本文为qq_38966867原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_38966867/article/details/107325336

智能推荐

Bridging signals

Bridging signals Time Limit: 1000MSMemory Limit: 10000K Total Submissions: 10926Accepted: 5982 Description 'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. Once ...

一天一大 leet

一天一大 leet 题目(难度:困难): 示例 抛砖引玉 官方答案 高手在民间 菜鸡的自白 20200606 题目(难度:困难): 给定一个未排序的整数数组,找出最长连续序列的长度。 要求算法的时间复杂度为 O(n)。 示例 示例 抛砖引玉 要求算法的时间复杂度为 O(n),即限制了只能循环一次; 先对数组排序 循环数组记录后一个元素等于前一个元素+1或者等于前一个元素的数量 满足条件++,不然重...

Tensorflow实现的CNN文本分类

https://blog.csdn.net/somtian/article/details/69359498 原博文, github 在这篇文章中,我们将实现一个类似于Kim Yoon的卷积神经网络语句分类的模型。 本文提出的模型在一系列文本分类任务(如情感分析)中实现了良好的分类性能,并已成为新的文本分类架构的标准基准。 本文假设你已经熟悉了应用于NLP的卷积神经网络的基础知识。 如果没有,建议...

JDBC新手入门教程

开发工具:idea 数据库:mysql jar包:junit-4.10 mysql-connector-java-8.0.18 junit-4.10下载 mysql-connector-java-8.0.18下载 注意1:jdbc的驱动因为使用的是mysql-connector-java-8.0.18,所以为(“com.mysql.cj.jdbc.Driver”),而不是(...

Lua 排序 table.sort

    正如C#中有Array.Sort(),lua中也有自己的排序方法即table.sort(table,function)。     lua中的排序默认是从大到小的排序;     传入一个方法参数,可以使排序从小到大; 打印结果:  ...

猜你喜欢

SURF算法简述及Python标记SURF特征检测实践

目录 一、SURF算法 1.算法简介 2.SURF与SIFT的具体差异 二、Python代码实践 1.测试环境 2.测试代码 3.核心函数 4.测试结果 一、SURF算法 1.算法简介 SURF(Speeded-Up Robust Features)加速稳健特征,是一种稳健的局部特征点检测和描述算法。 SURF是对SIFT算法的改进,该算子在保持 SIFT 算子优良性能特点的基础上,同时解决了 S...

Selenium3自动化测试——19.读取数据文件

1. 实现目标 在测试与开发中,经常需要对文件进行各种读取操作。这里介绍针对txt、csv、xml、json文件的读取。 2. 读取TXT文件 2.1 user_info.txt文件 2.2 读取txt文件.py 2.3 实现结果 3. 读取csv文件 3.1 user_info.csv  这里要注意,csv文件本身打开是utf-8的,而不是乱码 3.2 读取csv文件.py 这里,针对...

Flask 介绍

Flask 学习笔记 一、Flask 简介         Flask 是一款非常流行的 Python Web 框架,出生于 2010 年,作者是 Armin Ronacher,本来这个项目只是作者在愚人节的一个玩笑,后来由于非常受欢迎,进而成为一个正式的项目。         Flask 自2010年发布第一个版本以...

Java实现十大排序算法,配合动态图片

Java实现排序算法 其中不理解时间复杂度得可以看一下我的时间复杂度的文章,有助于理解 十大排序算法 1、冒泡排序 2、选择排序 3、插入排序 4、希尔排序 5、归并排序 6、快速排序 7、堆排序 8、计数排序 9、桶排序 10、基数排序 代码git地址:https://github.com/gaoyeming/sort-algorithm.git 排序算法说明 1,排序的定义 对一序列对象或者数...

(笔记)第二章:一个案例吃透深度学习(中)

目录 一、【手写数字识别】之网络结构 数据处理 经典的全连接神经网络 卷积神经网络 二、【手写数字识别】之损失函数 Softmax函数 交叉熵 交叉熵的代码实现 三、【手写数字识别】之优化算法 设置学习率 学习率的主流优化算法 一、【手写数字识别】之网络结构 之前我们用与房价预测相同的简单神经网络解决手写数字识别问题,但是效果并不理想。 原因:是手写数字识别的输入是28 × 28的像素...