Linux设备树的传递以及kernel中对设备树的解析
内容提要
当U-Boot加载设备树到内存后,ARM内核通过r2寄存器传递dtb地址。内核对dtb进行处理。使用bootm加载kernel镜像时,U-Boot跳转到boot_jump_linux函数。设备树传递方式与SoC架构相关。
延伸解读
设备树传递的架构依赖性
文章指出,设备树的传递方式与SoC架构密切相关。boot_jump_linux函数位于arch/arm/lib目录下,说明ARM架构下U-Boot向内核传递dtb地址的机制是架构特定的。不同SoC可能采用不同的寄存器或参数传递方式,但ARM通用寄存器r2是常见选择。这种架构依赖性意味着移植或调试时需关注具体平台的实现细节。
r2寄存器取值的两种来源
r2寄存器的值可通过bootm_header_t结构体的ft_addr成员或板级启动参数bi_boot_params获取。前者需要U-Boot支持设备树且文件非空,ft_addr和ft_len在解析镜像时实例化;后者是较古老的方式,通常由板级初始化指定。现代系统多采用前者,但了解后者有助于理解历史代码或特定平台。
内核解析设备树的两个阶段
内核解析设备树分为两个阶段:第一阶段进行校验和启动参数调整,包括crc32校验、扫描chosen和root节点、更新__machine_arch_type等;第二阶段将FDT解压为EDT,生成device_node节点。这两个阶段分工明确,第一阶段确保设备树合法并提取关键信息,第二阶段构建内核内部数据结构,为后续设备注册奠定基础。
调试设备树传递的实用方法
文章提到,确认r2是否为预期值可以通过打印方式或使用调试工具连接查看。此外,内核启动日志中会打印设备树模型名,如“OF: fdt: Machine model: V2P-CA9”,这有助于验证设备树是否被正确解析。对于开发者而言,结合日志和调试手段能快速定位设备树传递或解析中的问题。
Q&A
U-Boot如何加载设备树到内存?
U-Boot将设备树加载到内存后,ARM内核通过r2寄存器传递dtb地址。
内核如何处理设备树?
内核获取dtb地址后,进行校验和启动参数调整,随后将设备树解压为EDT,生成device_node节点。
boot_jump_linux函数的作用是什么?
boot_jump_linux函数是U-Boot与kernel之间信息衔接的关键API,负责将控制权转交给内核。
设备树的传递方式与什么相关?
设备树的传递方式与SoC架构密切相关,不同的SoC架构可能有不同的实现。
bootm_header_t结构体的作用是什么?
bootm_header_t结构体用于存储设备树的地址和长度,供内核在启动时使用。
内核对设备树的解析分为几个阶段?
内核对设备树的解析分为两个阶段:第一阶段是校验和启动参数调整,第二阶段是设备树解压。