Linux 内存虚实内存映射

news2024/12/26 23:23:48

Linux 内存虚实内存映射@TOC

以前关于虚拟地址和物理地址的学习只是在书本上,今天在实际的开发板上实践了一下

代码:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h
#include <linux/init_task.h>

int g=0x100;

static int __init tarzan_init(void)
{
int idx;
pr_info(“tarzan_init\n”);
int x=0x10;
int pint = NULL;
printk(“PHYS_OFFSET=0x%lx\r\n” , PHYS_OFFSET);
printk(“max_mapnr:%d\r\n” , max_mapnr);
printk(“high memory:0x%lx\r\n” , high_memory); //0xF000_0000 0xF000_0000- 0xC000_0000=0x3000_0000=768M
printk(“high memory(768M) -> phy addr:0x%lx\r\n” , __pa(high_memory));
pint = kmalloc(1024
sizeof(int),GFP_KERNEL);
if(!pint)
{
return -1;
}
else
{
printk(“virtual addr is :0x%lx , phy addr:0x%x\r\n” , pint , __pa(pint));
}
pr_info(“g -> VA=%lx , PA=%lx\r\n” , &g , __pa(&g));
pr_info(“x -> VA=%lx , PA=%lx\r\n” , &x , __pa(&x));
pr_info(“PAGE_OFFSET => %lx” , PAGE_OFFSET);
return 0;
}
static void __exit tarzan_exit(void)
{
pr_info(“tarzan_exit\n”);
}

module_init(tarzan_init);
module_exit(tarzan_exit);

MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“ZTE-liukai”);

Makefile:

ifneq ($(KERNELRELEASE),)

obj-m := tarzan.o

else

KDIR := /home/zte/work/hisi/hi3519/Hi3519AV100R001C02SPC020_NEW/Hi3519AV100R001C02SPC020/Hi3519AV100R001C02SPC020/01.software/board/Hi3519AV100_SDK_V2.0.2.0/osdrv/opensource/kernel/linux-4.9.y

all:
make -C ( K D I R ) M = (KDIR) M= (KDIR)M=(PWD) modules ARCH=arm CROSS_COMPILE=arm-himix200-linux-

clean:
rm -f *.ko *.o *.mod.o *.mod.c .symvers modul

endif

  1. 实验
    3.1 Hi3519AV100平台(32位,ARMv7平台)
    运行结果:
    /run/media/mmcblk0p4 #
    /run/media/mmcblk0p4 # insmod tarzan.ko
    tarzan_init
    PHYS_OFFSET=0x22000000
    max_mapnr:262144 (物理页框的个数,一个页框4KB)
    high memory:0xf0000000
    high memory(768M) -> phy addr:0x52000000
    virtual addr is :0xee89e000 , phy addr:0x5089e000
    g -> VA=bf016220 , PA=21016220
    x -> VA=ef3d1dc0 , PA=513d1dc0
    PAGE_OFFSET => c0000000
    Phy addr of 0xc0000000 is -> 0x22000000
    Phy addr of 0xc0000001 is -> 0x22000001
    Phy addr of 0xc0000002 is -> 0x22000002
    Phy addr of 0xc0000003 is -> 0x22000003
    Phy addr of 0xc0000004 is -> 0x22000004
    Phy addr of 0xc0000005 is -> 0x22000005
    Phy addr of 0xc0000006 is -> 0x22000006
    Phy addr of 0xc0000007 is -> 0x22000007
    Phy addr of 0xc0000008 is -> 0x22000008
    Phy addr of 0xc0000009 is -> 0x22000009
    Vir addr 0f 0x0 is -> 0x9e000000
    Vir addr 0f 0x1 is -> 0x9e000001
    Vir addr 0f 0x2 is -> 0x9e000002
    Vir addr 0f 0x3 is -> 0x9e000003
    Vir addr 0f 0x4 is -> 0x9e000004
    Vir addr 0f 0x5 is -> 0x9e000005
    Vir addr 0f 0x6 is -> 0x9e000006
    Vir addr 0f 0x7 is -> 0x9e000007
    Vir addr 0f 0x8 is -> 0x9e000008
    Vir addr 0f 0x9 is -> 0x9e000009
    名称 进程号 状态 优先级 父进程号
    init 1 1 120
    udevd 101 1 116
    udevd 135 1 118
    udevd 136 1 118
    lighttpd 393 1 120
    sshd 397 1 120
    dnsmasq 402 1 120
    sh 412 1 120
    insmod 425 0 120
    /-----------------------------------------------/
    /run/media/mmcblk0p4 #
    /run/media/mmcblk0p4 #
    从运行的LOG来看,内核态起始地址0xC000_0000对应的物理地址是0x2200_0000,和常见的书本上提到的"0xC000_0000映射到物理内存0x0000_0000"有出入,思考了一下,发现问题,DDR颗粒的0地址在ARM内存映射的地址不一定是0地址,系统的定义为:PHYS_OFFSET,该参数的定义为:DDR的地址偏移,后来从海思的手册里找到这个参数的定义:
    在这里插入图片描述

