目录
16.3.1 设备树在TF-A中的作用
设备树(Device Tree)是ARM体系架构中描述硬件配置的标准机制,在TF-A中扮演以下关键角色:
- 硬件抽象:提供与平台无关的硬件描述,减少平台特定代码
- 启动配置:传递内存布局、外设信息等关键启动参数
- 运行时服务:为PSCI、安全监控等提供硬件拓扑信息
- 多平台支持:同一份BLx固件可支持不同硬件变种
TF-A的设备树支持特点:
- 采用Flattened Device Tree(FDT)格式
- 支持动态修改和运行时解析
- 与Linux设备树保持兼容性
16.3.2 TF-A设备树处理流程
设备树来源
典型处理阶段:
- BL1阶段:可选加载基础设备树(通常由ROM代码提供)
- BL2阶段:
- 验证设备树完整性
- 添加/修改安全相关节点(如TZC配置)
- BL31阶段:
- 解析PSCI、GIC等关键节点
- 准备传递给非安全世界的设备树
- BL32/BL33:接收最终处理后的设备树
关键处理函数
// 典型设备树操作API
void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp);
int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible);
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len);
16.3.3 平台移植中的设备树配置
基础设备树配置
/ {
compatible = "arm,my-platform";
#address-cells = <2>;
#size-cells = <2>;
memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0 0x80000000>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
tf-a@0x80000000 {
reg = <0x0 0x80000000 0x0 0x200000>;
no-map;
};
};
};
安全扩展节点示例
/ {
firmware {
tf-a {
compatible = "arm,tf-a";
memory-region = <&tf_a_reserved>;
};
};
psci {
compatible = "arm,psci-1.0";
method = "smc";
cpu_suspend = <0xc4000001>;
cpu_off = <0x84000002>;
cpu_on = <0xc4000003>;
};
};
16.3.4 安全相关的设备树处理
典型安全配置项
-
内存区域保护:
tzc380: tzc@3ff00000 { compatible = "arm,tzc380"; reg = <0x0 0x3ff00000 0x0 0x1000>; ranges = <0x0 0x0 0x3ff00000 0x1000>; #address-cells = <1>; #size-cells = <1>; filters { filter@0 { region = <0>; start = <0x80000000>; end = <0x8fffffff>; sec-config = <0x11>; }; }; };
-
可信执行环境配置:
optee { compatible = "linaro,optee-tz"; method = "smc"; interrupt-parent = <&gic>; interrupts = <0 15 4>; };
设备树修改最佳实践
- 使用
fdt_del_node()
移除不安全节点 - 通过
fdt_setprop()
添加安全属性 - 保留原始设备树的备份副本
- 验证所有修改后的内存区域权限
16.3.5 调试与验证
常用调试方法
-
设备树dump工具:
fdtdump bl2.dtb
-
TF-A日志输出:
NOTICE("Found DT at %p, size %zu\n", fdt, fdt_totalsize(fdt));
-
运行时检查:
if (fdt_check_header(fdt) != 0) { ERROR("Invalid device tree header\n"); panic(); }
常见问题排查
问题现象 | 可能原因 | 解决方案 |
---|---|---|
设备树加载失败 | 地址/大小不匹配 | 检查BL2加载参数 |
属性读取异常 | 节点路径错误 | 使用fdtdump 验证结构 |
内存冲突 | 保留内存区域重叠 | 检查reserved-memory 节点 |
SMC调用失败 | PSCI配置错误 | 验证psci 节点兼容性 |
16.3.6 高级主题
动态设备树修改
int modify_cpu_nodes(void *fdt)
{
int offset, ret;
offset = fdt_path_offset(fdt, "/cpus");
if (offset < 0)
return -1;
ret = fdt_setprop_string(fdt, offset, "secure-status", "okay");
if (ret < 0)
return -1;
return 0;
}
多级设备树处理
注意:TF-A 2.6+版本引入了动态设备树(DT overlay)支持,允许运行时合并多个设备树片段。
16.3.7 平台移植检查清单
- 确认设备树源文件位置(通常位于
fdts/
目录) - 验证基础内存节点正确性
- 检查所有安全外设的配置状态
- 实现必要的设备树修改hook函数
- 测试非安全世界接收的设备树完整性
- 确保保留内存区域无冲突