【Linux 内核同函数多重定义】

发布于:2025-06-28 ⋅ 阅读:(19) ⋅ 点赞:(0)

参考链接:
内核源码中为什么会存在同一个函数的多重定义?什么是符号的强弱性?

阅读驱动源码,会发现同一个函数有不同的定义位置,比如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 这个头文件,而且他仅仅使用了这个结构体的一部分,所以干脆自己定义了,即使传进来的结构体类型与自己定义的结构体类型有点不同,但也不影响使用。


网站公告

今日签到

点亮在社区的每一天
去签到