Linux驱动的platform机制

本文深入探讨了Linux内核中的Platform驱动机制,包括Platform概述、Platform总线、设备和驱动注册流程、Platform分析等内容。Platform机制提高了驱动和资源管理的独立性,适用于与内核运行依赖性不大的外围设备,提供了统一的接口访问系统资源,增强了可移植性。
摘要由CSDN通过智能技术生成

一、Platform概述

    从Linux2.6起,内核引入了一套新的驱动管理和注册机制:Platform_device和 Platform_driver。现在Linux中大部分的设备驱动都可以使用这套机制,总线为platform_bus,设备用platform_device表示,驱动用platform_driver进行注册。

    Linux的这种platform driver机制和传统的device_driver机制相比,一个十分明显的优势在于platform机制将本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform_device提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性。下面是SPI驱动层次示意图,Linux中的SPI总线可理解为SPI控制器引出的总线:


和传统的驱动一样,platform机制也分为三个步骤:

1、总线注册阶段:

    内核启动初始化时linux3.12/init/main.c文件中的: kernel_init()→kernel_init_freeable()->do_basic_setup()→driver_init()→platform_bus_init()→bus_register(&platform_bus_type), 注册了一条platform总线(虚拟总线,platform_bus)。

分析流程:

    platform_bus_init ->bus_register,调用bus_register注册总线platform_bus_type,其名字为"platform",并且在platform目录下创建devices和drivers目录.

   
   
   
int __init platform_bus_init(void)
{
...
early_platform_cleanup();
 
error = device_register(&platform_bus);
error = bus_register(&platform_bus_type);
return error;
}
 
struct bus_type platform_bus_type = {
.name = "platform",
.dev_groups = platform_dev_groups,
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
};
分析bus_register:
    
    
    
int bus_register(struct bus_type *bus)
{
int retval;
struct subsys_private *priv; //重点
priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);
priv->bus = bus; //指定 priv中的bus_type;
bus->p = priv; //指定bus中的priv;
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); //将名字"platform"赋值给kobject
priv->subsys.kobj.kset = bus_kset;
priv->subsys.kobj.ktype = &bus_ktype; //初始化为bus_ktype
priv->drivers_autoprobe = 1;
 
retval = kset_register(&priv->subsys); //注册kset
retval = bus_create_file(bus, &bus_attr_uevent);
 
priv->devices_kset = kset_create_and_add("devices", NULL, //在sys/bus/platform目录创建devices
&priv->subsys.kobj);
 
priv->drivers_kset = kset_create_and_add("drivers", NULL, //在sys/bus/platform目录创建drivers
&priv->subsys.kobj);
klist_init (& priv -> klist_devices ,  klist_devices_get ,  klist_devices_put );
klist_init(&priv->klist_drivers, NULL, NULL);
 
retval = add_probe_files(bus);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值