uboot的驱动模型理解
UCLASS_DRIVER(spi) = {
.id = UCLASS_SPI,
.name = "spi",
.flags = DM_UC_FLAG_SEQ_ALIAS,
.post_bind = spi_post_bind,
.post_probe = spi_post_probe,
.child_pre_probe = spi_child_pre_probe,
.per_device_auto_alloc_size = sizeof(struct dm_spi_bus),
.per_child_auto_alloc_size = sizeof(struct spi_slave),
.per_child_platdata_auto_alloc_size =
sizeof(struct dm_spi_slave_platdata),
.child_post_bind = spi_child_post_bind,
};
/* Declare a new uclass_driver */
#define UCLASS_DRIVER(__name) \
ll_entry_declare(struct uclass_driver, __name, uclass) #define ll_entry_declare(_type, _name, _list) \
_type _u_boot_list_2_##_list##_2_##_name __aligned() \
__attribute__((unused, \
section(".u_boot_list_2_"#_list"_2_"#_name)))
struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
{
// 会根据.u_boot_list_2_uclass_1的段地址来得到uclass_driver table的地址
struct uclass_driver *uclass =
ll_entry_start(struct uclass_driver, uclass); // 获得uclass_driver table的长度
const int n_ents = ll_entry_count(struct uclass_driver, uclass);
struct uclass_driver *entry; for (entry = uclass; entry != uclass + n_ents; entry++) {
if (entry->id == id)
return entry;
} return NULL;
}
/* Declare a new U-Boot driver */
#define U_BOOT_DRIVER(__name) \
ll_entry_declare(struct driver, __name, driver) #define ll_entry_declare(_type, _name, _list) \
_type _u_boot_list_2_##_list##_2_##_name __aligned() \
__attribute__((unused, \
section(".u_boot_list_2_"#_list"_2_"#_name))) U_BOOT_DRIVER(tegra114_spi) = {
.name = "tegra114_spi",
.id = UCLASS_SPI,
.of_match = tegra114_spi_ids,
.ops = &tegra114_spi_ops,
.ofdata_to_platdata = tegra114_spi_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
.priv_auto_alloc_size = sizeof(struct tegra114_spi_priv),
.probe = tegra114_spi_probe,
};
ll_entry_declare(struct driver, tegra114_spi, driver) struct driver _u_boot_list_2_driver_2_tegra114_spi
__aligned() \
__attribute__((unused, \
section(".u_boot_list_2_driver_2_tegra114_spi")))
static int initf_dm(void)
{
#if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN)
int ret; ret = dm_init_and_scan(true);
if (ret)
return ret;
#endif
#ifdef CONFIG_TIMER_EARLY
ret = dm_timer_init();
if (ret)
return ret;
#endif return ;
}
int dm_init_and_scan(bool pre_reloc_only)
{
int ret; /*创建udevice和uclass空链表,创建根设备(root device)*/
ret = dm_init();
if (ret) {
debug("dm_init() failed: %d\n", ret);
return ret;
}
/*扫描U_BOOT_DEVICE定义的设备,与U_BOOT_DRIVER定义的driver进行查找,并绑定相应driver*/
ret = dm_scan_platdata(pre_reloc_only);
if (ret) {
debug("dm_scan_platdata() failed: %d\n", ret);
return ret;
} if (CONFIG_IS_ENABLED(OF_CONTROL)) {
/*扫描由FDT设备树文件定义的设备,与U_BOOT_DRIVER定义的driver进行查找,并绑定相应driver*/
ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
if (ret) {
debug("dm_scan_fdt() failed: %d\n", ret);
return ret;
}
}
ret = dm_scan_other(pre_reloc_only);
if (ret)
return ret; return ;
}
int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
{
/*从分段,.u_boot_list_2_driver_info中来查找*/
struct driver_info *info =
ll_entry_start(struct driver_info, driver_info); const int n_ents = ll_entry_count(struct driver_info, driver_info);
struct driver_info *entry;
struct udevice *dev;
int result = ;
int ret; for (entry = info; entry != info + n_ents; entry++) {
/*将driver_info列表里面的name,依次与driver列表里面的名字,进行匹配查找,然后进行绑定*/
ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev);
if (ret && ret != -EPERM) {
dm_warn("No match for driver '%s'\n", entry->name);
if (!result || ret != -ENOENT)
result = ret;
}
} return result;
} int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
const struct driver_info *info, struct udevice **devp)
{
struct driver *drv; /*从driver list中查找info的名字*/
drv = lists_driver_lookup_name(info->name);
if (!drv)
return -ENOENT;
if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
return -EPERM; /*创建udevice,绑定*/
return device_bind(parent, drv, info->name, (void *)info->platdata,
-, devp);
}
#define U_BOOT_DEVICE(__name) \
ll_entry_declare(struct driver_info, __name, driver_info)
uboot的驱动模型理解的更多相关文章
- u-boot器件驱动模型(Device&Drivers)之uclass (转)
一.剧情回顾 在上一篇链接器的秘密里面我们讲到我们用一些特殊的宏让链接器帮我们把一些初始化好的结构体列好队并安排在程序的某一个段里面,这里我例举出了三个和我们主题相关段的分布情况,它们大概如下图所示: ...
- uboot 网络驱动模型
原文:https://blog.csdn.net/zhouxinlin2009/article/details/45390065 UBOOT的PHYCHIP配置 PHYCHIP的配置位于 includ ...
- [uboot] (番外篇)uboot 驱动模型(转)重要
[uboot] uboot流程系列:[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)[project X] tiny210(s5pv210)从存储设备加载代码到D ...
- u-boot下的DM驱动模型 阶梯状 (转)
U-boot 下DM驱动模型的相关笔记要注意的关键两点: DM驱动模型的一般流程bind->ofdata_to_platdata(可选)->probe 启动,bind操作时单独完成的 ...
- usb驱动开发4之总线设备驱动模型
在上文说usb_init函数,却给我们留下了很多岔路口.这次就来好好聊聊关于总线设备驱动模型.这节只讲理论,不讲其中的函数方法,关于函数方法使用参考其他资料. 总线.设备.驱动对应内核结构体分别为bu ...
- linux驱动模型<输入子系统>
在linux中提供一种输入子系统的驱动模型,其主要是实现在input.c中. 在输入子系统这套模型中,他把驱动分层分类.首先分为上下两层,上层为input.c .下层为驱动的实现,下层分为两部分,一部 ...
- linux RTC 驱动模型分析【转】
转自:http://blog.csdn.net/yaozhenguo2006/article/details/6824970 RTC(real time clock)实时时钟,主要作用是给Linux系 ...
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
转载自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sy ...
- linux内核驱动模型
linux内核驱动模型,以2.6.32内核为例.(一边写一边看的,有点乱.) 1.以内核对象为基础.用kobject表示,相当于其它对象的基类,是构建linux驱动模型的关键.具有相同类型的内核对象构 ...
随机推荐
- 并发库应用之九 & 到时计数器CountDownLatch应用
申明:CountDownLatch好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行. java.util.concurre ...
- CAPTCHA---验证码 ---Security code
BotDetect Java CAPTCHA Generator 3. Add BotDetect Java CAPTCHA Library Dependency Here is how to add ...
- jQuery学习之旅 Item5 $与jQuery对象
1.$符号的由来 $符号本质就是函数的名字. jquery源码分析 通过分析我们知道,在jquery里边不只可以使用$符号,还可以使用jQuery标志 解决冲突问题 有的项目是中间过渡项目(proto ...
- javascript 事件编程之事件(流,处理,对象,类型)
1. 事件处理 1.1. 绑定事件方式 1)行内绑定 语法: //最常用的使用方式 <元素 事件="事件处理程序"> 2)动态绑定 //结构+样式+行为分离的页面(ht ...
- 译MassTransit 快速入门
给我看代码! 下面是MassTransit的功能设置. public class YourMessage { public string Text { get; set; } } public cla ...
- [Linux]Linux 下的 Docker 安装与使用
一.安装与配置 1.设置阿里云镜像源 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/cen ...
- Python常用算法(二)
1.快速排序 过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小 一般选取第一个数作为关键数据k,我们要把比k小的所有数据移到它的左面,从后往前找第一个比它 ...
- ArcGIS API for JavaScript 入门教程[3] 你看得到:数据与视图分离
这篇开始正式讲API. 数据和视图分离不是什么奇怪的事情了,这是一个著名的设计--数据与视图分开. 转载注明出处,博客园/CSDN/B站:秋意正寒. 目录:https://www.cnblogs.co ...
- java 日期类 小结
import java.text.*; import java.util.*; class Test2 { public static void main(String[] args) { Syste ...
- mvc 三个 之间 肮脏的交易
就当个小零食一样写. MVC 是 Model-View-Controller 的缩写,Model代表的是应用的业务逻辑(通过 JavaBean,EJB 组件实现),View 是应用的表示层(由 JSP ...