歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux 2.6下的platform_driver和platform_device(結合G870加密磁頭驅動分析)

Linux 2.6下的platform_driver和platform_device(結合G870加密磁頭驅動分析)

日期:2017/3/1 10:57:19   编辑:Linux編程
首先介紹一下注冊一個驅動的步驟:
1、定義一個platform_driver結構
2、初始化這個結構,指定其probe、remove等函數,並初始化其中的driver變量

3、實現其probe、remove等函數


看platform_driver結構,定義於include/linux/platform_device.h文件中:
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct device_driver driver;
};

可見,它包含了設備操作的幾個功能函數,同樣重要的是,它還包含了一個device_driver結構。剛才提到了驅動程序中需要初始化這個變量。下面看一下這個變量的定義,位於include/linux/device.h中:

struct device_driver {
const char * name;
struct bus_type * bus;
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module * owner;
const char * mod_name; /* used for built-in modules */
struct module_kobject * mkobj;
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
void (*shutdown) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state);
int (*resume) (struct device * dev);
};

需要注意這兩個變量:name和owner。那麼的作用主要是為了和相關的platform_device關聯起來,owner的作用是說明模塊的所有者,驅動程序中一般初始化為THIS_MODULE。

加密磁頭的platform_driver定義如下:

static struct platform_driver secure_head_driver = {
.driver = {
.name = "secure_head",
},
.suspend = secure_head_suspend,
.resume = secure_head_resume,
.probe = secure_head_module_probe,
.remove = secure_head_module_remove,
};

注意其中的driver這個結構體,只初始化了name。接著看一下和driver相關的另一個結構,定義如下:


struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
};

該結構中也有一個name變量。platform_driver從字面上來看就知道是設備驅動。設備驅動是為誰服務的呢?當然是設備了。platform_device就描述了設備對象。加密磁頭的platform_device定義如下(定義在arch/arm/mach-mx25/devices.c中):

static struct platform_device mxc_secure_head_device = {
.name = "secure_head",
.id = 0,
.num_resources = ARRAY_SIZE(imx_secure_head_resources),
.resource = imx_secure_head_resources,
.dev = {
.release = NULL,
},
};

它的name變量和剛才上面的platform_driver的name變量是一致的,內核正是通過這個一致性來為驅動程序找到資源,即platform_device中的resource。這個結構的定義如下,位於include/linux/ioport.h中:

struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};

下面是磁頭的resource的定義:

static struct resource imx_secure_head_resources[] = {
[0] = {
.start = IOMUX_TO_IRQ(MX25_PIN_DE_B),
.end = IOMUX_TO_IRQ(MX25_PIN_DE_B),
.flags = IORESOURCE_IRQ,
},
};

注意:其中IORESOURCE_IRQ表示這個是中斷資源,IOMUX_TO_IRQ(MX25_PIN_DE_B)為加密磁頭所對應的中斷引腳的映射地址。這樣在注冊設備時內核才知道這些數據。

Copyright © Linux教程網 All Rights Reserved