1 ARM920T的MMU工作原理
下图显示了MMU地址转化关系 一级表项的地址(pmd) = ( (TLB) & (0xFFFFC000) ) + ( (Table Index)<<2 ); 注1:TLB(Translate table base),即转换表基地址 注2:由于每个表项占32位(4Bytes),因此(Table Index)<<2 一级表项的内容(*pmd) = ( (pte) & (0xFFFFFC00) ) + prot_l1; ------------------------------------------------------------------------------------- 二级表项的地址(pte) = ( (pte) & (0xFFFFFC00) ) + ( (L2 table index) <<2 ); 二级表项的内容(*pte) = ( (PA) & (0xFFFFF000) ) + prot_pte; 2 create_mapping分析 static void __init create_mapping(struct map_desc *md) pgd = pgd_offset_k(addr); //计算pgd的地址(64bits) = ((mm)->pgd+pgd_index(addr)) // = ((mm)->pgd+((addr) >> 21) ) //pmd地址(32bits) = ((mm)->pgd+((addr) >> 20) )
//PGDIR_SIZE=(1UL << PGDIR_SHIFT)=2M //一次处理2个连续的一级表项:2*1M = 2M alloc_init_section(pgd, addr, next, phys, type); phys += next - addr; //尝试使用段映射 static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, //pmd地址(32bits) = ((mm)->pgd+((addr) >> 20) )
/* 当大小和地址1MB对齐时,使用段映射 */ if (addr & SECTION_SIZE) do { //2MB,循环2次 flush_pmd_entry(p); //small页映射 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
//当一级表项内容为空时,为二级表项分配空间2*512*4 = 4Kb(1Page) if (pmd_none(*pmd)) { //给一级表项赋值,pmd为指针,指向需赋值的地址 //pmdp[0] = __pmd(pmdval); } pte = pte_offset_kernel(pmd, addr); //2MB,2Mb/4Kb = 512次(最多) .macro armv3_set_pte_ext wc_disable=1 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits tst r3, #L_PTE_USER @ user? tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? .if /wc_disable 3 Linux MMU
4 9260EK 内存映射情况
|
|