pcie的pci_scan_bus

本文详细介绍了PCI Express (PCIe) 总线中资源(io/mem/bus)的初始化过程,特别是如何在创建根总线(root bus)之前准备这些资源。通过分析内核函数pci_scan_bus和pci_add_resource等,展示了资源添加到列表的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pcie的资源主要有三种,分别是io/mem/bus.再调用pci_create_root_bus的时候,这三种资源要提前准备好
[   13.419865] pci_bus 0002:80: root bus resource [mem 0xa8800000-0xaffeffff window]
[   13.419865] pci_bus 0002:80: root bus resource [mem 0xa8800000-0xaffeffff window]
[   13.434941] pci_bus 0002:80: root bus resource [io  0x0000-0xffff window]
[   13.434941] pci_bus 0002:80: root bus resource [io  0x0000-0xffff window]
[   13.448617] pci_bus 0002:80: root bus resource [bus 80-87]
[   13.448617] pci_bus 0002:80: root bus resource [bus 80-87]

例如在pci_scan_bus中首先添加到resources中
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
                    void *sysdata)
{
    LIST_HEAD(resources);
    struct pci_bus *b;

    pci_add_resource(&resources, &ioport_resource);
    pci_add_resource(&resources, &iomem_resource);
    pci_add_resource(&resources, &busn_resource);
    b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
    if (b) {
        pci_scan_child_bus(b);
    } else {
        pci_free_resource_list(&resources);
    }
    return b;
}
重点看一下资源是如何添加到resources 中
void pci_add_resource(struct list_head *resources, struct resource *res)
{
    pci_add_resource_offset(resources, res, 0);
}
void pci_add_resource_offset(struct list_head *resources, struct resource *res,
                 resource_size_t offset)
{
    struct resource_entry *entry;

    entry = resource_list_create_entry(res, 0);
    if (!entry) {
        printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res);
        return;
    }

    entry->offset = offset;
    resource_list_add_tail(entry, resources);
}
在pci_add_resource_offset中首先通过resource_list_create_entry 申请memory,并给resource_entry 中的__res 赋值
struct resource_entry *resource_list_create_entry(struct resource *res,
                          size_t extra_size)
{
    struct resource_entry *entry;

    entry = kzalloc(sizeof(*entry) + extra_size, GFP_KERNEL);
    if (entry) {
        INIT_LIST_HEAD(&entry->node);
        entry->res = res ? res : &entry->__res;
    }

    return entry;
}
一般res 不为null。
在pci_add_resource_offset 得到entry中再给offset赋值0.最后将resources 插入到resources 列表中.
回到pci_scan_bus 中将io/mem/bus 资源插入到resources 这个list中后,然后将可以通过pci_create_root_bus来创建root bus后,就可以通过pci_scan_child_bus来scan 子总线.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值