Uboot的DM驱动模型
https://blog.csdn.net/ooonebook/article/details/53234020
这个文章写的非常的好,是学习uboot的首选之一,还有正点原子的系统移植教程中也有非常详细的uboot的分析。
Uboot从设备树的reg属性获取地址
首先是非常熟悉Start.S,在这里会掉用board_init_f、board_init_r两个函数对系统做初始化。这两个初始化里面都有初始化驱动模型initf_dm、initr_dm。
只不过一个是 dm_init_and_scan(true)、一个是dm_init_and_scan(false)重点是看board_init_r中的初始化dm_init_and_scan(false)。
在dm_init_and_scan(false)中主要有两点:一个是初始化驱动模型的根节点,另一个就是扫描设备书创建udevice、uclass绑定、申请空间等。
但是这里的dm_extended_scan_fdt并没有扫描reg。那它具体做了什么。dm_extended_scan_fdt->dm_scan_fdt->dm_scan_fdt_node->lists_bind_fdt->device_bind_with_driver_data->device_bind_common。
具体在device_bind_common中可以看见。主要是创建uclass创建udevice和绑定driver等。
那reg的属性是在那里获取的?获取到什么地方?
首先平台的设备信息会保存到udevice的paltdata的指针下,在device_bind_common中会申请platdata的内存(根据driver下的platdata_auto_alloc_size)。
以最简单的GPIO为例,在driver的ofdata_to_platdata函数下去匹配到gpio驱动的设备结构体XXXX_gpio_platdata。
在初始化gpio driver的时候.挂载ofdata_to_platdata = of_match_ptr(XXXX_gpio_ofdata_to_platdata),
然后在 devfdt_get_addr(dev)获取gpio设备书节点下的reg中的地址。
是在device_probe中会调用上面的函数,到此就获取设备树中的reg属性结束。
所以在初始化设备的时候一定使用device_probe初始化设备。自定调用driver的probe可能会有部分指针没有初始化的问题。