zyp000 发表于 2012-4-10 20:16:03

请教一下MMU。

本帖最后由 zyp000 于 2012-4-10 21:03 编辑

初学,有些关于MMU的问题想请教下。
调试软件:KeilARM
硬件:TQ2440+JLINKv8

scatter文件如下
LR_ROM1 0x00000000 0x00100000{    ; load region size_region
ER_ROM1 0x00000000 0x00100000{; load address = execution address
   *.o(RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
}
RW_RAM1 0xA0004000 0x04000000{; RW data
   main.o(+RO)
   .ANY (+RW +ZI)
}
RW_IRAM 0x40000000 0x1000{
   .ANY (+RW +ZI)
}
}

1.没有使用MMU,并且scatter文件中第7行为 RW_RAM1 0x30000000 0x04000000 时,程序是成功的跑在SDRAM里的。

2.用MMU把0xA0000000起始的64MB空间映射到SDRAM上,0x30000000起始的64MB空间。
这样main.o段实际上就还应该是在SDRAM中运行了吧?

但是使用了MMU后,程序似乎是运行了,但是没有得到预期效果。
测试程序是一个简单流水灯程序,在试验MMU时,开发板刚上电后,大约1秒,4个IO控制的灯全部亮起,如果程序没有跑,4个IO等应该全是熄灭的吧?
我的MMU操作代码如下:
void create_pagetable(void)
{
        /* 段基址,AP,Domain,C,B,0b10为段描述符 */
        #define MMUFullAccess         (3<<10)
        #define MMUDomain                 (0<<5)
        #define MMUSpecial                 (1<<4)         //必须是1?
        #define MMUCacheAble         (1<<3)
        #define MMUBuffAble         (1<<2)
        #define MMUSection                 (2)

        #define MMUSecdesc                 (MMUFullAccess|MMUDomain|MMUSpecial|MMUSection)
        #define MMUSecdescWB        (MMUFullAccess|MMUDomain|MMUSpecial|MMUCacheAble|MMUBuffAble|MMUSection)
       
        unsigned int i;
        unsigned long mvaddr,paddr;
        unsigned long *ptbase = (unsigned long *)0x30000000;

        mvaddr         = 0;
        paddr         = 0;
        *( ptbase + ( mvaddr >> 20 ) )                 = ( paddr & 0xFFF00000 ) | MMUSecdescWB ;
        *( ptbase + ( mvaddr >> 20 ) + 1 )         = ( ( paddr + 0x100000 ) & 0xFFF00000 ) | MMUSecdescWB ;
       
        mvaddr        = 0x40000000;
        paddr        = 0x40000000;
        *( ptbase + ( mvaddr >> 20 ) )                 = ( paddr & 0xFFF00000 ) | MMUSecdesc ;

        mvaddr         = 0x48000000;
        paddr        = 0x48000000;
        for( i = 0 ; i < 0x181 ; i++ )
                *( ptbase + ( mvaddr >> 20 ) + i) = ( ( paddr + i * 0x100000 ) & 0xFFF00000 ) | MMUSecdesc ;
       
        mvaddr         = 0xA0000000;
        paddr         = 0x30000000;
        for( i = 0 ; i < 64 ; i++ )
                *( ptbase + ( mvaddr >> 20 ) + i) = ( ( paddr + i * 0x100000 ) & 0xFFF00000 ) | MMUSecdescWB ;
          
}

void MMUOn(void)
{
        unsigned long ptbase = 0x30000000;
        __asm
        {

        /* 使无效ICaches和DCaches */
        mov r1,#0
        mcr p15,0,r1,c7,c7,0

        /* 清空写缓冲区 */
        mcr p15,0,r1,c7,c10,4

        /* 使无效指令、数据TLB */
        mcr p15,0,r1,c8,c7,0

        /* 设置页表基地址 */
        mov r1,ptbase
        mcr p15,0,r1,c2,c0,0

        /* 域访问不检查权限 */
        mvn r1,#0
        mcr p15,0,r1,c3,c0,0
          
        /* 操作控制寄存器 */
        mrc p15,0,r1,c1,c0,0
        bic r1,r1,#0x3387
        orr r1,r1,#0x1007
        mcr p15,0,r1,c1,c0,0
       
        }
}
页: [1]
查看完整版本: 请教一下MMU。