linux总线设备驱动程序框架

简介: linux总线设备驱动程序框架

传统写法:上下分层


image.png


典型的如字符设备驱动。


  • 预先分配GPIO


  • 注册file_operations


  • 使用ioremap映射寄存器,操作寄存器


这种写法的缺点:


  • 硬件绑定很死


  • 不适合扩展


总线模型:左右分离


image.png


  • 把固定的硬件资源放到平台结构中


  • 把固定的驱动程序放到paltform_driver结构中


  • 设备与驱动程序通过bus联系起来(这里的总线是一个虚拟的概念)


struct platform_device led_device; <====> struct platform_driver led_drv;
struct platform_device btn_device; <====> struct platform_driver btn_drv;
struct platform_device lcd_device; <====> struct platform_driver lcd_drv;


这种写法的优缺点:


  • 方便扩展


  • 对于每一个单板都需要提供一个平台,重复的代码太多,从而有了后续的设备树驱动模型(此处暂不研究)


设备与driver是如何匹配上的


相关结构


struct platform_device {
    const char  *name;    //名称
    int     id;
    bool        id_auto;
    struct device   dev;
    u32     num_resources;
    struct resource *resource;
    const struct platform_device_id *id_entry;
    char *driver_override;      //Driver name to force a match
    /* MFD cell pointer */
    struct mfd_cell *mfd_cell;
    /* arch specific additions */
    struct pdev_archdata    archdata;
};
struct platform_driver {
    int (*probe)(struct platform_device *);     //匹配成功后被调用
    int (*remove)(struct platform_device *);
    void (*shutdown)(struct platform_device *);
    int (*suspend)(struct platform_device *, pm_message_t state);
    int (*resume)(struct platform_device *);
    struct device_driver driver;                //{.name = "xxx"}
    const struct platform_device_id *id_table;  //能支持的设备,一个driver可能支持多个设备
};
struct bus_type platform_bus_type = {
    .name       = "platform",
    .dev_attrs  = platform_dev_attrs,
    .match      = platform_match,               // 判断(dev,drv)是否匹配,若匹配,则调用drv->probe
    .uevent     = platform_uevent,
    .pm     = &platform_dev_pm_ops,
};


内核里面有一个虚拟总线(平台总线类型),其上挂着两个链表,左边是设备链表,右边是驱动链表。当我们去注册平台设备时,这个平台设备就会加入左边的链表;当我们去注册一个平台driver时这个平台driver就会加入右边的链表。


这些结构体加入链表后,就会马上和对方的链表的成员一一比较,如果有匹配上的就调用平台驱动的probe函数,来处理dev。


  • 如果platform_device.driver_override存在,则比较platform_device.driver_override和platform_driver.driver.name


  • 如果platform_driver id_table 不为空,比较platform_device.name和platform_driver.driver.name


  • 最后比较platform_device.name 和 platform_driver.driver.name


image.png


函数调用关系


platform_device_register
platform_device_add
    device_add
        bus_add_device // 放入链表
        bus_probe_device  // probe枚举设备,即找到匹配的(dev, drv)
            device_initial_probe
                __device_attach
                    bus_for_each_drv(...,__device_attach_driver,...)
                        __device_attach_driver
                            driver_match_device(drv, dev) // 是否匹配
                            driver_probe_device         // 调用drv的probe
platform_driver_register
__platform_driver_register
    driver_register
        bus_add_driver // 放入链表
            driver_attach(drv)
                    bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
                        __driver_attach
                            driver_match_device(drv, dev) // 是否匹配
                            driver_probe_device         // 调用drv的probe


总结


对于Linux总线设备驱动框架只是一个简单的认识,后续还需要深入学习,如有错误,敬请谅解。

相关文章
|
18天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
53 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
24天前
|
安全 Ubuntu Linux
Metasploit Pro 4.22.6-2024111901 (Linux, Windows) - 专业渗透测试框架
Metasploit Pro 4.22.6-2024111901 (Linux, Windows) - 专业渗透测试框架
42 9
Metasploit Pro 4.22.6-2024111901 (Linux, Windows) - 专业渗透测试框架
|
4月前
|
Linux 程序员 编译器
Linux内核驱动程序接口 【ChatGPT】
Linux内核驱动程序接口 【ChatGPT】
|
5月前
|
Linux
Linux 设备驱动程序(四)
Linux 设备驱动程序(四)
35 1
|
4月前
|
Linux API SoC
Linux电压和电流调节器框架 【ChatGPT】
Linux电压和电流调节器框架 【ChatGPT】
|
5月前
|
存储 缓存 安全
Linux 设备驱动程序(三)(下)
Linux 设备驱动程序(三)
43 0