ARM Linux (S3C6410架构/2.6.35内核)的内存映射(五)

发布者:落寞梦惊最新更新时间:2016-06-22 来源: eefocus关键字:ARM  Linux  S3C6410架构  2.6.35内核  内存映射 手机看文章 扫描二维码
随时随地手机看文章

ARM Linux的访问权限控制

ARM1176JZF-S处理器为访问权限控制定义了两个层次:第一层是"域"(Domain)的访问类型,第二层是页或者段的"读写权限"(Access Permission)。具体来说,过程是这样的:

1. 在ARM处理器中,MMU将整个存储空间分成最多16个域,记作D0~D15,每个域对应一定的存储区域,该区域具有相同的访问控制属性。每个域的访问权限分别由CP15的C3寄存器中的两位来设定,c3寄存器的大小为32bits,刚好可以设置16个域的访问权限。

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] 参考ARM1176JZF-S Revision: r0p7->6.5.2 Access permissions
 
 
下面看一下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] 

系统中定义了多个映射类型,最常用的是MT_MEMORY,它对应RAM;MT_DEVICE则对应了其他I/O设备,应用于ioremap;MT_ROM对应于ROM;MT_LOW_VECTORS对应0地址开始的向量;MT_HIGH_VECTORS对应高地址开始的向量,它有vector_base宏决定。

   [c]
arch/arm/include/asm/io.h

#define MT_DEVICE               0
#define MT_DEVICE_NONSHARED     1
#define MT_DEVICE_CACHED        2
#define MT_DEVICE_WC            3

arch/arm/include/asm/mach/map.h

#define MT_UNCACHED             4
#define MT_CACHECLEAN           5
#define MT_MINICLEAN            6
#define MT_LOW_VECTORS          7
#define MT_HIGH_VECTORS         8
#define MT_MEMORY               9
#define MT_ROM                  10
[/c] 

尽管ARM定义了16种不同的域,但是Linux只使用其中的三种:D0 ~ D2 (arch/arm/include/asm/domain.h)

   [c]
#define DOMAIN_KERNEL   0
#define DOMAIN_TABLE    0
#define DOMAIN_USER     1
#define DOMAIN_IO       2
[/c] 

内存空间和三种域的对应关系如下:

内存空间
设备空间 DOMAIN_IO
内部高速SRAM空间/内部MINI Cache空间 DOMAIN_KERNEL
RAM内存空间/ROM内存空间 DOMAIN_KERNEL
高低端中断向量空间 DOMAIN_USER


ARM处理器为每一个域定义了四种不两只的访问类型(0b00 ~ 0x11),Linux使用其中的三种(0b10不用),宏定义如下:
arch/arm/include/asm/domain.h

   [c]
#define DOMAIN_NOACCESS 0
#define DOMAIN_CLIENT   1
#define DOMAIN_MANAGER  3
[/c] 

Linux在系统引导设置MMU时初始化c3寄存器来实现对内存域的访问控制。其中对DOMAIN_USER,DOMAIN_KERNEL和DOMAIN_TABLE均设置DOMAIN_MANAGER权限;对DOMAIN_IO设置DOMAIN_CLIENT权限。
arch/arm/include/asm/domain.h

   [c]
#define domain_val(dom,type)    ((type) << (2*(dom)))

arch/arm/kernel/head.S
    ......
    mov     r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
                  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
                  domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
                  domain_val(DOMAIN_IO, DOMAIN_CLIENT))
    mcr     p15, 0, r5, c3, c0, 0           @ load domain access register
    mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
    b       __turn_mmu_on
ENDPROC(__enable_mmu)
[/c] 

在系统的引导过程中对这3个域的访问控制位并不是一成不变的,它提供了一个名为modify_domain的宏来修改域访问控制位。系统在setup_arch中调用early_trap_init后,DOMAIN_USER的权限位将被设置成DOMAIN_CLIENT。
arch/arm/include/asm/domain.h

   [c]
