Linux驅動學習(三)

2021-09-08 03:26:52 字數 3193 閱讀 3594

注:基於linux-2.6.38

這裡以s3c處理器的framebuffer驅動為例進行說明(其他的平台驅動原理一樣)。找到/drivers/video/samsung/s3cfb.c,首先看模組的初始化函式:

1

int __devinit s3cfb_init(void)2

第3行呼叫platform_driver_register(),引數s3cfb_driver的型別為struct platform_driver,看看它的定義:

1

static

struct platform_driver s3cfb_driver =,

10 };

第2~5行給一些函式指標賦值,記住第7行這個name成員的值,後面會再提到;下面看platform_driver_register()在drivers/base/platform.c裡的定義:

1

int platform_driver_register(struct platform_driver *drv)

2

第3行,設定當前驅動所在的匯流排,從這裡可以看出,平台裝置和平台驅動處在同一條匯流排上;第4~9行,也是一些函式指標賦值操作;關鍵看第11行呼叫的在drivers/base/driver.c裡定義的driver_register():

1

int 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():

1

struct device_driver *driver_find(const

char *name, struct bus_type *bus)210

return

null;

11 }

通過函式的2個引數就可以知道,意思就是在bus匯流排上通過name找到它所對應的驅動。其實這裡是不會找得到的,如果能找到就說明當前驅動之前已經註冊過,就會返回出錯資訊。

回到driver_register()第22行的bus_add_driver(),這個函式有點長,只給出關鍵部分:

1

int bus_add_driver(struct device_driver *drv)

29 .......................................

第4行的if條件一般會成立,因此看第5行的driver_attach():

1

int driver_attach(struct device_driver *drv)

2

遍歷匯流排上每乙個已經註冊了的裝置,每找到乙個就呼叫__driver_attach()來判斷是否與當前驅動匹配(怎麼樣才算匹配?答案即將揭曉),因此有必要看看__driver_attach()的定義:

1

static

int __driver_attach(struct device *dev, void *data)

2

如果第15行的driver_match_device()返回0的話後面的都不用執行了,看看它的定義:

1

static inline int driver_match_device(struct device_driver *drv,

2struct device *dev)

3

第4行,如果drv->bus->match這個函式有定義,就呼叫drv->bus->match函式,否則返回1。在這裡可以告訴你,drv->bus->match是有定義的,不信?那去看看。

1

struct bus_type platform_bus_type =;

是吧,再去看看match函式:

1

static

int platform_match(struct device *dev, struct device_driver *drv)

2

第8行和第12行,這兩條返回語句對於當前來說都不會被執行,因此重點在第16行,drv->name的值在本篇的最前面可以看到是"

s3c-fb

",接下來看pdev->name的值:

1

struct platform_device s3c_device_fb =;

第2行,看到了吧,也是"

s3c-fb

",事實上在這裡看來這兩個值一定要相同,驅動靠它來找到對應的裝置。

好了,回到__driver_attach()第18行以後的內容,其中第22行的driver_probe_device()會被執行,看它的定義:

1

int driver_probe_device(struct device_driver *drv, struct device *dev)

2

關鍵在第13行,really_probe()實現了真正的探測:

1

static

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 只顯示驅動的主裝置號,且是分類顯示...