打印

关于ARM的LINUX启动代码VIVI的内存页表

[复制链接]
1968|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/moz-screenshot.png这是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 = (unsignedlong *) MMU_TABLE_BASE,defineMMU_TABLE_BASE Ox33dfc000,望高手给予指点 下载 (66.17 KB)
2009-10-16 20:00


还有个问题,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。。。。。还望高手赐教啊

相关帖子

沙发
arm_fan168| | 2009-10-17 14:46 | 只看该作者
第一个问题涉及到C语言的指针的自增,其实是个很基础的问题。因为mmu_tlb_base在被定义的时候是定义成一个指向unsinged long型数据的指针,所以mmu_tlb_base 在进行加1运算的时候实际是加上该指针所指向的数据类型的一个单元所占的字节数,而一个unsigned long型的数据所占的内存单元是4,若mmu_tlb_base的初始值是0x33dfc000, 那么mmu_tlb_base+1所得到的结果是0x33dfc004.
  第二个问题,这段程序大意是把0x30000000起始的虚拟地址映射为与物理地址相同,一级翻译表中每个描述符描述的是1M内存的映射情况,虚拟地址的20-31位会作为一级翻译表的索引,pageoffset>>20就计算出了这个索引。不容易说明白,仔细看看ARM920T手册的MMU那一章。

使用特权

评论回复
板凳
zl39049979|  楼主 | 2009-10-17 17:23 | 只看该作者
2# arm_fan168 多谢,我自己弄明白了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

32

帖子

0

粉丝