linux设备模型浅析之设备篇

时间:2025-03-10

linux系统设备模型

Linux设备模型浅析之设备篇

本文属本人原创,欢迎转载,转载请注明出处。由于个人的见识和能力有限,不可能面面俱到,也可能存在谬误,敬请网友指出,本人的邮箱是yzq.seen@http://,博客是http://Linux设备模型,仅仅看理论介绍,比如LDD3的第十四章,会感觉太抽象不易理解,而通过阅读内核代码就更具体更易理解,所以结合理论介绍和内核代码阅读能够更快速的理解掌握linux设备模型。这一序列的文章的目的就是在于此,看这些文章之前最好能够仔细阅读LDD3的第十四章。大部分device和driver都被包含在一个特定bus中,platform_device和platform_driver就是如此,包含在 platform_bus_type中。这里就以对platform_bus_type的调用为主线,浅析platform_device的注册过程,从而理解linux设备模型。platform_bus_type用于关联SOC的 platform device和 platform driver,比如在内核linux-2.6.29中所有S3C2410中的 platform device都保存在devs.c中。这里就以S3C2410 RTC为例。在文章的最后贴有一张针对本例的device model图片,可在阅读本文章的时候作为参照。

一、S3C2410 RTC的platform device定义在arch/arm/plat-s3c24xx/devs.c中,如下:static struct resource s3c_rtc_resource[] = {

[0] = {

.start = S3C24XX_PA_RTC,

.end = S3C24XX_PA_RTC + 0xff,

.flags = IORESOURCE_MEM,

},

[1] = {

.start = IRQ_RTC,

.end = IRQ_RTC,

.flags = IORESOURCE_IRQ,

},

[2] = {

.start = IRQ_TICK,

.end = IRQ_TICK,

.flags = IORESOURCE_IRQ

}

};

struct platform_device s3c_device_rtc = {

.name = "s3c2410-rtc",

.id = -1,

.num_resources = ARRAY_SIZE(s3c_rtc_resource),

.resource = s3c_rtc_resource,

};

把它们添加在arch/arm/mach-s3c2440/ mach- smdk2440.c中,如下:

static struct platform_device *smdk2440_devices[] __initdata = {

&s3c_device_usb,

&s3c_device_lcd,

&s3c_device_wdt,

linux系统设备模型

&s3c_device_i2c0,

&s3c_device_iis,

& s3c_device_rtc

};

系统初始化的时候会调用drivers/base/platform.c里的platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices))将其注册到platform_bus_type,最终被添加到device hierarchy。platform_add_devices()调用了platform_device_register(),而后者又先后调用了

device_initialize()和platform_device_add()。有必要对platform_bus_type的定义作一番注释,其定义如下:

struct bus_type platform_bus_type = {

.name= "platform",// bus的名字,将会生成/sys/bus/platform目录

/* 该属性文件将产生在所有 platform_bus_type类型的设备目录下,文件名为"modalias” */.dev_attrs= platform_dev_attrs,

.match= platform_match,// 用于drive与device匹配的例程

.uevent= platform_uevent,// 用于输出环境变量,与属性文件“uevent”相关

.pm= PLATFORM_PM_OPS_PTR, // 电源管理方面

};

代码中,

1. 通过bus_register(&platform_bus_type)将platform_bus_type 注册到总线模块。本例中,当cat /sys/device/platform/s3c2410-rtc/modalias时将会打印出"platform:s3c2410-wdt",从

platform_dev_attrs的具体实现中你就能看出来。当cat /sys/device/platform/s3c2410-rtc/uevent时将会打印出”DRIVER=s3c2410-wdt MODALIAS=platform:s3c2410-wdt”,从 platform_uevent 的具体实现中你就能看出来。

二、下面解析device_initialize()和platform_device_add()两个例程,它们分别定义在drivers/base/core.c和drivers/base/platform.c中。

device_initialize()的代码如下:

void device_initialize(struct device *dev)

{

dev->kobj.kset = devices_kset;// 设置其指向的kset容器

kobject_init(&dev->kobj, &device_ktype);// 初始化 kobj,将 device_ktype传递给它

klist_init(&dev->klist_children, klist_children_get,

klist_children_put);// 初试化klist

INIT_LIST_HEAD(&dev->dma_pools);

init_MUTEX(&dev->sem);

spin_lock_init(&dev->devres_lock);

INIT_LIST_HEAD(&dev->devres_head);

device_init_wakeup(dev, 0);

device_pm_init(dev);// 初试化电源管理

set_dev_node(dev, -1);

}

代码中,

1. devices_kset是所有dev的kset,也就是所有dev都被链接在该kset下,其在初试化例程devices_init()中通过调用kset_create_and_add("devices", &device_uevent_ops, NULL)来创建。由于参数parent=NULL ,所以生成/sys/devices 目录。这里说明下kobj,kset结构体中包含有一个

linux系统设备模型

kobj,一个kobj生成一个目录,在这里就是”devices "目录,通过调用kobject_add_internal()例程生成。所以从dev->kobj.kset = devices_kset 可以看出,该dev.kobj添加到了devices_kset容器中,所的kobj都归属于一个特定的kset。关于kset,kobj,ktype,kref的关系可以参考书LDD3的第十四章,在第370页有一张说明kobj和kset关系的图(英文版)。

2. kobject_init(&dev->kobj, &device_ktype)用于初始化 dev->kobj中变量的参数,如ktype、kref、entry和state*等。初试化例程devices_init()还会调用kobject_create_and_add()例程生成/sys/dev、/sys/dev/block和/sys/dev/char目录。

3. 其他初始化。

platform_device_add代码如下:

int platform_device_add(struct platform_device *pdev)

{

int i, ret = 0;

if (!pdev)

return -EINVAL;

if (!pdev->dev.parent)

pdev->dev.parent = &platform_bus; // 设置为 platform_bus device

pdev->dev.bus = &platform_bus_type; // 设 …… 此处隐藏:16849字,全部文档内容请下载后查看。喜欢就下载吧 ……

linux设备模型浅析之设备篇.doc 将本文的Word文档下载到电脑

    精彩图片

    热门精选

    大家正在看

    × 游客快捷下载通道(下载后可以自由复制和排版)

    限时特价:7 元/份 原价:20元

    支付方式:

    开通VIP包月会员 特价:29元/月

    注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
    微信:fanwen365 QQ:370150219