今天trace platform device,看如何利用platform device structure內的device structure pointer得知platform device structure的位址
呼叫platform_match in drivers/base/platform.c
static __init struct platform_device *
early_platform_match(struct early_platform_driver *epdrv, int id)
{
struct platform_device *pd;
list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
if (platform_match(&pd->dev, &epdrv->pdrv->driver))
if (pd->id == id)
return pd;
return NULL;
}
這是platform_match的定義
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* match against the id table first */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
主要今天目標是這行,之前上課時老師有說過,現在才拿出來看 T _ T
struct platform_device *pdev = to_platform_device(dev);
define to_platform_device in include/linux/platform_device.h
#define to_platform_device(x) container_of((x), struct platform_device, dev)
define container_of in include/linux/kernel.h
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
define offsetof in include/linux/stddef.h
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
#endif /* __KERNEL__ */
offsetof 將0轉換成(TYPE *),即指向0的TYPE指標,((size_t) &((TYPE *)0)->MEMBER)就可以取得此MEMBER在這結構內位址值。
比如說platform_device structure(pd) 內的 device structure(dev)成員位置在0x1004。
假設dev在pd內的相對位址為4,那0x1004減去4就可以得到pd的指標位址。