Linux内存细节 build_mem_type_table与prepare_page_table

build_mem_type_table函数主要是mem_types对不同entry映射条目的后面域内容进行定义。 prepare_page_table是将虚拟地址对应的可以清空的字段全部清空。

1. build_mem_type_table

/*
 * Adjust the PMD section entries according to the CPU in use.
 */
static void __init build_mem_type_table(void)
{
	struct cachepolicy *cp;
	unsigned int cr = get_cr();
	unsigned int user_pgprot, kern_pgprot;
	int cpu_arch = cpu_architecture();
	int i;

#if defined(CONFIG_CPU_DCACHE_DISABLE)
	if (cachepolicy > CPOLICY_BUFFERED)
		cachepolicy = CPOLICY_BUFFERED;
#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
	if (cachepolicy > CPOLICY_WRITETHROUGH)
		cachepolicy = CPOLICY_WRITETHROUGH;
#endif
	printk("cpu_arch: %d\n", cpu_arch);
	if (cpu_arch < CPU_ARCH_ARMv5) {
		if (cachepolicy >= CPOLICY_WRITEALLOC)
			cachepolicy = CPOLICY_WRITEBACK;
		ecc_mask = 0;
	}

	/*
	 * ARMv5 and lower, bit 4 must be set for page tables.
	 * (was: cache "update-able on write" bit on ARM610)
	 * However, Xscale cores require this bit to be cleared.
	 */
	if (cpu_is_xscale()) {
		for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
			mem_types[i].prot_sect &= ~PMD_BIT4;
			mem_types[i].prot_l1 &= ~PMD_BIT4;
		}
	} else if (cpu_arch < CPU_ARCH_ARMv6) {
		for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
			if (mem_types[i].prot_l1)
				mem_types[i].prot_l1 |= PMD_BIT4;
			if (mem_types[i].prot_sect)
				mem_types[i].prot_sect |= PMD_BIT4;
		}
	}

	cp = &cache_policies[cachepolicy];
	kern_pgprot = user_pgprot = cp->pte;
	printk("kern_pgprot: %u", kern_pgprot);

	/*
	 * Enable CPU-specific coherency if supported.
	 * (Only available on XSC3 at the moment.)
	 */
	if (arch_is_coherent()) {
		if (cpu_is_xsc3()) {
			mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
			mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
		}
	}

	/*
	 * ARMv6 and above have extended page tables.
	 */
	if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
		/*
		 * Mark cache clean areas and XIP ROM read only
		 * from SVC mode and no access from userspace.
		 */
		mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
		mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;

		/*
		 * Mark the device area as "shared device"
		 */
		mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
		mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;

#ifdef CONFIG_SMP
		/*
		 * Mark memory with the "shared" attribute for SMP systems
		 */
		user_pgprot |= L_PTE_SHARED;
		kern_pgprot |= L_PTE_SHARED;
		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
#endif
	}

	for (i = 0; i < 16; i++) {
		unsigned long v = pgprot_val(protection_map[i]);
		v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
		protection_map[i] = __pgprot(v);
	}

	mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
	mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;

	if (cpu_arch >= CPU_ARCH_ARMv5) {
#ifndef CONFIG_SMP
		/*
		 * Only use write-through for non-SMP systems
		 */
		mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
		mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
#endif
	} else {
		mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
	}

	pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
				 L_PTE_DIRTY | L_PTE_WRITE |
				 L_PTE_EXEC | kern_pgprot);

	mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
	mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
	mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
	mem_types[MT_ROM].prot_sect |= cp->pmd;

	switch (cp->pmd) {
	case PMD_SECT_WT:
		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
		break;
	case PMD_SECT_WB:
	case PMD_SECT_WBWA:
		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
		break;
	}
	printk("Memory policy: ECC %sabled, Data cache %s\n",
		ecc_mask ? "en" : "dis", cp->policy);

	for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
		struct mem_type *t = &mem_types[i];
		if (t->prot_l1)
			t->prot_l1 |= PMD_DOMAIN(t->domain);
		if (t->prot_sect)
			t->prot_sect |= PMD_DOMAIN(t->domain);

		printk("mem_types %d: prot_pte=0x%x, prot_pte_ext=0x%x, prot_l1=0x%x, prot_sect=0x%x, domain=0x%x\n", i, t->prot_pte, t->prot_pte_ext, t->prot_l1, t->prot_sect, t->domain);
	}
}

代码执行打印结果如下: 

cpu_arch: 3
kern_pgprot: 12Memory policy: ECC disabled, Data cache writeback
mem_types 0: prot_pte=0xa3, prot_pte_ext=0x0, prot_l1=0x51, prot_sect=0x452, domain=0x2
mem_types 1: prot_pte=0xa3, prot_pte_ext=0x80, prot_l1=0x51, prot_sect=0x2452, domain=0x2
mem_types 2: prot_pte=0xaf, prot_pte_ext=0x0, prot_l1=0x51, prot_sect=0x45e, domain=0x2
mem_types 3: prot_pte=0xa3, prot_pte_ext=0x0, prot_l1=0x51, prot_sect=0x1456, domain=0x2
mem_types 4: prot_pte=0x0, prot_pte_ext=0x0, prot_l1=0x0, prot_sect=0x1e, domain=0x0
mem_types 5: prot_pte=0x0, prot_pte_ext=0x0, prot_l1=0x0, prot_sect=0x1a, domain=0x0
mem_types 6: prot_pte=0xcf, prot_pte_ext=0x0, prot_l1=0x31, prot_sect=0x0, domain=0x1
mem_types 7: prot_pte=0xdf, prot_pte_ext=0x0, prot_l1=0x31, prot_sect=0x0, domain=0x1
mem_types 8: prot_pte=0x0, prot_pte_ext=0x0, prot_l1=0x0, prot_sect=0x41e, domain=0x0
mem_types 9: prot_pte=0x0, prot_pte_ext=0x0, prot_l1=0x0, prot_sect=0x1e, domain=0x0

2. prepare_page_table

prepare_page_table: start=0x0, MODULE_START=0xbf000000, PAGE_OFF=0xc0000000, PGDIR_SIZE=0x200000, VMALLOC_END=0xe0000000, exc_memory_bank=0xc4000000

主要是这些字段进行清空

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值