从这张图里可以看出DDR给到Linux OS的地址是从0x2200_0000偏移开始的。

3.2 Hi3516DV300平台 (ARMv7 32)

insmod tarzan.ko

tarzan_init
PHYS_OFFSET=0x80000000
max_mapnr:131072
high memory:0xe0000000
high memory(768M) -> phy addr:0xa0000000
virtual addr is :0xde7de000 , phy addr:0x9e7de000g -> VA=bf55221c , PA=7f55221c
x -> VA=de711dc0 , PA=9e711dc0
PAGE_OFFSET => c0000000
Phy addr of 0xc0000000 is -> 0x80000000
Phy addr of 0xc0000001 is -> 0x80000001
Phy addr of 0xc0000002 is -> 0x80000002
Phy addr of 0xc0000003 is -> 0x80000003
Phy addr of 0xc0000004 is -> 0x80000004
Phy addr of 0xc0000005 is -> 0x80000005
Phy addr of 0xc0000006 is -> 0x80000006
Phy addr of 0xc0000007 is -> 0x80000007
Phy addr of 0xc0000008 is -> 0x80000008
Phy addr of 0xc0000009 is -> 0x80000009

Vir addr 0f 0x0 is -> 0x40000000
Vir addr 0f 0x1 is -> 0x40000001
Vir addr 0f 0x2 is -> 0x40000002
Vir addr 0f 0x3 is -> 0x40000003
Vir addr 0f 0x4 is -> 0x40000004
Vir addr 0f 0x5 is -> 0x40000005
Vir addr 0f 0x6 is -> 0x40000006
Vir addr 0f 0x7 is -> 0x40000007
Vir addr 0f 0x8 is -> 0x40000008
Vir addr 0f 0x9 is -> 0x40000009
/-----------------------------------------------/
~ #
~ #
在这里插入图片描述

可见,Hi3516DV300的 DDR起始地址为0x8000_0000
3.3 飞思卡尔i.max6平台
/mnt # insmod tarzan.ko
tarzan_init
PHYS_OFFSET=0x80000000
max_mapnr:131072
high memory:0xa0000000
high memory(768M) -> phy addr:0xa0000000
virtual addr is :0x88429000 , phy addr:0x88429000
g -> VA=7f00021c , PA=7f00021c
x -> VA=887fbdf0 , PA=887fbdf0
PAGE_OFFSET => 80000000
Phy addr of 0xc0000000 is -> 0xc0000000
Phy addr of 0xc0000001 is -> 0xc0000001
Phy addr of 0xc0000002 is -> 0xc0000002
Phy addr of 0xc0000003 is -> 0xc0000003
Phy addr of 0xc0000004 is -> 0xc0000004
Phy addr of 0xc0000005 is -> 0xc0000005
Phy addr of 0xc0000006 is -> 0xc0000006
Phy addr of 0xc0000007 is -> 0xc0000007
Phy addr of 0xc0000008 is -> 0xc0000008
Phy addr of 0xc0000009 is -> 0xc0000009
Vir addr 0f 0x0 is -> 0x0
Vir addr 0f 0x1 is -> 0x1
Vir addr 0f 0x2 is -> 0x2
Vir addr 0f 0x3 is -> 0x3
Vir addr 0f 0x4 is -> 0x4
Vir addr 0f 0x5 is -> 0x5
Vir addr 0f 0x6 is -> 0x6
Vir addr 0f 0x7 is -> 0x7
Vir addr 0f 0x8 is -> 0x8
Vir addr 0f 0x9 is -> 0x9

