platform_driver_register调用probe

platform_driver_register调用probekernel_init中do_basic_setup()->driver_init()->platform_bus_init()->…初始化platformbus(虚拟总线)设备向内核注册的时候platform_device_register()->platform_device_add()->…内核把设备挂在虚拟的platformbus下驱动注册的时候platform_dri

大家好,又见面了,我是你们的朋友全栈君。

kernel_init中do_basic_setup()->driver_init()->platform_bus_init()->…初始化platform bus(虚拟总线)
设备向内核注册的时候platform_device_register()->platform_device_add()->…内核把设备挂在虚拟的platform bus下
驱动注册的时候platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev()
对每个挂在虚拟的platform bus的设备作__driver_attach()->driver_probe_device()->drv->bus->match()==platform_match()->比较strncmp(pdev->name, drv->name, BUS_ID_SIZE),
如果相符就调用platform_drv_probe()->driver->probe(),如果probe成功则绑定该设备到该驱动.
kernel/init/main.c 

static int __init kernel_init(void * unused)
{
/*
* Wait until kthreadd is all set-up.
*/
wait_for_completion(&kthreadd_done);
/*
* init can allocate pages on any node
*/
set_mems_allowed(node_states[N_HIGH_MEMORY]);
/*
* init can run on any cpu.
*/
set_cpus_allowed_ptr(current, cpu_all_mask);

cad_pid = task_pid(current);

smp_prepare_cpus(setup_max_cpus);

do_pre_smp_initcalls();
lockup_detector_init();

smp_init();
sched_init_smp();

do_basic_setup();

/* Open the /dev/console on the rootfs, this should never fail */
if (sys_open((const char __user *) “/dev/console”, O_RDWR, 0) < 0)
printk(KERN_WARNING “Warning: unable to open an initial console.\n”);

(void) sys_dup(0);
(void) sys_dup(0);
/*
* check if there is an early userspace init.  If yes, let it do all
* the work
*/

if (!ramdisk_execute_command)
ramdisk_execute_command = “/init”;

if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
prepare_namespace();
}

/*
* Ok, we have completed the initial bootup, and
* we’re essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/

init_post();
return 0;
}


static void __init do_basic_setup(void)
{
cpuset_init_smp();
usermodehelper_init();
init_tmpfs();
driver_init();
init_irq_proc();
do_ctors();
do_initcalls();
}

kernel/drivers/base/init.c

void __init driver_init(void)
{
/* These are the core pieces */
devtmpfs_init();
devices_init();
buses_init();
classes_init();
firmware_init();
hypervisor_init();

/* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init();
system_bus_init();
cpu_dev_init();
memory_dev_init();
}

kernel/drivers/base/platform.c
注册虚拟总线
int __init platform_bus_init(void)
{
int error;

early_platform_cleanup();

error = device_register(&platform_bus);
if (error)
return error;
error =  bus_register(&platform_bus_type);
if (error)
device_unregister(&platform_bus);
return error;
}


kernel/drivers/base/platform.c

int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}


kernel/drivers/base/platform.c

int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type;
if (drv->probe)
drv->driver.probe = platform_drv_probe;
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;

return driver_register(&drv->driver);
}

kernel/drivers/base/driver.c

int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;

BUG_ON(!drv->bus->p);

if ((drv->bus->probe && drv->probe) ||
   (drv->bus->remove && drv->remove) ||
   (drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING “Driver ‘%s’ needs updating – please use ”
“bus_type methods\n”, drv->name);

other = driver_find(drv->name, drv->bus);
if (other) {
put_driver(other);
printk(KERN_ERR “Error: Driver ‘%s’ is already registered, ”
“aborting…\n”, drv->name);
return -EBUSY;
}

ret = bus_add_driver(drv);
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}

kernel/drivers/base/bus.c

int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;

bus = bus_get(drv->bus);
if (!bus)
return -EINVAL;

pr_debug(“bus: ‘%s’: add driver %s\n”, bus->name, drv->name);

priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
    “%s”, drv->name);
if (error)
goto out_unregister;

if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
module_add_driver(drv->owner, drv);

error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(KERN_ERR “%s: uevent attr (%s) failed\n”,
__func__, drv->name);
}
error = driver_add_attrs(bus, drv);
if (error) {
/* How the hell do we get out of this pickle? Give up */
printk(KERN_ERR “%s: driver_add_attrs(%s) failed\n”,
__func__, drv->name);
}

if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR “%s: add_bind_files(%s) failed\n”,
__func__, drv->name);
}
}

kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;

out_unregister:
kobject_put(&priv->kobj);
kfree(drv->p);
drv->p = NULL;
out_put_bus:
bus_put(bus);
return error;
}

kernel/drivers/base/Dd.c

int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
EXPORT_SYMBOL_GPL(driver_attach);

kernel/drivers/base/bus.c

int bus_for_each_dev(struct bus_type *bus, struct device *start,
    void *data, int (*fn)(struct device *, void *))
{
struct klist_iter i;
struct device *dev;
int error = 0;

if (!bus)
return -EINVAL;

klist_iter_init_node(&bus->p->klist_devices, &i,
    (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
return error;
}
EXPORT_SYMBOL_GPL(bus_for_each_dev);
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158267.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SMO算法最通俗易懂的解释

    SMO算法最通俗易懂的解释我的机器学习教程「美团」算法工程师带你入门机器学习已经开始更新了,欢迎大家订阅~任何关于算法、编程、AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主在线答疑~此外,公众号内还有更多AI、算法、编程和大数据知识分享,以及免费的SSR节点和学习资料。其他平台(知乎/B站)也是同名「图灵的猫」,不要迷路哦~SVM通常用对偶问题来求解,这…

    2022年6月30日
  • java 旅游管理系统

    java 旅游管理系统旅游系统设计分为前后网站和后台管理系统,功能点包含旅游景点信息分类展示、景点详情(地理位置、特色景点概述等)、下单预订、记录分享等功能。需搭建ftp服务:https://blog.csdn.net/weixin_44989660/article/details/111280276一:前端子系统功能需求分析1.游客注册登录功能模块:游客预定景点等操作需要先将账号密码进行注册,根据注册的账号密码登录到前端子系统中对功能模块进行操作。2.预定景点功能模块:游客遇到自己喜欢的景点信息后,可以通过点击预定景点按

    2022年6月11日
  • datagrip激活码_最新在线免费激活[通俗易懂]

    (datagrip激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月28日
  • Struts2学习笔记1

    Struts2学习笔记1

    2021年11月23日
  • ubuntu 安装apt_Unable to locate package vim

    ubuntu 安装apt_Unable to locate package vimubuntu通过apt命令快速安装指定版本的nginx先安装nginx依赖的第三方包sudoaptinstallcurlgnupg2ca-certificateslsb-release添加nginx官方的ubuntu的apt源echo”debhttp://nginx.org/packages/ubuntu`lsb_release-cs`nginx”\|sudotee/etc/apt/sources.list.d/nginx.list新增

    2022年9月16日
  • 【Windows】Win10家庭版启用组策略gpedit.msc

    【前言】大家都认为,Windows10家庭版中并不包含组策略,其实不然,它是有相关文件的,只是不让你使用而已。那么我们让系统允许你使用就好了。【操作步骤】1、首先你需要在桌面上新建一个txt文本文档。然后将以下代码复制到这个新建的txt文本文档中,修改其后缀.txt变成.cmd以管理员身份运行即可使用组策略gpedit.msc了

    2022年4月6日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号