真实面经题目 · 原创解析
设备树中配置 64 位地址空间时,reg 里的四个数字分别表示什么?
这题考设备树地址编码规则,回答要强调 reg 由父节点的 address-cells 和 size-cells 决定,四个数字通常是 64 位地址高低和 64 位长度高低。
真实面经题目 · 原创解析
这题考设备树地址编码规则,回答要强调 reg 由父节点的 address-cells 和 size-cells 决定,四个数字通常是 64 位地址高低和 64 位长度高低。
设备树里的 reg 不是固定几个数字,而是由父节点的 #address-cells 和 #size-cells 决定每个资源条目占多少个 32 位 cell。所谓 64 位地址空间里看到四个数字,常见是父节点 #address-cells = 2、#size-cells = 2,所以一个 reg entry 由 2 个 cell 表示地址、2 个 cell 表示长度:第一个是地址高 32 位,第二个是地址低 32 位,第三个是 size 高 32 位,第四个是 size 低 32 位。每个 cell 是 32 位 big-endian 编码。驱动一般不手工解析这四个数,而是用 platform_get_resource、of_address_to_resource 等接口获得 resource,再 ioremap。还要注意 ranges 会做父子地址转换,多个资源会连续写多组 cell。
设备树把整数属性编码成一个个 32 位 cell。地址和长度要用几个 cell,不由当前节点自己决定,而由父 bus 节点的 #address-cells 和 #size-cells 决定。
当父节点要求 2 个地址 cell 和 2 个 size cell 时,一个资源就是 addr_hi、addr_lo、size_hi、size_lo。它表达的是 64 位起始地址和 64 位资源大小。
子总线里的地址可能不是 CPU 物理地址,需要通过 ranges 属性转换到父总线地址空间。驱动使用内核接口可以自动处理很多这类转换。
如果设备有多个寄存器区域,reg 会连续放多组 address+size。解析时必须按父节点 cell 数成组读取,不能按固定四个数硬切。
那一个资源的长度只占 1 个 32 位 cell;例如 address-cells 为 2、size-cells 为 1 时,一个 reg entry 就是 3 个数字。
不同总线 cell 数和 ranges 规则不同,硬解析容易错;内核 resource 接口能按设备树规则处理地址和长度。
我会先看 dmesg 和返回码,再查 /sys 下设备、驱动和资源状态,必要时加 trace/ftrace 或最小日志,先证明问题出在设备生成、匹配、资源获取、回调路径还是用户态交互。