Linux 内存虚实内存映射

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值