文章目录
- 1、U_BOOT_DRIVER
- 2、DM框架
- dm_scan_platdata
- dm_extended_scan_fdt
1、U_BOOT_DRIVER
使用这个宏可以定义一个驱动实例,宏定义是
其中使用的struct driver结构体
使用的ll_entry_declare宏定义是
归结为
2、DM框架
1、 DM框架
DM模型抽象出了以下四个概念/数据结构
其中uclass是
使用UCLASS_DRIVER定义一个uclass driver,uclass_driver是uclass的驱动,并不是具体硬件的土洞,做一些uclass通用的准备/回收工作。
udevice 是具体的硬件实例,dts中配置了两个硬件node,会有两个udevice,例如dts中配置了两个timer,就会有两个timer udevice,uboot会将udevice和它所属的uclass以及具体的驱动driver绑定起来。
driver 是具体硬件的驱动,对应每个硬件的驱动实现。使用U_BOOT_DRIVER定义一个驱动实例。
模型的全局数据结构
在 driver/core/root.h 和 root.c 文件中有 dm_init_and_scan 函数,进行dm框架的 init和设备树扫描。
dm_init 过程中使用的宏定义
Uboot有两种方式描述设备:①平台数据;②设备树方式。这店与Linux内核也一致。在dm_scan_platdata中,会扫描所有的平台数据并绑定驱动程序,将扫描所有可用的平台数据为每个数据创建驱动程序。
dm_scan_platdata
使用的lists_bind_drivers 函数,会搜索并将所有驱动程序绑定到父驱动程序,在文件drivers/core/lists.c中,传入的DM_ROOT_NON_CONST宏是dm_root,udevice设备的跟节点,作为parents:
通过ll_entry_start 方式获取内存中某个section的数据,
此处是获取section(“.u_boot_list_2_driver_info_1”),在for循环中,获取到section的start位置,通过ll_entry_count 计算section中的数量,在循环中逐个识别,并bind。
section(“.u_boot_list_2_driver_info_1”)
Struct driver_info 是 实例化设备所需的信息。通过map文件查看到driver_info声明不多,大多数通过设备树更新。
device_bind_by_name函数在drivers/core/device.c 文件中,parent变量是dm_root,global变量的root变量,info是当前section的driver_info。
在lists_driver_lookup_name 函数中,根据name从driver段中查找
section(“.u_boot_list_2_driver_1”)
根据u-boot.map文件可以查看到
全部的段,由1开始,3结束,中间的记录都是 .u_boot_list_2_xxx_2_xxx 的格式。
dm_extended_scan_fdt
dm_scan_fdt函数分析
这个函数是如果u-boot配置了支持设备树绑定设备驱动,那么将会执行该函数。dm_scan_fdt函数用于扫描设备树,绑定驱动程序。这将扫描设备树并为每个节点创建一个驱动程序(只检查顶级子节点)。
和kernel的方法相似,通过match 属性compatible进行配对