#define set_domain(x)                                   \
        do {                                            \
        __asm__ __volatile__(                           \
        "mcr    p15, 0, %0, c3, c0      @ set domain"   \
          : : "r" (x));                                 \
        isb();                                          \
        } while (0)

#define modify_domain(dom,type)                                 \
        do {                                                    \
        struct thread_info *thread = current_thread_info();     \
        unsigned int domain = thread->cpu_domain;               \
        domain &= ~domain_val(dom, DOMAIN_MANAGER);             \
        thread->cpu_domain = domain | domain_val(dom, type);    \
        set_domain(thread->cpu_domain);                         \
        } while (0)
[/c] 

关键字:ARM  Linux  S3C6410架构  2.6.35内核  内存映射 引用地址:ARM Linux (S3C6410架构/2.6.35内核)的内存映射(五)

上一篇:ARM1176JZFS/S3C6410 内存地址转换
下一篇:ARM Linux (S3C6410架构/2.6.35内核)的内存映射(四)

推荐阅读最新更新时间:2024-03-16 14:58

ARM·存储器配置
关于配置SDRAM的这个程序,因为研究了2天,所以这里最后再复习一下 首先补充一下基本的知识: 运行地址- 链接地址 在SRAM或者SDRAM中执行程序时,PC指向这个地址,那么命令就应该在这个地址里面 ; 加载地址- 存储地址 程序保存在NAND FLSAH中的地址 位置无关码:B,BL,MOV 位置有关码:LDR PC,=Label 【关于Makefile】 sdram.bin : head.S leds.c arm-linux-gcc -c -o head.o head.S arm-linux-gcc -c -o leds.o leds.c arm-linux-l
[单片机]
ARM嵌入式平台的VGA接口设计
大多数嵌入式产品的显示终端都选择LCD,但在某些需要大屏幕显示的应用中,工业级LCD的价格比较昂贵,且现有的大屏幕显示器(包括CRT显示器和LCD显示器)一般都采用统一的15针VGA显示接口。三星公司ARM9芯片S3C2410以其强大的功能和高性价比在目前嵌入式产品中得到广泛的应用。笔者在开发基于ARM嵌入式平台的血液流变测试仪的过程中,成功地利用高性能视频D/A转换芯片ADV7120,将S3C2410自带的LCD扫描式接口转换为VGA接口,使之能够驱动VGA接口的显示器。 1 VGA接口介绍 近年来,业界制定出了众多数字化的显示接口协议,较为典型的是DVI(Digital Visual Interface)。由于数字接口的标
[工业控制]
[Linux 底层]U-boot编译移植
系统版本:Ubuntu18.04-64 编译器版本:gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) uboot版本:2018.07 -linux4sam_6.0 板子型号:at91sama5d3x-xplained MCU型号:sama5d36 1、uboot目录如下: 2、在configs/ 文件夹下面有官方的默认配置 # To put environment variables in nandflash (default): sama5d3_xplained_nandflash_defconfig # To put envi
[单片机]
[<font color='red'>Linux</font> 底层]U-boot编译移植
Linux下vim编辑器的使用小技巧
Vim是Linux操作系统中最常用一个编辑器。如配置文件的更改、环境变量的设置等等基本上都是在这个vim编辑器上完成。所以这是Linux系统管理员最常用的一个工具。不过这个工具虽然小,但是其有很多的实用小技巧。有些系统管理员可能并不知道。在此笔者就把这些技巧共享出来,大家若觉得有用,不妨在工作中用用看。 一、备份个性化配置文件。 Vim文本编辑器有很多默认的设置。但是当系统管理员熟悉了这个工具之后,可能这个默认的设置就不符合他们的需求了。为此系统管理员希望能够像Word等文本处理器一样对其进行一些个性化的设置,以方便他们编写配置文件、设置环境变量等等。如系统管理员可能会重新定义某些键的功能、创建一些缩写符号、或者设置特定的
[嵌入式]
基于ARM的在线更新机制的设计实现
0 引言 分散型控制系统中的现场终端一般由控制器和各检测模块构成,它们之间通过一定的通信网络建立数据的交换链路。这种系统具有高可靠、开放性、灵活性、协调性、易维护等优点。然而,该分散型系统也具有终端数量多、分布范围广的特点。一旦终端系统软件存在缺陷或用户提出新的功能和指标要求时,其升级、维护的工作量和成本都非常大。本文针对上述情况,设计了一种方便、灵活、快速及稳定地对MCU节点进行在线更新的机制。基于LPC11C24微控制器组成的CAN网络,采用IAP编程技术(In Application Programming),实现了对目标节点MCU的软件更新功能。 1 LPC11C24单片机和CAN总线 恩智浦半导体(NXP)推出业界首款内嵌
[单片机]
基于<font color='red'>ARM</font>的在线更新机制的设计实现
ARM、DSP、FPGA的技术特点和区别有哪些
ARM、DSP、FPGA与什么区别?各自有什么特点?这是一个很基础的问题,本文对ARM、DSP、FPGA的各自特点和技术进行了分析。 ARM(Advanced RISC Machines)是微处理器行业的一家知名企业,设计了大量高性能、廉价、耗能低的RISC处理器、相关技术及软 件。ARM架构是面向低预算市场设计的第一款RISC微处理器,基本是32位单片机的行业标准,它提供一系列内核、体系扩展、微处理器和系统芯片方案,四 个功能模块可供生产厂商根据不同用户的要求来配置生产。由于所有产品均采用一个通用的软件体系,所以相同的软件可在所有产品中运行。目前ARM在手持设备 市场占有90以上的份额,可以有效地缩短应用程序开发与测试
[单片机]
Arm联合创始人:Arm收购将使美形成新的技术垄断
据thisismoney报道,Arm联合创始人Hermann Hauser警告称,若将Arm出售给英伟达,美国将形成技术垄断。 Hauser称,基于Arm架构设计的芯片无处不在。收购Arm将意味着Arm不再是“半导体行业的瑞士”,它的知识产权可能会让英伟达成为谷歌、Facebook和亚马逊那样的主导力量。 在一封给议会外交事务委员会的信中,Hauser说:“世界上任何一家重要的半导体公司都能获得Arm许可证。” 英伟达有机会成为全球微处理器的准垄断供应商。这将使英伟达在所有处理器领域占据主导地位,并形成另一家美国技术垄断企业。英伟达虽一再强调,它将保持Arm对竞争对手的中立立场,但有人呼吁对该交易进行调查。
[手机便携]
ARM入门笔记
ISP实验 一.背景 由于前面的实验都是用仿真器将代码下载到AT91SAM7S64的SRAM里调试的,还不能在实际的Flash ROM里跑。所以在这个实验中,我们将通过ATMEL提供的SAM-BA 软件和AT91SAM7S64自带的ROMBoot功能,完成AT91SAM7S64的Flash ROOM的在线烧写。 二.实验目的 用前面 I/O口输入实验 的源程序生成二进制文件,下载到AT91SAM7S64的Flash ROM中,且能脱机正确运行。 三.操作方法 1 安装。双击Install SAM-BA.exe文件运行,按提示一步步安装即可。 2 连接好硬件,且使AT91SAM7S64处于RomBoot状态。 3 运行。双
[单片机]
<font color='red'>ARM</font>入门笔记
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
502 Bad Gateway

502 Bad Gateway


openresty
设计资源 培训 开发板 精华推荐

502 Bad Gateway

502 Bad Gateway


openresty
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
随便看看
    502 Bad Gateway

    502 Bad Gateway


    openresty
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
502 Bad Gateway

502 Bad Gateway


openresty