这是VIVI启动代码中的设置页表
for (sectionNumber = 0; sectionNumber < 4096; sectionNumber++) {
pageoffset = (sectionNumber << 20);
*(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC;
}
不清楚的就是*(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC;把后面的32位数据赋在mmu_tlb_base + (pageoffset >> 20)这个地址上,(起初我想应该是把后面的32位数据的低8位赋在这个地址上)也许ARM是4字节存储,于是编译器自动的把地址自加,比如A=0,那么*A指向内存0处的内容,B是32位数据,*A=B就把B的内容放到了A,A+1,A+2,A+3。但是每循环1次,SECTIONNUMBER自+1,那么mmu_tlb_base + (pageoffset >>20)也自+1,如果按照上面的4字节存储的话,不是覆盖掉了之前写的数据吗?比如第1次mmu_tlb_base + (pageoffset>>20)=0,然后把32位数据放到了从这里开始的4字节,0,1,2,3这四个字节,之后地址自+1,应该是指向1这个内存位置,而不是指向4,那么这个页表不是建立失败了吗?难道在GCC编译中,基地址mmu_tlb_base还会自动+4????mmu_tlb_base的定义是staticunsigned long *mmu_tlb_base = (unsigned long *) MMU_TABLE_BASE,defineMMU_TABLE_BASE Ox33dfc000,望高手给予指点
还有个问题,for (pageoffset = DRAM_BASE; pageoffset < (DRAM_BASE+DRAM_SIZE); pageoffset += SZ_1M) {
//DPRINTK(3, "Make DRAM section cacheable: 0x%08lx\n", pageoffset);
*(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC | MMU_CACHEABLE;为了把让虚拟地址和实际物理地址相同,就有了上面这些程序,mmu_tlb_base就是33DFC000,PAGEOFFSET为什么要右移20位?如果要把虚拟地址30000000对上物理地址30000000,不是只用从第301个页表项开始设置吗?第301个页表项相对于mmu_tlb_base的位移为300*4=1200个字节,而我算出DRAM_BASE(30000000)右移20位并不是1200。。。。。还望高手赐教啊 |