扁平设备树内存映射声明含义及reg属性各字段意义解析
扁平设备树(FDT)内存映射声明全解析
Hey,我来把这个问题拆解清楚——扁平设备树里的memory节点,本质就是给操作系统内核递的物理内存“说明书”,内核启动时全靠它搞清楚系统里的内存资源分布。先讲基础逻辑,再对着你的示例逐条解析。
一、内存映射声明的核心意义
每个memory节点必须带两个关键属性:
device_type = "memory":给内核拍板——“我这节点描述的是正经物理内存,别搞混了”reg:实打实的内存坐标和尺寸,格式取决于系统的地址宽度(32位/64位),你的示例用的是64位地址的表示方式,所以reg是4个32位数值的组合。
二、你的示例中reg属性的具体含义
先把你的两个内存节点贴出来方便对照:
memory@40000000 { device_type = "memory"; reg = <0 0x40000000 0 0x20000000>; }; memory@200000000 { device_type = "memory"; reg = <2 0x00000000 0 0x20000000>; };
这里的reg遵循64位地址的拆分规则:把64位的起始物理地址拆成「高32位 + 低32位」,64位的内存大小拆成「高32位 + 低32位」,也就是格式为 <addr_high addr_low size_high size_low>。
第一个节点:memory@40000000
reg = <0 0x40000000 0 0x20000000>
逐个数值解释:
- 第一个
0:起始地址的高32位,这里是0,说明起始地址没超过32位 - 第二个
0x40000000:起始地址的低32位,拼接后完整起始地址是(0 << 32) | 0x40000000 = 0x40000000(对应1GB的物理位置) - 第三个
0:内存大小的高32位,0表示大小也没超过32位 - 第四个
0x20000000:内存大小的低32位,拼接后大小是(0 << 32) | 0x20000000 = 0x20000000(对应512MB)
总结:这是一块从0x40000000开始的512MB物理内存。
第二个节点:memory@200000000
reg = <2 0x00000000 0 0x20000000>
同样拆解:
- 第一个
2:起始地址的高32位,计算下来是2 << 32 = 0x800000000 - 第二个
0x00000000:起始地址的低32位,拼接后完整起始地址是(2 << 32) | 0x00000000 = 0x800000000(对应32GB的物理位置) - 第三个
0:内存大小的高32位,无额外值 - 第四个
0x20000000:内存大小的低32位,还是512MB
总结:这是一块从0x800000000开始的512MB物理内存。
额外小贴士
为什么要拆成4个数值?因为有些64位嵌入式平台的物理地址超过了32位(比如你的第二个节点就用到了33位地址),单靠一个32位数值装不下完整地址,所以FDT用两个32位数值拼接成64位的地址/大小。如果是32位系统,reg一般只需要两个数值:<address size>,不用拆高低位。
内容的提问来源于stack exchange,提问作者Thảo M. HoàNg