在这里插入图片描述

飞思卡尔的该芯片使用的是1:1 (user:kernel)模型,即用户态和内核态地址范围均为2GB。
在这里插入图片描述

该平台为1:1的使用模型,PAGE_OFFSET=80000000(2GB), PHYS_OFFSET=0x80000000,最后的结果为物理地址=虚拟地址
4. 结论

i.max地址映射范围可知,DDR的起始地址为0x8000_0000 , 故PHYS_OFFSET=0x80000000
这个参数Kernel是怎么知道的?答案是通过单板的DTS传给内核的,起始地址为0x8000_0000,大小为512MB
在这里插入图片描述

                      i.max6 dts 内存配置

在这里插入图片描述

                    hi3519 dts 内存配置

在这里插入图片描述

                 hi3516 dts内存配置

在低端内存的虚实地址换算的方法如下,为线性映射,两者之间差一个固定偏移,这个偏移不一定是0xC000_0000,还和DDR内存地址在系统中的起始地址有关系,具体计算方法如下:
虚拟地址=物理地址 - PHYS_OFFSET + PAGE_OFFSET
物理地址=虚拟地址 - PAGE_OFFSET + PHYS_OFFSET

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/51064.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Pandas数据处理100例】(九十一):Pandas读取txt文本文件

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

grid管理下的多实例配置不同监听端口

某现场有两个实例&#xff0c;且客户要求两个实例使用不同的端口&#xff0c;但是grid管理下的监听默认只能一个端口&#xff0c;可以通过以下方式解决 oracle下&#xff1a; srvctl add listener -l listener_cc -p 1522 -o $ORACLE_HOME srvctl add listener -l listener_…

[附源码]SSM计算机毕业设计学院竞赛管理信息系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

还不会使用 Vue-Router?请看过来

目录注明&#xff1a;路由的概念什么是路由和前端路由路由的分类配置Vue-router安装实例化router挂载配置路由一个路由匹配 多组件视图使用路由声明式路由导航 router-link编程式路由导航缓存路由组件 &#xff08;keep-alive&#xff09;注明&#xff1a; Vue-router 3.x的版本…

如何保持电机安全运行

介绍 电动机在电子系统中的使用已变得普遍。电机尺寸、控制和成本效率方面的创新使设计人员能够将电机添加到系 统中&#xff0c;从而创造新功能并扩展最终产品的功能。 随着电动机数量的急剧增加&#xff0c;对功率效率的担忧促使系统设计人员使用更高电压的电机并提高其设计…

Springboot毕业设计毕设作品,个人博客系统设计与实现

功能清单 【后台管理员功能】 系统设置&#xff1a;设置关于我们、联系我们、加入我们、法律声明 会员列表&#xff1a;查看所有注册会员信息&#xff0c;支持删除 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支…

天图投资通过聆讯:资产管理规模247亿 投了小红书与奈雪

雷递网 雷建平 11月30日深圳市天图投资管理股份有限公司&#xff08;简称&#xff1a;“天图投资”&#xff09;日前通过聆讯&#xff0c;准备在港交所上市。天图投资被称为消费赛道狙击手&#xff0c;在深圳、北京、上海、香港四地设有办公室&#xff0c;投资案例包括飞鹤、周…

Python异常类

1.内建异常类的继承关系 2.常见异常汇总 异常名称 说明 ArithmeticError所有数值计算错误的基类AssertionError断言语句失败AttributeError对象没有这个属性BaseException所有异常的基类DeprecationWarning关于被弃用的特征的警告EnvironmentError操作系统错误的基类EO…

计算机组成原理-输入输出系统(持续更新中)

I/O系统基本概念 基本概念 I/O硬件 现代计算机的结构 “I/O”就是"输入/输出" IO设备就是可以将数据输入到计算机&#xff0c;或者可以接收计算机输出数据的外部设备。 常见的IO设备 主机如何与I/O设备进行交互&#xff1f; I/O接口&#xff1a;又称I/O控制器&…

11 【Express服务端渲染】

11 【Express服务端渲染】 1.Express脚手架的安装 安装Express脚手架有两种方式&#xff1a; 1.1 使用express-generator安装 使用命令行进入项目目录&#xff0c;依次执行&#xff1a; cnpm i -g express-generator可通过express -h查看命令行的指令含义 express -hUsag…

