• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

arm中的系统内存映射

好的,我们来详细说明 ARM 架构中的“系统内存映射”(System Memory Map)。

这是一个非常核心的概念,它定义了处理器内核如何看待其整个地址空间,即地址总线上的每个地址对应的是什么物理设备或内存类型。

一、核心概念:什么是系统内存映射?

简单来说,系统内存映射是一张“地址分配表”。它将处理器可寻址的整个内存地址空间(例如,32位ARM是4GB的地址空间)划分成多个连续的区块,并为每个区块预先定义好其用途。

当处理器内核(CPU)想要访问一个特定的内存地址时(无论是取指令还是读写数据),这个地址会通过总线系统发送出去。内存映射决定了:

  1. 这个地址最终访问的是哪个物理设备:是内部的SRAM?还是外部的DDR内存?或者是某个外设的寄存器?
  2. 访问这些地址有什么特性:这个区域是可执行的(存放代码)吗?是可读可写的(存放数据)吗?是否有缓存(Cache)?是否有缓冲(Buffer)?

二、为什么需要内存映射?

  1. 统一编址(Memory-mapped I/O):ARM 体系结构采用“内存映射I/O”的方式。这意味着CPU访问外设(如UART, GPIO, SPI等)就像访问普通内存一样,都是通过加载(LDR)和存储(STR)指令来完成。外设的控制寄存器、状态寄存器和数据寄存器都被分配了特定的内存地址。这简化了编程模型,无需特殊的I/O指令。
  2. 结构化与模块化:预先定义好的映射使得芯片设计(SoC设计)和软件开发变得有章可循。不同的厂商(如ST, NXP, TI)在设计自己的ARM芯片时,都遵循这个通用的框架,只是填充自己特有的外设和内存大小。
  3. 安全性与特权控制:内存映射区域通常与处理器的特权级别(Privilege Level)和内存保护单元(MPU)或内存管理单元(MMU)紧密相关。例如,某些系统控制寄存器只能在内核特权模式下访问,用户模式访问会触发异常。
  4. 优化性能:通过映射,可以告诉总线系统和Cache控制器如何对待对不同区域的访问。例如,访问外部设备寄存器通常不应该被缓存,而访问内存则应被缓存以提高性能。

三、ARM(特别是Cortex-A和Cortex-M)的内存映射概览

ARM为不同的处理器系列提供了通用的内存映射建议,但具体芯片的详细映射需要查阅该芯片的参考手册。下图展示了ARM架构中系统内存映射的核心区域划分:

flowchart TD A[ARM 系统内存映射 4GB 地址空间] --> B["0x0000 0000<br>启动块(Boot Block)"] A --> C["0x4000 0000 附近<br>片上外设(Peripherals)"] A --> D["0x6000 0000 附近<br>外部RAM(如SDRAM)"] A --> E["0x8000 0000 附近<br>外部设备(如FPGA)"] A --> F["0xE000 0000 附近<br>私有外设总线(PPB)<br>Cortex-M内核外设等"] A --> G["0xFFFF 0000<br>高向量地址(可选)"] B --> B1[引导加载程序<br>(Bootloader)<br>初始代码] C --> C1[GPIO, UART, SPI等<br>控制寄存器] D --> D1[主程序运行内存<br>堆、栈、数据区] F --> F1[NVIC, SCB, SysTick<br>SysTick等内核寄存器]

1. Cortex-M 系列(微控制器)的内存映射

Cortex-M系列的内存映射是高度统一和固定的,这对于跨平台移植非常有利。其主要区域包括:

地址范围 区域名称 描述
0x0000 0000 - 0x1FFF FFFF 代码区域 (Code) 用于存放程序代码。通常映射到芯片内部的Flash存储器。也用于中断向量表。
0x2000 0000 - 0x3FFF FFFF SRAM 区域 用于存放数据(变量、堆栈等)。通常映射到芯片内部的SRAM。
0x4000 0000 - 0x5FFF FFFF 片上外设 (Peripherals) 映射到芯片厂商集成的各种外设,如GPIO, UART, TIMER等。
0x6000 0000 - 0x9FFF FFFF 外部RAM 用于扩展外部存储器(如SDRAM, SRAM)。
0xA000 0000 - 0xDFFF FFFF 外部设备 用于扩展外部设备(如FPGA、LCD控制器)。
0xE000 0000 - 0xE00F FFFF 私有外设总线 (PPB) 这是非常关键的区域,包含了Cortex-M内核本身的外设:
- NVIC (嵌套向量中断控制器)
- SCB (系统控制块)
- SysTick (系统定时器)
- MPU (内存保护单元)
这些寄存器用于系统配置、中断控制和调试。

