U-Boot驱动定义和查找

环境

U-Boot版本:官方2023.04
开发板:ZYNQ 7000 ZC702Kit Rev1.1

注册代码宏定义

/* Declare a new uclass_driver */
#define UCLASS_DRIVER(__name)						\
	ll_entry_declare(struct uclass_driver, __name, uclass_driver)


/**
 * U_BOOT_DRIVER() - Declare a new U-Boot driver
 * @__name: name of the driver
 */
#define U_BOOT_DRIVER(__name)						\
	ll_entry_declare(struct driver, __name, driver)


/**
 * ll_entry_declare() - Declare linker-generated array entry
 * @_type:	Data type of the entry
 * @_name:	Name of the entry
 * @_list:	name of the list. Should contain only characters allowed
 *		in a C variable name!
 */
#define ll_entry_declare(_type, _name, _list)				\
	_type _u_boot_list_2_##_list##_2_##_name __aligned(4)		\
			__attribute__((unused))				\
			__section("__u_boot_list_2_"#_list"_2_"#_name)

ll_entry_declare 宏定义是创建一个类型为 _type 的结构体,并且存放到 _u_boot_list_2#list_2#_name 程序段。
_list 作为分类字段,保证 driver 类型连续在一起,_name作为结构体名称。
编译后 map 文件可以看到

__u_boot_list_2_uclass_driver_2_root
                0x040e29f4       0x48 drivers/core/root.o
                0x040e29f4                _u_boot_list_2_uclass_driver_2_root
 __u_boot_list_2_uclass_driver_2_serial
                0x040e2a3c       0x48 drivers/serial/serial-uclass.o
...
 __u_boot_list_2_driver_2_root_driver
                0x040e1ed4       0x44 drivers/core/root.o
                0x040e1ed4                _u_boot_list_2_driver_2_root_driver
 __u_boot_list_2_driver_2_serial_dcc
                0x040e1f18       0x44 drivers/serial/arm_dcc.o
                0x040e1f18                _u_boot_list_2_driver_2_serial_dcc
 __u_boot_list_2_driver_2_serial_zynq
                0x040e1f5c       0x44 drivers/serial/serial_zynq.o
                0x040e1f5c                _u_boot_list_2_driver_2_serial_zynq
 __u_boot_list_2_driver_2_simple_bus
                0x040e1fa0       0x44 drivers/core/simple-bus.o
                0x040e1fa0                _u_boot_list_2_driver_2_simple_bus
...

设备查找

  • 列表定位
#define ll_entry_start(_type, _list)					\
({									\
	static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN)	\
		__attribute__((unused))					\
		__section("__u_boot_list_2_"#_list"_1");			\
	(_type *)&start;						\
})

#define ll_entry_end(_type, _list)					\
({									\
	static char end[0] __aligned(4) __attribute__((unused))		\
		__section("__u_boot_list_2_"#_list"_3");			\
	(_type *)&end;							\
})

设备注册时 _list 和 _name 之间加入序列 2 作为标识,每一类最前面插入一个序列为 1 并且不带 _name 的对象,最后面插入一个序列为 3 并且不带 _name 的对象。通过起始和结束的特殊对象查找一个段的地址范围。

设备数量统计

#define ll_entry_count(_type, _list)					\
	({								\
		_type *start = ll_entry_start(_type, _list);		\
		_type *end = ll_entry_end(_type, _list);		\
		unsigned int _ll_result = end - start;			\
		_ll_result;						\
	})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怦然心动如往昔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值