You Only Learn One Representation: Unified Network for Multiple Tasks

You Only Learn One Representation: Unified Network for Multiple Tasks一、引言&#xff08;一&#xff09;、 Explicit deep learning&#xff08;二&#xff09;、Implicit deep learning&#xff08;三&#xff09;、Knowledge modeling(四)、Kernel space alignment二、…

Python 算法:感受算法的小小魅力和复杂度的计算

一、小小算法的魅力 这是一个很普通的小例子&#xff0c;但是可以让我们领略到算法改进之后的强大魅力。 已知abc 1000&#xff0c;且a^2b^2c^2&#xff0c;求a、b、c的所有自然数解。 这个很简单&#xff0c;就是通过代码分别给a、b、c赋值&#xff0c;然后返回符合abc 10…

Kafka集群环境搭建及基本使用

前提条件 操作系统&#xff1a;CentOS7服务器&#xff1a;3台Java环境&#xff1a;JDK1.8。安装教程参考JDK1.8安装Zookeeper环境 搭建教程参考Zookeeper集群环境搭建及使用Kafka基础知识参考Kafka角色及功能概览 搭建步骤 下载 执行下载命令wget https://archive.apache.o…

使用SpringBoot实现RabbitMQ各个模式

实现了RabbitMQ各个模式&#xff08;simple、topic、direct、fanout及发送方确认和接收方确认&#xff09;的一个demo 源码&#xff1a;https://gitee.com/xunan29/study-rabbitmq-test-project 参考文章&#xff1a; https://blog.csdn.net/K_kzj_K/article/details/10664225…

[ Linux ] Linux信号概述 信号的产生

目录 0.问题引入&#xff1a; 0.1 将进程设置为后台进程 0.2 查看后台进程并将后台进程提至前台 0.3 将前台进程设置为后台进程 1.信号的概念 2.查看信号列表 3.信号处理的常见方式 4.信号的产生 4.1 用户层产生信号的方式 4.1.1通过终端按键产生信号 4.1.2调用系统函…

【数据集研究】PASCAL VOC 2007

目录1、数据集地址2、适用的比赛1&#xff09;Main Competitions2&#xff09;Taster Competitions3、类别及类别的定义1&#xff09;数据集包含的类别2&#xff09;类别的定义4、数据集1&#xff09;训练集、验证集、测试集2&#xff09;图片和待检测物在类别的分布详情5、标注…

Kamiya丨Kamiya艾美捷小鼠BDNF ELISA原理分析

Kamiya艾美捷小鼠BDNF ELISA预期用途&#xff1a; 小鼠BDNF ELISA用于定量测定小鼠细胞培养物上清液、细胞裂解物、细胞培养物中的BDNF&#xff0c; 血清和血浆&#xff08;肝素、EDTA、柠檬酸盐&#xff09;。仅供研究使用。 引言&#xff1a; 脑源性神经营养因子&#xff…

多线程与高并发(13)——Java常见并发容器总结

本文总结常见的并发容器&#xff0c;包含ConcurrentHashMap、CopyOnWriteArrayList 、ConcurrentLinkedQueue、BlockingQueue 、ConcurrentSkipListMap&#xff0c;本文仅做简单的总结&#xff0c;不做详细的源码分析。 一、ConcurrentHashMap HashMap不是线程安全的&#xf…

Linux基本命令(三)——服务器搭建

搭建简单Web服务器 安装web服务 yum -y install httpd 启动httpd服务 systemctl start httpd查看httpd是否开启成功 service httpd status以下是状态信息&#xff1a; 重新启动httpd systemctl restart httpd6.进入主配置文件 vim /etc/httpd/conf/httpd.conf编辑自配置文件 v…

FPGA控制W5500完成UDP环回测试

FPGA控制W5500完成UDP环回测试&#xff11; 前言&#xff12; 前期准备&#xff13; &#xff37;5500寄存器描述4 &#xff37;5500 环回测试4.1 W5500初始化4.1.1 通用寄存器初始化4.1.2 socket寄存器初始化4.2 W5500数据接收4.3 W5500数据发送4.4 数据环回5 总结&#x…