QEMU aarch64 virt 平台物理内存与外设映射详解
QEMU 模拟的 ARM64 通用 virt 平台采用 ARM 统一编址架构:所有外设寄存器、启动存储、主内存都映射在同一个 64 位物理地址空间中,CPU 通过完全相同的读写指令访问内存和外设,没有独立的 IO 端口空间。
安全隔离层面:主 DRAM 的安全/非安全区域划分由 TZC-400(TrustZone 地址空间控制器) 硬件完成,外设的安全访问权限由系统保护单元控制,两者共同构成 TrustZone 的硬件隔离基础。
一、完整物理地址映射表
以下是 virt 平台标准固定的地址布局(不同 QEMU 版本微调不影响核心区域),按地址从低到高排序,标注安全相关属性:
1. 启动存储区(Flash/ROM)
|
外设/区域名称
|
起始物理地址
|
结束物理地址
|
大小
|
功能说明
|
安全属性
|
|
Flash Bank 0
|
0x0000_0000
|
0x03FF_FFFF
|
64MB
|
模拟芯片 BootROM,存放 BL1 启动固件,CPU 复位后从该地址取第一条指令
|
可配置为仅安全态可读,是安全启动链的起点
|
|
Flash Bank 1
|
0x0400_0000
|
0x07FF_FFFF
|
64MB
|
第二块可读写 Flash,用于存储启动参数、设备树等
|
默认非安全可访问
|
2. 系统核心外设区(MMIO 映射)
所有片上外设的寄存器都映射到该区域,CPU 读写对应地址就是直接操作外设寄存器。
|
外设/区域名称
|
起始物理地址
|
结束物理地址
|
大小
|
功能说明
|
安全属性
|
|
GIC Distributor(中断分发器)
|
0x0800_0000
|
0x0800_FFFF
|
64KB
|
GICv2/v3 中断控制器的分发端,管理所有中断源的路由与优先级
|
支持安全分组,安全中断仅安全世界可处理
|
|
GIC CPU Interface(CPU 接口)
|
0x0801_0000
|
0x0801_FFFF
|
64KB
|
每个 CPU 核心的中断接口,用于响应和确认中断
|
对应 CPU 安全状态访问
|
|
GIC V2M / HYP / VCPU
|
0x0802_0000
|
0x0809_FFFF
|
512KB
|
中断虚拟化、虚拟机扩展相关的寄存器组
|
虚拟化扩展使用
|
|
GIC Redistributor(重分发器)
|
0x080A_0000
|
0x08FF_FFFF
|
~14.6MB
|
GICv3 专用,每个核心对应一个重分发器
|
支持安全隔离
|
|
UART0(PL011 串口)
|
0x0900_0000
|
0x0900_0FFF
|
4KB
|
通用串口控制台,是最常用的调试输出通道
|
默认非安全可访问,可配置为安全专属串口
|
|
RTC(PL031 实时时钟)
|
0x0901_0000
|
0x0901_0FFF
|
4KB
|
实时时钟,提供系统时间基准
|
非安全可访问
|
|
fw_cfg 固件配置接口
|
0x0902_0000
|
0x0902_0FFF
|
4KB
|
QEMU 专属,用于向固件传递启动参数、内核镜像信息
|
非安全可访问
|
|
SMMUv3 系统内存管理单元
|
0x0905_0000
|
0x0906_FFFF
|
128KB
|
外设 DMA 虚拟化与地址翻译
|
支持安全上下文隔离
|
|
安全 GPIO
|
0x090B_0000
|
0x090B_0FFF
|
4KB
|
仅安全世界可访问的 GPIO 控制器,用于安全状态控制
|
仅安全态可读写
|
|
VirtIO MMIO 设备组
|
0x0A00_0000
|
0x0A00_3FFF
|
16KB
|
最多 32 个 virtio 设备(磁盘、网卡等)的 MMIO 接口,每个占 0x200 字节
|
非安全默认访问,可配置安全通道
|
|
平台总线扩展区
|
0x0C00_0000
|
0x0DFF_FFFF
|
32MB
|
平台自定义外设的预留区域
|
按需配置
|
|
低地址预留安全内存
|
0x0E00_0000
|
0x0EFF_FFFF
|
16MB
|
可选的早期安全 SRAM 区域,用于启动阶段的安全固件运行
|
仅安全世界可访问
|
3. PCIe 扩展外设区
|
外设/区域名称
|
起始物理地址
|
结束物理地址
|
大小
|
功能说明
|
|
PCIe MMIO 空间
|
0x1000_0000
|
0x3EFF_FFFF
|
~752MB
|
PCIe 设备的内存映射 IO 空间,显卡、网卡等设备的 BAR 空间映射在此
|
|
PCIe PIO 空间
|
0x3EFF_0000
|
0x3EFF_FFFF
|
64KB
|
PCIe 兼容 IO 端口空间
|
|
PCIe ECAM 配置空间
|
0x3F00_0000
|
0x3FFF_FFFF
|
16MB
|
PCIe 配置寄存器空间,用于枚举和配置 PCIe 设备
|
4. 主 DRAM 内存区
|
区域名称
|
起始物理地址
|
大小说明
|
功能说明
|
安全属性
|
|
主 DRAM 起始
|
0x4000_0000
|
由 QEMU 启动参数
-m
决定(默认 1GB 到
0x7FFF_FFFF
)
|
系统主运行内存,普通世界操作系统、用户程序都运行在此区域
|
默认非安全可访问
|
|
安全 DRAM 子区域
|
自定义(常见如
0xE100_0000
)
|
通常 16MB/32MB,由 TZC 配置划分
|
OP-TEE 操作系统、可信应用 TA、安全世界栈堆的运行区域,从主 DRAM 中单独划出
|
仅安全世界可读写
,非安全访问会被 TZC 硬件直接拦截
|
|
TZC-400 控制器寄存器
|
平台自定义(通常在系统控制 MMIO 区)
|
4KB
|
配置 DRAM 安全区域划分的控制寄存器,只有 EL3 特权级可写
|
仅 EL3 可配置,Secure EL1 只读
|
QEMU_SECURE_DRAM_BASE = 0xe1000000 就是在主 DRAM 高位划出的安全专属区域,由 ATF 在 BL2 阶段通过 TZC-400 控制器写入硬件配置生效。
二、物理地址空间布局图
按地址从低到高的纵向布局,直观展示各区域的位置关系:
物理地址
↑
高地址| 主 DRAM(高位区域) |
| ──────────────────────────────── |
| 安全 DRAM 专属区(TZC 保护) | ← OP-TEE 运行区域,仅安全可访问
| ──────────────────────────────── |
| 主 DRAM(普通区域) | ← Linux/Android 系统运行区域
0x4000_0000 ────────────────────────────
| PCIe ECAM 配置空间 |
0x3F00_0000 ────────────────────────────
| PCIe PIO / MMIO 空间 |
0x1000_0000 ────────────────────────────
| 低地址预留安全内存 |
0x0E00_0000 ────────────────────────────
| 平台总线扩展区 |
0x0C00_0000 ────────────────────────────
| VirtIO MMIO 设备组 |
0x0A00_0000 ────────────────────────────
| UART / RTC / GPIO / SMMU 等外设 |
0x0900_0000 ────────────────────────────
| GIC 中断控制器组 |
0x0800_0000 ────────────────────────────
| Flash Bank 1 |
0x0400_0000 ────────────────────────────
| Flash Bank 0(启动ROM) | ← CPU 复位入口,BL1 所在位置
低地址0x0000_0000 ───────────────────────
三、内存与外设的核心关系
1. 统一编址的工作原理
ARM 架构没有独立的 IO 地址空间,所有外设的控制寄存器、数据寄存器都被映射到物理地址空间的固定位置:
- CPU 读写 0x09000000 地址,总线会自动路由到 UART 外设的寄存器,实现串口收发;
- CPU 读写 0x40000000 地址,总线会路由到 DDR 内存控制器,实现内存读写;
- 地址解码由总线硬件自动完成,软件只需要按地址访问即可,不需要特殊的 IO 指令。
2. 安全隔离的实现方式
内存侧:TZC-400 区域化保护
- TZC-400 是 DDR 内存控制器的前端模块,所有访问主 DRAM 的请求都要经过它的权限检查;
- 它将主 DRAM 划分为最多 8 个独立区域,每个区域可以单独配置「安全世界权限」和「非安全世界权限」;
- 非安全世界发起的访问如果命中安全区域,会被硬件直接拒绝,触发总线错误,CPU 无法读取到任何有效数据。
外设侧:安全属性配置
- 每个外设都有对应的安全属性位,配置为「安全外设」后,只有安全世界的代码才能读写它的寄存器;
- 非安全世界访问安全外设会被总线拦截,触发异常;
- 典型的安全外设:安全 UART、安全 GPIO、安全 DMA 控制器,用于安全世界的调试和专用功能。
3. 与 ATF/OP-TEE 的对应关系
- ATF BL2 阶段:配置 TZC-400 寄存器,划分出安全 DRAM 区域,先锁好安全边界,再加载 OP-TEE 和 U-Boot;
- OP-TEE 运行期:内核和 TA 都运行在 TZC 保护的安全 DRAM 中,普通世界完全无法访问;
- SMC 交互:普通世界通过 SMC 指令触发安全调用,数据通过共享内存(非安全区域)传递,OP-TEE 读取后拷贝到安全内存内部处理。

683

被折叠的 条评论
为什么被折叠?



