主题 : 东山的(嵌入式linux 应用开发) mmu映射程序看不懂!!需求解释 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 5252
精华: 0
发帖: 8
金钱: 80 两
威望: 80 点
综合积分: 16 分
注册时间: 2009-04-16
最后登录: 2009-08-10
楼主  发表于: 2009-04-17 21:35

 东山的(嵌入式linux 应用开发) mmu映射程序看不懂!!需求解释

不知道有谁也在看这本书,书中关于建立页表这块,虚拟地址移位 virtuladdr>>20  ;怎么看感觉都不对,感觉应该移18位就可以了,请高手指点下。。程序间下方:(红色标记位置)void create_page_table(void)
{

/*
* 用于段描述符的一些宏定义
*/
#define MMU_FULL_ACCESS     (3 << 10)   /* 访问权限 */
#define MMU_DOMAIN          (0 << 5)    /* 属于哪个域 */
#define MMU_SPECIAL         (1 << 4)    /* 必须是1 */
#define MMU_CACHEABLE       (1 << 3)    /* cacheable */
#define MMU_BUFFERABLE      (1 << 2)    /* bufferable */
#define MMU_SECTION         (2)         /* 表示这是段描述符 */
#define MMU_SECDESC         (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \
                             MMU_SECTION)
#define MMU_SECDESC_WB      (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \
                             MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)
#define MMU_SECTION_SIZE    0x00100000

    unsigned long virtuladdr, physicaladdr;
    unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
    
    /*
     * Steppingstone的起始物理地址为0,第一部分程序的起始运行地址也是0,
     * 为了在开启MMU后仍能运行第一部分的程序,
     * 将0~1M的虚拟地址映射到同样的物理地址
     */
    virtuladdr = 0;
    physicaladdr = 0;
   *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \
                                            MMU_SECDESC_WB;  


    /*
     * 0x56000000是GPIO寄存器的起始物理地址,
     * GPBCON和GPBDAT这两个寄存器的物理地址0x56000010、0x56000014,
     * 为了在第二部分程序中能以地址0xA0000010、0xA0000014来操作GPBCON、GPBDAT,
     * 把从0xA0000000开始的1M虚拟地址空间映射到从0x56000000开始的1M物理地址空间
     */
    virtuladdr = 0xA0000000;
    physicaladdr = 0x56000000;
    *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \
                                            MMU_SECDESC;


    /*
     * SDRAM的物理地址范围是0x30000000~0x33FFFFFF,
     * 将虚拟地址0xB0000000~0xB3FFFFFF映射到物理地址0x30000000~0x33FFFFFF上,
     * 总共64M,涉及64个段描述符
     */
    virtuladdr = 0xB0000000;
    physicaladdr = 0x30000000;
    while (virtuladdr < 0xB4000000)
    {
        *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \
                                                MMU_SECDESC_WB;
        v
        irtuladdr += 0x100000;
        physicaladdr += 0x100000;
    }
}
级别: 侠客
UID: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
1楼  发表于: 2009-04-18 10:09
(1 << 20) = 1024 * 1024 = 1M
不过为什么是virtualaddr >> 20呢?