重要特性:

  • 别名机制 (Bit-band):Cortex-M3/M4/M7等支持位带操作。它将一块特定的内存区域(SRAM和外设区)的每个位都映射到别名区的一个字(32位地址)。通过写入别名区的字,可以实现对原始位的原子性读-修改-写操作,这对于操作标志位非常高效且安全。
  • 向量表偏移:中断向量表默认从地址0x0开始,但可以通过寄存器重定位到SRAM区域(例如,为了在运行时动态更新中断服务例程)。

2. Cortex-A 系列(应用处理器)的内存映射

Cortex-A系列用于高性能应用(如手机、服务器),其内存映射更为灵活,主要由MMU(内存管理单元) 管理。

  • 物理地址空间:芯片设计时也会定义一个基础的物理内存映射,类似于一个“推荐布局”,规定DDR内存、GIC(中断控制器)、定时器等大概位于什么地址范围。
  • 虚拟地址空间:对应用程序而言,最重要的是虚拟内存映射。操作系统(如Linux)通过MMU为每个进程分配一个独立的、从0开始的4GB(32位)虚拟地址空间。MMU负责将进程使用的虚拟地址转换为实际的物理地址。
    • 用户空间:通常0x0000 0000 - 0xBFFF FFFF用于用户程序(代码、堆、栈、库)。
    • 内核空间:0xC000 0000 - 0xFFFF FFFF是内核空间,用于存放操作系统内核代码、数据和设备驱动。用户程序无法直接访问此区域,从而实现了保护。

Cortex-A的固定性体现在系统级外设的访问上,例如GIC、通用定时器等的寄存器地址是在处理器设计时就被部分固定的,或者通过特定配置寄存器告知操作系统其位置。

四、如何查看和使用?

  1. 查阅官方文档:

    • ARM公司:会提供《Cortex-Mx Technical Reference Manual (TRM)》,其中有一章专门描述通用内存映射。
    • 芯片厂商:你使用的具体芯片的《参考手册》(Reference Manual)会提供最精确、最详细的内存映射表。这是开发时必须使用的终极指南。它会明确告诉你GPIOA的寄存器从哪个地址开始,UART1的数据寄存器地址是多少。
  2. 编程中的应用:

    • 在无操作系统的嵌入式(Cortex-M)开发中,你经常会看到这样的代码:

      // 定义一个指针,直接指向GPIOA的输出数据寄存器(ODR)的地址
      #define GPIOA_ODR (*(volatile uint32_t *)(0x40020014))
      
      // 通过指针操作寄存器
      GPIOA_ODR |= 0x00000008; // 将GPIOA的第3引脚设置为高电平
      

      这里的 0x40020014 这个地址就来自于芯片内存映射表。

    • 在有操作系统的环境中(如Cortex-A跑Linux),驱动开发者同样需要将物理地址映射到进程的虚拟地址空间(通过 ioremap() 等函数),然后才能访问。

总结

特性 Cortex-M (微控制器) Cortex-A (应用处理器)
主要特点 固定映射,高度统一 灵活映射,由MMU管理
核心管理单元 MPU(可选,用于保护) MMU(必需,用于虚拟化)
编程模型 直接操作物理地址 操作系统管理虚拟地址
外设访问 地址固定,查手册即可 地址可能动态分配或重映射
目的 确定性、实时性、简单 多功能、安全性(进程隔离)、兼容性

总而言之,ARM的系统内存映射是连接软件和硬件的桥梁,它提供了一个结构化的框架,使得软件能够通过读写特定地址的方式来控制整个芯片的硬件资源。理解它是进行底层嵌入式系统开发的基础。

posted on 2025-09-13 09:57  SOC验证工程师  阅读(69)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3