设备树(DTS)手动编写中的内存映射核心问题咨询
手动创建设备树(DTS)RAM配置问题解答
背景信息
我正从零开始手动创建设备树(DTS),通过设备的/proc目录获取硬件信息,当前重点配置memory节点(RAM相关)。已知内核代码起始地址为0x40080000,对应的/proc/iomem内容如下:
# /proc/iomem 40000000-4cdfffff : System RAM 40080000-4154ffff : Kernel code 41550000-4167ffff : reserved 41680000-4209cfff : Kernel data
外设硬件的RAM地址分布对应的/proc/iomem内容:
# /proc/iomem 00110b80-00110bff : dvfsrc@10012000 10212000-1021207f : cq_dma@10212000 10228000-10229fff : dramc@1022a000 11000080-110000ff : i2c0@11007000 11200000-1120ffff : usb0@11200000 11220000-11220fff : mt6768-afe-pcm@11220000 11230000-1123ffff : mmc@11230000 11cd0000-11cd0fff : mmc@11230000 4d010000-4d010fff : persistent_ram 4d100000-755dffff : System RAM 6e000000-6f61ffff : reserved 140000000-23fff5fff : System RAM
我编写的示例DTS片段:
{ model = "mediatek,MT6769H"; compatible = <&model>, "mediatek,MT6768"; interrupt-parent = <0x1>; #address-cells = <2>; // 用于格式化reg输入 #size-cells = <2>; // 用于格式化reg输入 serial-number = ""; chasis-type = "handset"; cpus { }; // Physical RAM ram memory { device_type = "memory"; reg = <0x0 0x0 0x23fff5fff 0x0>; // 我认为第一个0x0是RAM起始地址,0x23fff5fff是物理RAM总容量 }; // Peripheral memory mapping reserved-memory { mmmc_reserved: mmc@11230000 { #address-cells = <1>; #size-cells = <1>; compatible = "manufacturer,model"; reg = <0x11230000 0xFFFF>; }; }; mmc: mmc@11230000 { memory-region = <&mmc_reserved>; }; };
问题解答
1. 内核基地址应设置为0x0还是0x40000000?
要区分两个核心概念:
- 物理RAM的起始地址:从
/proc/iomem的System RAM条目可知,第一段物理内存的起始是0x40000000,这是需要写入memory节点reg属性的物理内存起始地址。 - 内核代码的起始地址:
0x40080000是内核代码加载到物理RAM中的具体位置,属于0x40000000-0x4cdfffff这个RAM区间的一部分,不需要作为memory节点的起始地址。
因此,memory节点中物理RAM的起始地址应写0x40000000,而非0x0(你的/proc/iomem中0x0起始的区间没有标记为System RAM,不能作为RAM起始)。
2. 是否必须在memory节点中记录物理RAM的总容量?
不能直接写总容量,memory节点的reg属性必须准确列出所有物理RAM的连续地址区间——内核需要通过这些区间识别哪些地址是可用的物理内存。
从你的/proc/iomem来看,物理RAM分为三个不连续的区间,对应转换为DTS的reg条目(根节点#address-cells = <2>、#size-cells = <2>,每个区间用[高地址 低地址 长度高地址 长度低地址]表示):
memory { device_type = "memory"; reg = <0x0 0x40000000 0x0 0xcd00000>, <0x0 0x4d100000 0x0 0x284e0000>, <0x1 0x40000000 0x0 0xffff6000>; // 0x140000000是64位地址,高32位为0x1,低32位为0x40000000 };
只有准确列出所有RAM区间,内核才能正确识别和使用全部物理内存。
3. 当外设存在两个内存地址条目时,该如何处理?
对于像mmc这样占用两个不连续内存区域的外设,需要在对应的设备节点和reserved-memory节点中分别添加两个reg条目:
步骤1:修改reserved-memory中的mmc预留节点
reserved-memory { mmmc_reserved: mmc@11230000 { #address-cells = <1>; #size-cells = <1>; compatible = "mediatek,mmc-reserved"; // 替换为实际兼容属性 reg = <0x11230000 0x10000>, // 对应11230000-1123ffff,长度0x10000 <0x11cd0000 0x1000>; // 对应11cd0000-11cd0fff,长度0x1000 }; };
步骤2:修改mmc设备节点的reg属性
mmc: mmc@11230000 { reg = <0x0 0x11230000 0x0 0x10000>, <0x0 0x11cd0000 0x0 0x1000>; memory-region = <&mmc_reserved>; // 其他属性... };
通过这种方式,内核就能识别该外设的所有内存映射区域,同时预留对应的内存空间避免被其他模块占用。
内容的提问来源于stack exchange,提问作者Bret Joseph
相关产品推荐
相关产品推荐

