在设备树(Device Tree, DT)中定义保留内存(Reserved Memory),通常用于为特定硬件设备、内核功能(如 CMA)或驱动预留一段物理内存,使其不被内核动态分配。以下是具体的方法和示例:
一、设备树中定义保留内存的步骤 1. 在根节点下添加 reserved-memory 节点在设备树的根节点( / )下创建一个名为 reserved-memory 的子节点,用于管理所有保留内存区域。该节点需包含 #address-cells 和 #size-cells 属性,以指定地址和大小的表示方式(通常与系统地址空间的格式一致)。2. 定义具体的保留内存区域在 reserved-memory 节点下添加子节点,每个子节点描述一个保留内存区域。每个子节点需包含以下属性: - reg :指定物理地址和大小,格式为 [address] [size] 。- no-map (可选):若设置该属性,内核将不会自动将此内存映射到虚拟地址空间,需手动通过 ioremap 等函数映射。3. (可选)将保留内存关联到设备若保留内存供特定设备使用,可在设备节点中通过 memory-region 或类似属性引用保留内存区域。 二、示例设备树片段 /dts-v1/;#include <dt-bindings/reserved-memory/reserved-memory.h>/ { reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; /* 保留内存区域 1:供设备 A 使用,不自动映射 / reserved_mem1: reserved-mem@10000000 { reg = <0x10000000 0x1000000>; / 物理地址 0x10000000,大小 16MB / no-map; linux,用途 = “device_a”; }; / 保留内存区域 2:供 CMA 使用,自动映射 / cma_mem: cma@20000000 { reg = <0x20000000 0x2000000>; / 物理地址 0x20000000,大小 32MB / linux,cma-default; }; }; / 设备 A 的节点,引用保留内存 */ device_a { compatible = “vendor,device-a”; memory-region = <&reserved_mem1>; };}; 三、关键属性说明 1. #address-cells 和 #size-cells - 用于定义子节点中 reg 属性的地址和大小的字节数。例如, #address-cells = <1> 表示地址占 1 个单元格(通常为 32 位), #size-cells = <1> 表示大小占 1 个单元格。2. reg 属性 - 格式为 reg = <address1 size1 address2 size2 …> ,用于描述物理地址范围。每个保留内存区域至少需要一个 reg 条目。3. no-map 属性 - 若设置该属性,内核不会自动将此内存映射到虚拟地址空间。若需访问该内存,驱动需手动通过 ioremap 映射。4. linux,cma-default - 标记该保留内存为 CMA(Contiguous Memory Allocator)区域,供内核动态分配大页内存。5. memory-region - 在设备节点中使用此属性引用保留内存区域,建立设备与保留内存的关联。 四、注意事项 1. 物理地址有效性 - 保留内存的物理地址必须是系统中实际存在的,且未被其他设备或内存区域占用。2. 对齐要求 - 保留内存的大小需满足硬件或内核的对齐要求(如 4KB 对齐),否则可能导致映射失败。3. 内核版本兼容性 - 不同 Linux 内核版本对设备树保留内存的支持可能略有差异,建议参考内核文档(如 Documentation/devicetree/bindings/reserved-memory/)。4. 映射与访问 - 未设置 no-map 的保留内存会被内核自动映射,但需通过内核提供的接口(如 devm_ioremap_resource )获取虚拟地址,避免直接操作物理地址。 通过以上方法,可在设备树中清晰定义保留内存,并实现与硬件设备或内核功能的集成。
01-14
279

01-10
1826

09-01
1057

03-28
1万+

03-18