韦东山Linux嵌入式课程社区
直播中

任青

7年用户 182经验值
私信 关注

为什么MMU实验不是4字节对齐?

是4B的一级描述符,图上写错了,抱歉
这个是韦老师MMU实验的C语言源码,可以正常使用,但是问题来了,4B的描述符地址的[1:0]位应该是00啊,也就是4字节对齐啊,可是这里明显不是4字节对齐,而是1字节对齐
我找了一下完全开发手册,里面的MMU段地址转换过程图如下所示
也就是说,这里的VA是右移18位,并不是像韦老师源码里的右移20位,可是我把韦老师的源码改为右移18位后,发现程序无法正常跑起来,这是为什么呢?
有没有人亲手写过MMU实验的?能不能帮我分析分析?

回帖(3)

张霞

2019-8-5 09:40:50
你要知那20bit是用来干什么的~用来区别1M空间的地址。
举报

冯晓婕

2019-8-5 09:55:53
2∧20刚好等于1M
举报

刘丽菲

2019-8-5 10:08:30
时间过得有点久了,最近重新看了一下mmu部分。我发现这个问题的答案是什么了。
一开始我还是弄不懂为什么,但是后来我看了一下反编译代码,发现有这么几句:
    unsigned long virtuladdr, physicaladdr;
    unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
    virtuladdr = 0xA0000000;
    physicaladdr = 0x56000000;
    *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | MMU_SECDESC;
以上是编译前的c语言源代码
以下是编译后经过反编译的汇编代码
  e0:        e3a02c0a         mov        r2, #2560        ; 0xa00
  e4:        e3a0120b         mov        r1, #-1342177280        ; 0xb0000000
  e8:        e78c3102         str        r3, [ip, r2, lsl #2]
第一句代码是0xa000 0000左移20位后得出的数,作为偏移码,而第三句则是将r3中的描述符放入0x3000 0000+(0xa00<<2)中,这里就是问题之处,明明代码中写的是右移20位,可是在真正存入指针所指的地址的时候,却又左移了两位,刚好就是18位。
一开始我还不明白为什么会右移20位之后又重新左移两位,后来看了一下c代码,指针的类型都是unsigned long型的,自增1的时候,地址会自增4,例如有如下定义:
unsigned long *p1=0x3000 0000;
p1++;//此时p1=0x3000 0004
或者
p1=p1+4;//此时p1=0x3000 0000+4*4 即 p1=0x3000 0000+(4<<2)
所以c代码中的:
*(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | MMU_SECDESC;
之所以virtuladdr>>20,就是因为mmu_tlb_base是unsigned long型的指针,所以左移20位后会再次乘4,即左移两位
举报

更多回帖

发帖
×
20
完善资料,
赚取积分