1. 总线设备驱动模型
这一部分的主要内容可参考上述博客
1.1 platform dev和drv 匹配机制
-
首先匹配
device
中的driver_override
与drv
中name
是否匹配 -
第二匹配设备中
device
中从设备树中解析的properties(即compatible) type name
。存放在device
存放在devicenode
中,deriver
存放在of_match_table
中此项中匹配顺序为
compatible > type > name
-
如果上述依然无法配到到对应的
device
和driver
,则接下来去匹配platform_device.name
和platform_driver.id_table[i].name
-
最后回去匹配
device
的name
与deriver
的name
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);
/* When driver_override is set, only bind to the matching driver */
if (pdev->driver_override)
return !strcmp(pdev->driver_override, drv->name);
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv))
return 1;
/* Then try ACPI style match */
if (acpi_driver_match_device(dev, drv))
return 1;
/* Then try to match against the id table */
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);
}
当device与deriver匹配成功后调用deriver->probe。在probe中执行相关的初始化操作
2. 知识点扩展
2.1 ioremap/iounmap
将物理地址转化为linux能直接使用的虚拟地址
static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
返回地址为虚拟地址的首地址
注意:ioremap物理地址和虚拟地址的映射是整页整页的映射的。(一页为4096字节)
2.2 volatile
这里需要理解一点就是编译器的优化机制
int a;
a = 0;
a = 1;
如上所述,编译器可以直接优化为a=1
,这对于操作硬件寄存器等操作来说是不能接受的