ARM Linux (S3C6410架构/2.6.35内核)的内存映射(五)
ARM Linux的访问权限控制
ARM1176JZF-S处理器为访问权限控制定义了两个层次:第一层是"域"(Domain)的访问类型,第二层是页或者段的"读写权限"(Access Permission)。具体来说,过程是这样的:
1.
Bits | 31, 30 | 29, 28 | 27, 26 | 25, 24 | 23, 22 | 21, 20 | 19, 18 | 17, 16 | 15, 14 | 13, 12 | 11, 10 | 9, 8 | 7, 6 | 5, 4 | 3, 2 | 1, 0 |
Domain | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
对于每一个域所对应的两个bit,访问类型设置方法如下:
值 | 访问类型 | 含义 |
---|---|---|
0b00 | 无访问权限 | 此时访问该域将产生访问失效 |
0b01 | 用户(client) | 根据CP15的C1控制寄存器中的R和S位以及页表中地址变换条目中的访问权限控制位AP来确定是否允许各种系统工作模式的存储访问 |
0b10 | 保留 | 使用该值会产生不可预知的结果 |
0b11 | 管理者(Manager) | 不考虑CP15的C1控制寄存器中的R和S位以及页表中地址变换条目中的访问权限控制位AP,在这种情况下不管系统工作在特权模式还是用户模式都不会产生访问失效 |
2. 如果域的访问类型是0b01的话,下面就进入第二层。所访问内存页或段的权限还要根据CP15的C1寄存器中的R和S位以及页/段表项中的访问权限控制位AP(X)来决定。
APX | AP[1:0] | 特权模式访问权限 | 用户模式访问权限 |
---|---|---|---|
0 | b00 | 禁止访问;S=1,R=0或S=0,R=1时只读 | 禁止访问;S=1,R=0时只读 |
0 | b01 | 读写 | 禁止访问 |
0 | b10 | 读写 | 只读 |
0 | b11 | 读写 | 读写 |
1 | b00 | 保留 | 保留 |
1 | b01 | 只读 | 禁止访问 |
1 | b10 | 只读 | 只读 |
1 | b11 | 只读 | 只读 |
[8] |
下面看一下Linux是如何实现的。
在谈到create_mapping之前,必须说明一下Linux是如何实现对页面的访问控制的。
Linux使用结构体mem_type来定义不同的内存映射类型(arch/arm/mm/mm.h),不同的映射类型定义了不同的访问权限:
[c]struct mem_type {unsigned int prot_pte;unsigned int prot_l1;unsigned int prot_sect;unsigned int domain;};[/c]
其中处成员含义如下:
prot_pte代表页表项的访问控制权,pte即第二级映射表项(页表项)。
prot_l1代表段表项的访问控制位,l1即第一级映射表项(段表项/主页表项)。
prot_sect代表主页表(注意,不是主页表项)的访问控制位和内存域。
domain代表所属的内存域。
对于ARM处理器,Linux定义了一个类型为struct mem_type的局部静态数组(arch/arm/mm/mmu.c)。根据不同的映射类型,定义了不同的访问权限。
[c]static struct mem_type mem_types[] = {[MT_DEVICE] = { .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |L_PTE_SHARED,.prot_l1 = PMD_TYPE_TABLE,.prot_sect = PROT_SECT_DEVICE | PMD_SECT_S,.domain = DOMAIN_IO,},[MT_DEVICE_NONSHARED] = { .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_NONSHARED,.prot_l1 = PMD_TYPE_TABLE,.prot_sect = PROT_SECT_DEVICE,.domain = DOMAIN_IO,},[MT_DEVICE_CACHED] = { .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_CACHED,.prot_l1 = PMD_TYPE_TABLE,.prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB,.domain = DOMAIN_IO,},[MT_DEVICE_WC] = { .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,.prot_l1 = PMD_TYPE_TABLE,.prot_sect = PROT_SECT_DEVICE,.domain = DOMAIN_IO,},[MT_UNCACHED] = {.prot_pte = PROT_PTE_DEVICE,.prot_l1 = PMD_TYPE_TABLE,.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,.domain = DOMAIN_IO,},[MT_CACHECLEAN] = {.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,.domain = DOMAIN_KERNEL,},[MT_MINICLEAN] = {.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,.domain = DOMAIN_KERNEL,},[MT_LOW_VECTORS] = {.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |L_PTE_EXEC,.prot_l1 = PMD_TYPE_TABLE,.domain = DOMAIN_USER,},[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,},[MT_MEMORY] = {.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,.domain = DOMAIN_KERNEL,},[MT_ROM] = {.prot_sect = PMD_TYPE_SECT,.domain = DOMAIN_KERNEL,},[MT_MEMORY_NONCACHED] = {.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,.domain = DOMAIN_KERNEL,},};[/c]
ARMLinuxS3C6410架构2 6 35内核内存映 相关文章:
- ARM Linux (S3C6410架构/2.6.35内核)的内存映射(三)(11-09)
- ARM Linux (S3C6410架构/2.6.35内核)的内存映射(四)(11-09)
- ARM Linux (S3C6410架构/2.6.35内核)的内存映射(二)(11-09)
- 达芬奇数字媒体片上系统的架构和Linux启动过程(06-02)
- 基于TMS320DM642的农药喷洒系统(04-22)
- 用DSP56F805 PWM模块输出高频正弦波(05-25)