ioremap将物理地址映射为虚拟地址问题?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ioremap将物理地址映射为虚拟地址问题?相关的知识,希望对你有一定的参考价值。
void *ioremap(unsigned long offset, unsigned long size);
第一个问题:offset是只物理地址偏移吗,也就是物理地址的低20位,高12位物理叶宽可以不用写是吧
第二个问题:#define rGPBCON (*(volatile unsigned *)0x56000010)这是裸机程序时的地址,这是物理地址吗?,物理地址不是在bank6吗,应该是从0x30000000开始到0x33fffffff
第三个问题:ioremap映射得到的虚拟地址是系统自动分配的吗,不能分配指定的地址吗?那驱动里头GPIO寄存器的的虚拟地址不是从指定了从0xf0e000000开始啊,用的是其他的什么映射函数吗?
第四个问题:模块驱动里头我都没有进行IO内存映射,直接使用s3c2410_gpio_getpin就看配置寄存器。
第五个问题:ARM体系机构没有IO端口是吧,也就是说不能用inb , outb 等指令
内核物理地址和虚拟地址之间的静态映射过程
一:当我们开启了MMU之后,使用的都是虚拟地址,这时就需要考虑物理地址到虚拟地址的映射问题。建立映射表的三个关键部分是:
(1)映射表
(2)映射表建立函数
(3)映射表建立函数被调用
1:映射表
(1)映射表是具体的物理地址和虚拟地址的起始地址定义,在我们前面使用静态映射来操作LED时有介绍,三星版本的移植的内核,其主映射表在arch/arm/plat-s5p/include/plat/map-s5p.h和arch/arm/plat-samsung/include/plat/map-base.h中
arch/arm/plat-s5p/include/plat/map-s5p.h的主要内容如下
arch/arm/plat-samsung/include/plat/map-base.h的主要内容如下:
在这里,我们指定了虚拟地址的基地址,也就是宏S3C_ADDR_BASE 0XFD000000,在我们开启了MMU之后,其映射的虚拟地址都是根据这个基地址+偏移量来得到的某个具体的寄存器的,这样当我们建立了映射之后,就可以直接操作虚拟地址来操作我们对应的寄存器,在这里,也只是映射了需要用到的寄存器的虚拟地址,假如要添加,则只需在map-s5p.h中添加相应的映射即可。
(2)GPIO相关的主映射表位于:arch/arm/machs5pv210/include/mach/regs-gpio.h
GPIO的具体寄存器定义位于:arch/arm/mach-s5pv210/include/mach/gpio-bank.h
需要注意的是,不同版本的内核其映射表的位置是不同的,,但是一般都在arch/arm/xxx/map_xx.h文件中
2:映射表的建立过程
上面,我们介绍了内核通过宏定义定义了很多寄存器对应虚拟地址的基地址,那么这些宏是在哪被调用的呢,映射表又是如何被调用的呢。
答案就是kernel/arch/arm/mach-s5pv210/mach-smdkc110.c中的smdkc110_map_io函数。它的调用层级如下:
smdkc110_map_io
s5p_init_io
iotable_init
iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
iotable_init函数就是最终实现建立虚拟地址映射的函数。其中S5P_iodesc是一个数组,它里面包括了我们上面用大量的宏定义得到的映射表。也就是说我们上面创建的宏都在这里被使用到了。
所以当我们需要添加新的虚拟地址映射时只需要做两步
(1)在我们的map-s5p.h或者是map-base.h中添加相应的宏定义
(2)在我们的s5p_iodesc中添加相应的数组元素
3:映射表建立函数的调用过程
以上是关于ioremap将物理地址映射为虚拟地址问题?的主要内容,如果未能解决你的问题,请参考以下文章