打印
[嵌入式linux]

菜鸟关于ARM的LINUX启动代码VIVI内存页表问题

[复制链接]
2451|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这是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。。。。。还望高手赐教啊

相关帖子

沙发
未来是梦| | 2009-10-17 21:50 | 只看该作者
本帖最后由 未来是梦 于 2009-10-17 23:09 编辑

不过是个C语言指针问题;
比如
char * a;
int * b;
假设 char 是一个字节,int是4个字节;
a,b初始值都是0;
那么a+1 指向了1;
b+1就指向了4;
现在,看看 :
static unsigned long *mmu_tlb_base = (unsigned long *) MMU_TABLE_BASE
mmu_tlb_base是(unsigned long *) 型的指针,这里unsigned long占4个字节;
那么对它+1,就产生4个字节的内存偏移;
第二个问题,右移20位,是因为一页的的大小是SZ_1M,;
如果把mmu_tlb当作一个大数组,那么物理地址右移20位就可以得这个数组的下标0x300,然后就填页表;其他一些基础知识你的理解也是不对,建议多看看书

使用特权

评论回复
板凳
zl39049979|  楼主 | 2009-10-18 12:14 | 只看该作者
2# 未来是梦 已经解决

使用特权

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

本版积分规则

10

主题

32

帖子

0

粉丝