现在的位置: 首页 > 综合 > 正文

linux内核学习(18)设备模型之第一层sysfs关系图

2013年09月20日 ⁄ 综合 ⁄ 共 2652字 ⁄ 字号 评论关闭

很就没跟大家聊天了,上次聊还是分析完内核启动全过程的事情。这几次发的都是我目前学习设备模型的心得,把它都总结了起来,然后放到博客中供大家学习与探讨。

如果你还记得当时分析到了driver_init()这个函数,那么太好了,因为下面的内容就是对这个函数进行简要分析的。如果你没关注过,那么也不用太那个什么,因为这个函数和内核启动全过程基本没什么联系,看看它在哪里就知道了。drivers/base/init.c文件中,看看目录就知道,我们开始进入设备模型这块内容了,而base/这个目录将设备模型的第一层和第二层,描述的非常细致。第一层和第二层这样的层是我自己分出来的。

第一层:kobject、kset。
第二层:device、bus_type、device_driver。

其实这个是显然的,很多书籍中都提到过第二层,第一层还比较少,不过第一层我基本分析处理完了,重要的东西我已经写在了文章中,这次将第一层里涉及的还有一点内容给说完,那么第一层也算是结束了。

看看driver_init()这个函数吧。

来自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();
}

好像不怎么多,就是调用几个其他的初始化函数。看看第一个devtmpfs_init()。

#ifdef CONFIG_DEVTMPFS
extern int devtmpfs_init(void);
#else
static inline int devtmpfs_init(void) { return 0; }
#endif

设备临时文件,现在我们不要关心,等用到了在回过来分析即可。devices_init(),比较重要。

int __init devices_init(void)
{
    devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
    if (!devices_kset)
        return -ENOMEM;
    dev_kobj = kobject_create_and_add("dev", NULL);
    if (!dev_kobj)
        goto dev_kobj_err;
    sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
    if (!sysfs_dev_block_kobj)
        goto block_kobj_err;
    sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
    if (!sysfs_dev_char_kobj)
        goto char_kobj_err;

    return 0;

 char_kobj_err:
    kobject_put(sysfs_dev_block_kobj);
 block_kobj_err:
    kobject_put(dev_kobj);
 dev_kobj_err:
    kset_unregister(devices_kset);
    return -ENOMEM;
}

创建了几个kobject、kset第一层的对象。注意这些xxx_create_and_add()函数在我之前的文章里都有总结,但没做过多的分析,只需知道内核对象和sysfs文件系统有着关系即可,在sys/目录里存放着这些实实在在的内核对象。对于sysfs我们其实无需担心,因为它接口函数都可以顾名思义,由于sysfs在目前来说不是很重要,因此,我就没去具体分析它了,等用到了具体细节在分析也不迟。同理下面的几个函数完成的功能都差不多。

int __init buses_init(void)
{
    bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
    if (!bus_kset)
        return -ENOMEM;
    return 0;
}

int __init classes_init(void)
{
    class_kset = kset_create_and_add("class", NULL, NULL);
    if (!class_kset)
        return -ENOMEM;
    return 0;
}

int __init firmware_init(void)
{
    firmware_kobj = kobject_create_and_add("firmware", NULL);
    if (!firmware_kobj)
        return -ENOMEM;
    return 0;
}

int __init hypervisor_init(void)
{
    hypervisor_kobj = kobject_create_and_add("hypervisor", NULL);
    if (!hypervisor_kobj)
        return -ENOMEM;
    return 0;
}

你说上面的内核对象具体用来干什么,其实我也不是很清楚,如果清楚了还分析个毛啊!现存着,放在大脑里或者笔记里,等到时候自然需要我们去分析,而且还得必须搞得非常清楚不可。先说到这里,下面的函数是第二层了。我们将第一层出现的常量和关系给总结一下,想了一下,还是用图形的方式表现的更清楚。

可以自己到/sys/目录看看,有没有这些文件,当然的使用的是2.6.36的内核才行,不然可能有些文件没有,呵呵,我用的2.6.22的就没有上面两个文件。好了,上面的东西可能说的有些不具体,我希望有些问题还得自己去分析出来,我只是一个简单总结而已,没有深入。

抱歉!评论已关闭.