您的位置 首页 硬件

S3C2440之MMU操作(MDK4.22)

关于MMU知识:1.ARMCPU上的地址转换过程涉及到了3个概念,虚拟地址VA,变换地址MVA,物理地址PA。当没有启动MMU的时候,CPU核,CACHE,MM…

关于MMU常识:

1.ARM CPU上的地址转化进程触及到了3个概念,虚拟地址VA,改换地址MVA,物理地址PA。当没有发动MMU的时分,CPU核,CACHE,MMU见到的都是PA。

发动MMU之后,CPU核对外宣布VA,VA被转化为MVA,供应CACHE和MMU运用,MMU再将MVA转化为PA,终究找到实在的地址。

CPU看见的VA,CACHE和MMU看不见VA,看见的是MVA;设备只看到VA。

转化算法:假如VA<32M,那么运用进程PID来转化,PID经过CP15的C13读取。

if(VA<32M) then

MVA = VA | (PID << 25);

else

MVA = VA; //VA >= 32M

2.协处理器的cp15寄存器c2的31-14位寄存一级页表的地址,一级页表有4096项,每项4字节,共16k,所以c2的0到13位不运用

若为段映射,只需求一级页表,每段1M,4096*1M=4G空间;若为页映射就需求二级页表,方针的物理页有大页,小页,极小页。

3.一级页表的描述符和二级页表描述符

注意到一级描述符是用来指引二级描述符的,除了段的直接指引到物理内存,若运用二级页表的话,那么二级页表类型有粗页表,细页表两种。

粗页表256项,每项指引真是内存为4K巨细,自身占256*4=1k字节;细页表1024项,每项指引1k巨细,自身二级页表占1024*4=4k字节。

所以注意到,若要对应实在物理页的大页的话,怎么办呢?运用粗页的话,需求16个粗页二级描述符;运用细页的话,需求64个二级描述符。

4段的转化举例

5内存拜访权限问题

注意到一级页表中的描述符中有domain字段,4位,共16种状况

对应的为cp15中的c3寄存器设置。

00无拜访权限,任何拜访都会导致domain fault反常

01客户形式,运用段描述符,页描述符进行权限查看

10保存

11管理形式,不进行权限查看,运转任何拜访

cp15中的c3 + domain + cp15寄存器c1中的R/S/A位 + 描述符AP一起决议拜访权限

6TIB和Cache的效果

TLB是为了减轻页表拜访所带来的拜访内存担负,运用程序拜访的局部性原理,挑选高速且容量较小的存储器存储近期运用的页表条目。

一般做法:在发动MMU之前使无效整个TLB;更改页表表项的时分,使无效所触及到的虚拟地址所对应到的TLB条目。

Cache的效果,在主存和CPU通用寄存器之间设置一个高速,容量相对较小的存储器。把正在碑文的指令的邻近一部分数据或许指令从主存调入这个

存储器,供CPU在一段时间内运用。Cache的(1)clean操作是将cache或writerbuffer现已脏的数据写入主存(2)invalidate不将数据写入主存,使之不能

再运用罢了。

cp15的寄存器1的12位Icr位舱位Icaches;第2位写1舱位Dcaches;Writterbuffer和Dcache紧密结合,没有专门的控制为舱位,中止它。

程序部分:

本程序将0-1M映射为自身,将0xa0000000~0xa000fffff映射为0x56000000~0x560ffffff,将0xb0000000~0xb3ffffff映射为0x30000000~0x3fffffff

触及到代码文件有s3c2440.s文件,init.c文件,led.c文件,led.sct文件

s3c2440.s主要是调用一些初始化程序,init.c是初始化代码,led.c仅仅运用新的虚拟地址寻觅gpio,点亮led。

编译器MDK4.22a

led.sct文件如下所示:

LR_ROM1 0x00000000 0x00200000 { ; load region size_region
NANDFLASH 0x00000000 0x00200000 { ; load address = execution address
*.o (initcode, +First)
.ANY (+RO)
}
}

LR_ROM2 2048 2048 {
SDRAM 0xb0004000 {
led.o (*)
}
}

存在多个加载域,会发生多个bin,能够拜见的另一篇文章讲到怎么衔接多个bin文件S3C2440开发工具realview MDK4.22运用入门

init.c文件:

//creat page table
void create_page_table(void)
{
#define MMU_FULL_ACCESS(3<<10)
#define MMU_DOMAIN(0<<5)
#define MMU_SPECIAL(1<<4)
#define MMU_CACHEABLE(1<<3)
#define MMU_BUFFERABLE(1<<2)
#define MMU_SECTION(2<<0)
#define MMU_SECDESC(MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL |\
MMU_SECTION)
#define MMU_SECDESC_WB(MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL |\
MMU_SECTION | MMU_CACHEABLE | MMU_BUFFERABLE)
#define MMU_SECTION_SIZE0x00100000

ulong virtualaddr, physicaladdr;
ulong *mmu_tlb_base = (ulong*)0x30000000;

/*<1>0~1M map to 0~1M virtualaddr == physicaladdr*/
virtualaddr = 0;
physicaladdr = 0;

//mmu page table store at 0x30000000
//vritualaddr>>20 is index of mmu page table
*(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC_WB;

/*<2>0xa0000000~0xa000fffff map to 0x56000000~0x560fffff*/
virtualaddr = 0xa0000000;
physicaladdr = 0x56000000;
*(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC;

/*<3>0xb0000000~0xb3ffffff map to 0x30000000~0x33fffffff total=64m totaldescs=64*/
virtualaddr = 0xb0000000;
physicaladdr = 0x30000000;

while(virtualaddr < (ulong)0xb4000000)
{
*(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC_WB;
virtualaddr += MMU_SECTION_SIZE;
physicaladdr += MMU_SECTION_SIZE;
}
}

//init MMU
void mmu_init(void)
{
ulong ttb = 0x30000000;

__asm{
mov r0,#0
mcr p15,0,r0,c7,c7,0 //invalidate Icache Dcache

mcrp15,0,r0,c7,c10,4//drain writer buffer
mcr p15,0,r0,c8,c7,0 //invalidate TLB

mov r4,ttb
mcr p15,0,r4,c2,c0,0 //set page table base-addr

mvn r0,#0 //invert all bits:0x0000000->0xffffffff
mcr p15,0,r0,c3,c0,0 //set domain(all is 0b11)

mrc p15,0,r0,c1,c0,0 //read control register

bic r0,r0,#0x3000
bic r0,r0,#0x0300
bic r0,r0,#0x0087

orr r0,r0,#0x0002
orr r0,r0,#0x0004
orr r0,r0,#0x1000
orr r0,r0,#0x0001

mcr p15,0,r0,c1,c0,0

};
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/yingjian/264986.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部