参考链接:
内核源码中为什么会存在同一个函数的多重定义?什么是符号的强弱性?
阅读驱动源码,会发现同一个函数有不同的定义位置,比如drivers/pci/of.c
中的of_pci_range_parser_init
函数。可找到两个定义位置:
位于:drivers/of/address.c
static int parser_init(struct of_pci_range_parser *parser,
struct device_node *node, const char *name)
{
int rlen;
parser->node = node;
parser->pna = of_n_addr_cells(node);
parser->na = of_bus_n_addr_cells(node);
parser->ns = of_bus_n_size_cells(node);
parser->dma = !strcmp(name, "dma-ranges");
parser->bus = of_match_bus(node);
parser->range = of_get_property(node, name, &rlen);
if (parser->range == NULL)
return -ENOENT;
parser->end = parser->range + rlen / sizeof(__be32);
return 0;
}
int of_pci_range_parser_init(struct of_pci_range_parser *parser,
struct device_node *node)
{
return parser_init(parser, node, "ranges");
}
EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
位于:include/linux/of_address.h
static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
struct device_node *node)
{
return -ENOSYS;
}
通过实验验证也可知道上面的才是真正的实现,但是drivers/pci/of.c中调用了<linux/of_address.h>让我很疑惑内核是怎么做到的,为什么这么做,这就需要看看第一篇参考文章了。
不光函数是这样,有些结构体也可找到在多个文件中定义:
还是这个文件的struct of_pci_range range;
位于:drivers/pci/of_property.c
struct of_pci_range {
u32 child_addr[OF_PCI_ADDRESS_CELLS]; //3
u32 parent_addr[OF_PCI_ADDRESS_CELLS]; //3
u32 size[OF_PCI_SIZE_CELLS]; //2
};
位于:include/linux/of_address.h
struct of_pci_range {
union {
u64 pci_addr;
u64 bus_addr;
};
u64 cpu_addr;
u64 size;
u32 flags;
};
虽然通过文件的使用判断第二个文件是真的,但是为啥要在drivers/pci/of_property.c
中定义一个不一样的呢?,what’s the fuck?老子晕了。可能的解释是:
drivers/pci/of_property.c
中确实需要使用struct of_pci_range这个结构体,但是他没有include linux/of_address.h
这个头文件,而且他仅仅使用了这个结构体的一部分,所以干脆自己定义了,即使传进来的结构体类型与自己定义的结构体类型有点不同,但也不影响使用。