• 【打卡】【sysfs相关API详解】21天学习挑战赛—RK3399平台开发入门到精通-Day20



    活动地址:CSDN21天学习挑战赛

    学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
    想系统/深入学习某技术知识点…
    一个人摸索学习很难坚持,想组团高效学习…
    想写博客但无从下手,急需写作干货注入能量…
    热爱写作,愿意让自己成为更好的人…

    在Linux概念中,bus下还细化很多,比如不仅仅真正的物理总线归类为bus,还有常用的platform虚拟总线,接下来看看详细的platform总线的相关platform_bus_init:
    kernel/drivers/base/platform.c

    struct bus_type platform_bus_type = {
        .name       = "platform",  // 总线类型名称
        .dev_groups = platform_dev_groups, //总线设备组,包括设备属性
        .match      = platform_match, //总线匹配函数
        .uevent     = platform_uevent, //热拔插操作函数
        .pm     = &platform_dev_pm_ops, //电源管理,休眠唤醒操作集
    };
    EXPORT_SYMBOL_GPL(platform_bus_type);
    
    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); // 注册platform_bus_type总线到内核
        if (error)
            device_unregister(&platform_bus);
        of_platform_register_reconfig_notifier();
        return error;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    尽管上面的bus
    因为device和driver都是挂载在bus上的,为层次结构清晰,接下来按照顺序看看详细的bus_register、device_register和bus_register的实现机制:

    bus_register

    kernel/drivers/base/bus.c

    /**
     * bus_register - register a driver-core subsystem
     * @bus: bus to register
     *
     * Once we have that, we register the bus with the kobject
     * infrastructure, then register the children subsystems it has:
     * the devices and drivers that belong to the subsystem.
     */
    int bus_register(struct bus_type *bus)
    {
        int retval;
        struct subsys_private *priv;
        struct lock_class_key *key = &bus->lock_key;
    
        priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);
        if (!priv)
            return -ENOMEM;
    
        priv->bus = bus;
        bus->p = priv;
    
        BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
    
        retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
        if (retval)
            goto out;
    
        priv->subsys.kobj.kset = bus_kset;
        priv->subsys.kobj.ktype = &bus_ktype;
        priv->drivers_autoprobe = 1;
    
        retval = kset_register(&priv->subsys);
        if (retval)
            goto out;
    
        retval = bus_create_file(bus, &bus_attr_uevent);
        if (retval)
            goto bus_uevent_fail;
    
        priv->devices_kset = kset_create_and_add("devices", NULL,
                             &priv->subsys.kobj);
        if (!priv->devices_kset) {
            retval = -ENOMEM;
            goto bus_devices_fail;
        }
    
        priv->drivers_kset = kset_create_and_add("drivers", NULL,
                             &priv->subsys.kobj);
        if (!priv->drivers_kset) {
            retval = -ENOMEM;
            goto bus_drivers_fail;
        }
    
        INIT_LIST_HEAD(&priv->interfaces);
        __mutex_init(&priv->mutex, "subsys mutex", key);
        klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
        klist_init(&priv->klist_drivers, NULL, NULL);
    
        retval = add_probe_files(bus);
        if (retval)
            goto bus_probe_files_fail;
    
        retval = bus_add_groups(bus, bus->bus_groups);
        if (retval)
            goto bus_groups_fail;
    
        pr_debug("bus: '%s': registered\n", bus->name);
        return 0;
    
    bus_groups_fail:
        remove_probe_files(bus);
    bus_probe_files_fail:
        kset_unregister(bus->p->drivers_kset);
    bus_drivers_fail:
        kset_unregister(bus->p->devices_kset);
    bus_devices_fail:
        bus_remove_file(bus, &bus_attr_uevent);
    bus_uevent_fail:
        kset_unregister(&bus->p->subsys);
    out:
        kfree(bus->p);
        bus->p = NULL;
        return retval;
    }
    EXPORT_SYMBOL_GPL(bus_register);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    通过bus_register注册完bus后,将会生成目录结构如下:
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    .NET高级面试指南专题十七【 策略模式模式介绍,允许在运行时选择算法的行为】
    信奥中的数学:集合与子集
    《从行动开始:自我管理的科学 》读书笔记
    Linux文件和文件夹命令详解
    走出3个新生儿喂养误区,新手爸妈变高手
    Ae 效果:CC Star Burst
    计算机毕业设计(附源码)python应急互助信息管理系统
    如何用prompt提示词开发Open AI项目?
    3. executors
    关于融合软件运行unity程序被闪退解决方案
  • 原文地址:https://blog.csdn.net/qq_23327993/article/details/126450164