从create_mapping()看arm linux的页表
来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/120613197201571932454226
createmapping会调用到allocinitpte(), 进而调用setpte_ext()
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
这里qemu模拟的versatilepb ARM Versatile/PB (ARM926EJ-S) ARMv5TEJ
所以setpteext(pte, pfnpte(pfn, _pgprot(type->prot_pte)), 0);
就是
cpuarm926setpteext (pte, pfnpte(pfn, _pgprot(type->prot_pte)), 0);
/*
* cpu_arm926_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
ENTRY(cpu_arm926_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
#endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
mov pc, lr
其中宏armv3setpte_ext实现在 linux-2.6.35.7/arch/arm/mm/proc-macros.S
/*
* The ARMv3, ARMv4 and ARMv5 set_pte_ext translation function,
* covering most CPUs except Xscale and Xscale 3.
*
* Permission translation:
* YUWD AP SVC User
* 0xxx 0x00 no acc no acc
* 100x 0x00 r/o no acc
* 10x0 0x00 r/o no acc
* 1011 0x55 r/w no acc
* 110x 0xaa r/w r/o
* 11x0 0xaa r/w r/o
* 1111 0xff r/w r/w
*/
.macro armv3_set_pte_ext wc_disable=1
str r1, [r0], #-2048 @ linux version
cpuarm926setpteext(ptep, pte, ext)参数中的ptep已经指向linux版的pte了, linux版在高地址, hw版在低地址, 所以有上面的-2048.
arm hw版二级页表和linux版 在内存布局的关系如下图所示:
高地址 +--------------+ x+1024*4
^ | linux pte |
| | |
| +--------------+ x+1024*3
| | linux pte |
| | |
| +--------------+ x+1024*2
| | hw pte |
| | |
| +--------------+ x+1024*1
| hw pte |
| |
低地址 +--------------+ x+0
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
bic r2, r2, #PTE_TYPE_MASK
orr r2, r2, #PTE_TYPE_SMALL
先清低2位,然后D1:D0写为10,也就是使用small page
tst r3, #L_PTE_USER @ user?
orrne r2, r2, #PTE_SMALL_AP_URO_SRW
将linux版本的LPTEUSER转为arm版本
这个bit(LPTEUSER)来自memtypes[]的struct memtype的成员prot_pte
static struct mem_type mem_types[] = {
[MT_HIGH_VECTORS] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
L_PTE_USER | L_PTE_EXEC,
.prot_l1 = PMD_TYPE_TABLE,
.domain = DOMAIN_USER,
},
};
tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty?
orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
留意0x55| 0xaa==0xff, 对应本段代码前面的注释
Permission translation:
YUWD AP SVC User
1011 0x55 r/w no acc
110x 0xaa r/w r/o
11x0 0xaa r/w r/o
1111 0xff r/w r/w
问题:AP3到AP0是?
答:If the level one descriptor defines a page-mapped access and the level two descriptor is for a large or small page, four access permission fields, ap3
to ap0, are specified, each corresponding to one quarter of the page. For small pages ap3 is selected by the top 1KB of the page and ap0 is selected by the bottom 1KB of the page.
问题:对于二级页表中small page, 当前是哪个domain呢?
答:所属的一级页表的domain决定, 见Figure3-4. D8:D5这4个bit选择16个domain中的一个.
tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
movne r2, #0
对应arm的二级页表中的fault的情况, 见Figure3-9.
.if \wc_disable
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
tst r2, #PTE_CACHEABLE
bicne r2, r2, #PTE_BUFFERABLE
#endif
.endif
str r2, [r0] @ hardware version
.endm
相关资料 ARM926EJ-S Technical Reference Manual
本文地址: https://awakening-fong.github.io/posts/arm/arm_create_mapping_page_table
转载请注明出处: https://awakening-fong.github.io
若无法评论, 请打开JavaScript, 并通过proxy.
blog comments powered by Disqus