歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux下設備device_register和驅動driver_register先後注冊的影響和關系

Linux下設備device_register和驅動driver_register先後注冊的影響和關系

日期:2017/3/1 10:05:08   编辑:Linux編程

開始Linux驅動的真正開發,也是從基層開始看的。相比以為Linux下的驅動就是點燈之類的Led來說,現在我的感受就是,那些完全就是表面的東西。核心層次的驅動,完全不是這麼隨隨便便寫出來的。也正好說明現在很多公司正在寫驅動的不多,完全獨立寫的也不多,因為實在太復雜。只能靠著源碼或者BSP來修改。半個多月來看了Linux2.6.10下面的音頻驅動OSS架構,不是一般的復雜。熟悉了I2C驅動的整個架構( 見 http://www.linuxidc.com/Linux/2012-07/64445.htm )。

今天為何再寫這個內容,因為最近開始看Linux下面的視頻架構。恍惚間看到device_register和driver_register,這兩個對驅動真正核心的東西,讓我察覺到這兩個到底誰需要先執行,還是沒關系。百度了很多,都說的是表面文章,去qq上也是一肚子的灰,因此我依舊獨立解決,雖然我知道這個問題基本沒人去思考(除了寫內核的大神們),因為這塊內容和內核走的很近很近,代碼量也大。所以基本可見的分析都在表面。故把我這次的分析總結寫在這裡,供大家借鑒,不對之處也請多指正。

從函數driver_register和device_register在源碼中來看,這兩個函數的執行順序前後都有出現,但是之前都活在表面,沒有深入的看過,因為知道內核在深入下去就是很復雜的東西。但為了解決問題只會硬著頭皮去看。下面是我的一些分析,主要涉及到的是鏈表,kobject,kset,bus,device,device_driver幾個結構體。

1. 先從driver_register的調用流程說起,主要介紹核心的調用,其間的某些函數不做解析。

driver_register->bus_add_driver->

int bus_add_driver(struct device_driver * drv)
{
struct bus_type * bus = get_bus(drv->bus);
int error = 0;

if (bus) {
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
error = kobject_set_name(&drv->kobj, "%s", drv->name); //給kobj賦予名字
if (error) {
put_bus(bus);
return error;
}
drv->kobj.kset = &bus->drivers; //kset指向bus->drivers(類型為kset)
if ((error = kobject_register(&drv->kobj))) {
put_bus(bus);
return error;
}

down_read(&bus->subsys.rwsem);
driver_attach(drv);
up_read(&bus->subsys.rwsem);
module_add_driver(drv->owner, drv);

driver_add_attrs(bus, drv);
}
return error;
}

在這個函數中,我覺得核心的是語句 drv->kobj.kset = &bus->drivers;,為何會這樣說。因為實際上在設備和驅動在注冊的過程中,都會將自己結構體的鏈表成員添加到bus->drivers和bus->devices為鏈表頭的鏈表中去。最後都根據這些鏈表遍歷所在成員的地址,然後找到設備和驅動依次執行是否probe。

Copyright © Linux教程網 All Rights Reserved