很就沒跟大家聊天了,上次聊還是分析完核心啟動全過程的事情。這幾次發的都是我目前學習裝置模型的心得,把它都總結了起來,然後放到部落格中供大家學習與探討。
如果你還記得當時分析到了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的就沒有上面兩個檔案。好了,上面的東西可能說的有些不具體,我希望有些問題還得自己去分析出來,我只是一個簡單總結而已,沒有深入。