Linux裝置模型之platform匯流排

2021-06-18 13:38:15 字數 4066 閱讀 2051

------------------------------------------

出處:------------------------------------------

一:前言

platform匯流排是kernel中最近加入的一種虛擬匯流排.在近版的2.6kernel中,很多驅動都用platform改寫了.只有在分析完platform匯流排之後,才能繼續深入下去分析.在分析完sysfs和裝置驅動模型之後,這部份應該很簡單了.閒言少敘.步入正題.go.go!以下的源**分析是基於2.6.25的.

二:platform概貌

在分析源**之前,先在核心**中找乙個platform架構的驅動程式.下面以i8042晶元的驅動為例進行分析.

在linux-2.6.25/drivers/input/serio/i8042.c的intel 8042的初始化入口中,有以下**分段:

static int __init i8042_init(void)

err = platform_device_add(i8042_platform_device);

if (err)

goto err_free_device;……}

我們在上面的程式片段中看到,驅動程式先註冊了乙個platform device.然後又新增了乙個platform device.這裡就涉及到了platform的兩個最主要的操作,乙個裝置驅動註冊,乙個裝置註冊.

要了解platform匯流排的來龍去脈.得從它的初始化開始.

三:platform初始化

platform匯流排的初始化是在linux-2.6.25/drivers/base/platform.c中的platform_bus_init()完成的,**如下:

int __init platform_bus_init(void)

上面**中呼叫的子函式在<

接著,這段初始化**又建立了乙個名為「platform」的匯流排.

platform_bus_type的定義如下:

struct bus_type platform_bus_type = ;

我們知道,在bus_type中包含了諸如裝置與驅動匹配.hotplug事件等很多重要的操作.這些操作在分析platform裝置註冊與platform驅動註冊的時候依次分析.

四:platform device註冊

在intel 8042的驅動**中,我們看到註冊乙個platform device分為了兩部分,一部份是建立乙個platform device結構,另一部份是將其註冊到匯流排中.先來看第乙個介面.

struct platform_device *platform_device_alloc(const char *name, int id)

return pa ? &pa->pdev : null;

}這段**主要初始化了封裝在struct platform_object中的struct device.

struct platform_object結構定義如下:

struct platform_object ;

在定義中,定義name為乙個長度.所以,才有了platform_device_alloc()中分配struct platform_object的時候多加了名稱的長度:

pa = kzalloc(sizeof(struct platform_object) + strlen(name), gfp_kernel);

struct device結構如下:

struct platform_device ;

在這個結構裡封裝了struct device.struct resource. struct resource這個結構在此之前沒有接觸過,這個結構表示裝置所擁有的資源.即i/o埠或者是i/o對映記憶體.

platform_device_add()**分段分析如下:

int platform_device_add(struct platform_device *pdev)

if (p && insert_resource(p, r))

}如果裝置指定了它所擁有的資源,將這些資源分配給它.如果分配失敗,則失敗退出.從**中可以看出.如果struct resource的flags域被指定為ioresource_mem.則所表示的資源為i/o對映記憶體.如果指定為ioresource_io.則所表示的資源為i/o埠.

pr_debug("registering platform device '%s'. parent at %s\n",

pdev->dev.bus_id, pdev->dev.parent->bus_id);

ret = device_add(&pdev->dev);

if (ret == 0)

return ret;

failed:

while (--i >= 0)

if (pdev->resource[i].flags & (ioresource_mem|ioresource_io))

release_resource(&pdev->resource[i]);

return ret;

}device_add()已經很熟悉了吧.沒錯,它就是將裝置註冊到指定的bus_type.

在分析linux裝置模型的時候,曾說過.呼叫device_add()會產生乙個hotplug事件.platform device的hotplug與一般的device事件相比.它還要它所屬bus_type的uevent().對這個流程不熟悉的可以參照<< linux裝置模型深探》.platform device所屬的bus_type為platform_bus_type.它的uevent()介面**如下:

static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)

上面的**很簡單,它就是在環境變數中新增一項modalias.

五:platform driver的註冊

在intel 8024的驅動**中看到.platform driver註冊的介面為:

int platform_driver_register(struct platform_driver *drv)

struct platform_driver主要封裝了struct device_driver結構.如下:

struct platform_driver ;

在這個介面裡,它指定platform driver的所屬匯流排.如果在struct platform_driver指定了各項介面的操作,就會為struct device_driver中的相應介面賦值.

不要被上面的platform_drv_***嚇倒了,它們其實很簡單,就是將struct device轉換為struct platform_device和struct platform_driver.然後呼叫platform_driver中的相應介面函式

最後, platform_driver_register()將驅動註冊到匯流排上.

這樣,匯流排上有裝置,又有驅動,就會進行裝置與匹配的過程,呼叫的相應介面為:

bus ->match --- > bus->probe/driver->probe (如果匯流排的probe操作不存在,就會呼叫裝置的probe介面).

這樣,我們又回到platform_bus_type中的各項操作了.

對應的match介面如下:

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

從**中看出.如果要匹配成功,那麼裝置與驅動的名稱必須要一致.

platform_bus_type中沒有指定probe介面,所以,會轉至驅動的probe介面,在platform_driver_register()中.將其probe介面指定為了platform_drv_probe.這個函式又會將操作回溯到struct platform_driver的probe介面中.

到這裡,platform driver的註冊過程就會析完了.

六:小結

在本小節裡,我們以linux裝置模型為基礎.分析虛擬匯流排platform的架構.對其hotplug事件,以及裝置與驅動的匹配過程做了非常詳細的分析.這部份知識是我們深入理解具體裝置驅動的基礎.

linux裝置模型之kobject

kobject 結構 在linux核心裡,kobject是組成linux裝置模型的基礎,乙個kobject對應sysfs裡的 乙個目錄。從物件導向的角度來說,kobject可以看作是所有裝置物件的基類,因為c 語言並沒有物件導向的語法,所以一般是把kobject內嵌到其他結構體裡來實現類似的 作用,...

Linux驅動之裝置模型 3

4 小結 4.1 kobject,kset和ktype kobject,kset和ktype就三個結構體,但是卻很容易讓人混淆,是由於它們內部相互交織。l kobject,是裝置模型中的基本物件,包含了引用計數,父子關係,目錄項等,通常會嵌入到其它的資料結構中,使其也具有kobject的特性 l k...

Linux驅動之裝置模型 5

6 裝置 6.1 裝置 l linux裝置模型中每乙個裝置用device結構來表示 struct device 6.2 裝置屬性 l 裝置屬性由device attribute來表示 structdevice attribute device attr name,mode,show,store l ...