很就没跟大家聊天了,上次聊还是分析完内核启动全过程的事情。这几次发的都是我目前学习设备模型的心得,把它都总结了起来,然后放到博客中供大家学习与探讨。
如果你还记得当时分析到了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的就没有上面两个文件。好了,上面的东西可能说的有些不具体,我希望有些问题还得自己去分析出来,我只是一个简单总结而已,没有深入。