注:基於linux-2.6.38
這裡以s3c處理器的framebuffer驅動為例進行說明(其他的平台驅動原理一樣)。找到/drivers/video/samsung/s3cfb.c,首先看模組的初始化函式:
1int __devinit s3cfb_init(void)2
第3行呼叫platform_driver_register(),引數s3cfb_driver的型別為struct platform_driver,看看它的定義:
1static
struct platform_driver s3cfb_driver =,
10 };
第2~5行給一些函式指標賦值,記住第7行這個name成員的值,後面會再提到;下面看platform_driver_register()在drivers/base/platform.c裡的定義:
1int platform_driver_register(struct platform_driver *drv)
2
第3行,設定當前驅動所在的匯流排,從這裡可以看出,平台裝置和平台驅動處在同一條匯流排上;第4~9行,也是一些函式指標賦值操作;關鍵看第11行呼叫的在drivers/base/driver.c裡定義的driver_register():
1int driver_register(struct device_driver *drv)221
22 ret =bus_add_driver(drv);
23if
(ret)
24return
ret;
25 ret = driver_add_groups(drv, drv->groups);
26if
(ret)
27bus_remove_driver(drv);
28return
ret;
29 }
看第14行的driver_find():
1struct device_driver *driver_find(const
char *name, struct bus_type *bus)210
return
null;
11 }
通過函式的2個引數就可以知道,意思就是在bus匯流排上通過name找到它所對應的驅動。其實這裡是不會找得到的,如果能找到就說明當前驅動之前已經註冊過,就會返回出錯資訊。
回到driver_register()第22行的bus_add_driver(),這個函式有點長,只給出關鍵部分:
1int bus_add_driver(struct device_driver *drv)
29 .......................................
第4行的if條件一般會成立,因此看第5行的driver_attach():
1int driver_attach(struct device_driver *drv)
2
遍歷匯流排上每乙個已經註冊了的裝置,每找到乙個就呼叫__driver_attach()來判斷是否與當前驅動匹配(怎麼樣才算匹配?答案即將揭曉),因此有必要看看__driver_attach()的定義:
1static
int __driver_attach(struct device *dev, void *data)
2
如果第15行的driver_match_device()返回0的話後面的都不用執行了,看看它的定義:
1static inline int driver_match_device(struct device_driver *drv,
2struct device *dev)
3
第4行,如果drv->bus->match這個函式有定義,就呼叫drv->bus->match函式,否則返回1。在這裡可以告訴你,drv->bus->match是有定義的,不信?那去看看。
1struct bus_type platform_bus_type =;
是吧,再去看看match函式:
1static
int platform_match(struct device *dev, struct device_driver *drv)
2
第8行和第12行,這兩條返回語句對於當前來說都不會被執行,因此重點在第16行,drv->name的值在本篇的最前面可以看到是"
s3c-fb
",接下來看pdev->name的值:
1struct platform_device s3c_device_fb =;
第2行,看到了吧,也是"
s3c-fb
",事實上在這裡看來這兩個值一定要相同,驅動靠它來找到對應的裝置。
好了,回到__driver_attach()第18行以後的內容,其中第22行的driver_probe_device()會被執行,看它的定義:
1int driver_probe_device(struct device_driver *drv, struct device *dev)
2
關鍵在第13行,really_probe()實現了真正的探測:
1static
int really_probe(struct device *dev, struct device_driver *drv)216
1718
if (dev->bus->probe) else
if (drv->probe)
27 ...................................
第10行,把驅動和裝置對應起來;第18~26行,意思很明顯,從目前來看,第18行的條件不成立而第22行的條件會成立,因此會執行驅動裡定義的probe()函式,在這裡已經知道了驅動程式裡的probe()是什麼時候被呼叫的,後面那些內容是「收尾」工作了。
到這裡已經找到了我想要的東西了,也就告一段落了。
linux裝置驅動學習(三) 併發控制
1.併發介紹 一般來說,作業系統都是支援併發執行能力的,多個執行單元訪問同乙個模組時,如果不能支援併發,則會讓這個模組功能紊亂,像讀寫操作時。兩個使用者同時讀寫,那麼可能乙個使用者執行讀操作時,另乙個使用者可以執行了它的寫操作,這就會出現功能不協調的情況。因此這裡通過併發,將 放在臨界區,通過特定的...
linux驅動學習
1.在dev目錄下用ls l檢視字元裝置,輸出第一列為c的的標識的裝置,其中有主裝置號,和次裝置號 裝置檔案對應裝置驅動,linux將每個裝置對映成為乙個檔案,如果訪問檔案,那麼對應的訪問就是相應的io驅動程式,檔案和驅動主要是通過主裝置號聯絡起來的,次裝置號就是反應了具體是那個裝置 核心中 dev...
Linux驅動學習
1.make時使用make arch arm cross compile arm linux gnueabihf 命令而不是make命令 2.編譯.c檔案使用arm linux gnueabihf gcc o c生產可執行檔案 3.cat proc devices 只顯示驅動的主裝置號,且是分類顯示...