MMU初始化问题
是redboot的一段启动代码。<br />CPU为 ARM926EJ<br /><br />REDBOOT的程序段都在FLASH中运行,没有拷贝到RAM。而且<br /><br />程序段的编译地址为C0000000(虚地址)开始.<br /><br />程序实际烧写到到00000000开始的FLASH中,然后启动代码将将0开始的FLASH映射到C0000000空间。<br /><br /><br /><br />摘录一段与MMU初始化有关的启动代码(CACHE在之前已经使能):<br /> bl hal_mmu_init<br /> FAKE_LED_MACRO(6)<br /><br /> // Enable MMU<br /> ldr r2,=10f<br /> ldr r1,=MMU_Control_Init|MMU_Control_M<br /> mcr MMU_CP,0,r1,MMU_Control,c0<br /> <font color=#FF0000><font color=#FF0000></font>mov pc,r2 <font color=#FF0000></font></font> <br />10: <br /> nop<br /> nop<br /><br /><br />hal_mmu_init是C语言函数,将00000000开始的FLASH 映射到C0000000空<br /><br />间,<br />mcr MMU_CP,0,r1,MMU_Control,c0 这条使能MMU。<br /><br />mov pc,r2 实现绝对跳转,跳到标号10开始的地方,该地址是绝对地<br /><br />址,也是虚拟地址。因为此时MMU已经初始化完成,从下一条指令开始,程序从虚拟地址(编译指定的地<br /><br />址)开始运行。<br /><br />现在对mov pc,r2 这条指令的执行有点疑问,这条指令是怎样取指的?<br />这条指令之前MMU已经使能,00000000开始的空间已经不存在,<br />我在想<br />mcr MMU_CP,0,r1,MMU_Control,c0执行时,应该mov pc,r2这条<br /><br />指令已经取指,所以MMU使能后,mov pc,r2能被取指、执行。<br /><br />不知道这样理解对不对?<br />今天终于可以用仿真器调试了
与猜测结果基本吻合。<br /> mcr MMU_CP,0,r1,MMU_Control,c0<br /> mov pc,r2 <br /><br />单步:mcr MMU_CP,0,r1,MMU_Control,c0 执行后<br /> mov pc,r2 无法取指,程序飞掉,<br /> 应该是单步时,指令取指不再是流水线的缘故,取一条指令,执行一条指令。内容变化
我认为,在使能MMU后,mov pc, r2这条指令还没有执行时,内存中的内容已经发生了变化,mov pc, r2 指令执行后,PC指向了10处,但这里的指令已经不是原来的内容,程序就会跑飞。你可以检查比较一下。我觉得是使能MMU的问题
我觉得是使能MMU的问题,而不是mov pc, r2这条指令的问题RE
mcr MMU_CP,0,r1,MMU_Control,c0 这条指令执行时,<br /><br />应该mov pc,r2这条指令已经取指,<br />所以MMU使能后,mov pc,r2能被取指、执行。<br /><br />我是这样理解,<br /><br />PC指向了10处时(也就是mov pc,r2执行后),标号10处的内容和<br />MMU使能之前的内容是一模一样的,仿真器看过了,只不过空间变换了,<br />MMU使能前从0x0000000开始,使能后从 0xc000000开始<br />检查建议
1:在跳转指令mov pc, r2前<br />和<br />使能MMU的指令mcr MMU_CP,0,r1,MMU_Control,c0 后<br />可以添加2条NOP指令来填充流水线,避免指令预取造成的干扰<br /> mcr MMU_CP,0,r1,MMU_Control,c0<br /> nop<br /> nop<br /> mov pc,r2 <br />2:映射并使能MMU后,所有地址对于CPU而言都是虚拟地址。所以检查10<br />是否是一个合法的虚拟地址。<br /><br />有问题大家一块讨论,增张知识!!<br /> 学学 linux上面的吧
第一页的虚拟地址和物理地址完全一样,即等效映射.<br />这样可以平缓过度... 后面再把该页的修改过来.
页:
[1]