微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Windows中获取PCI区域大小?

我需要扫描我的PCI总线并获取特定供应商的特定设备的信息.
我的目标是找到AMD显卡的PCI区域大小,以便将该卡的PCI内存映射到用户空间,以便进行i2c传输并查看来自各种传感器的信息.

为了扫描PCI总线,我在一年前下载并编译了pciutils 3.1.7 for Windows x64.据说它使用DirectIO.

这是我的代码.

int scan_pci_bus()
{
    struct pci_access *pci;
    struct pci_dev *dev;
    int i;

    pci = pci_alloc();
    pci_init(pci);

    pci_scan_bus(pci);

    for(dev = pci->devices; dev; dev = dev->next) 
    {
        pci_fill_info(dev,PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_PHYS_SLOT);
        if(dev->vendor_id == 0x1002 && dev->device_id == 0x6899)
        {
            //vendor is AMD,Device ID is a AMD HD5850 GPU
            for(i = 0; i < 6; i++) 
            {
                printf("Region Size %d %x ID %x\n",dev->size[i],dev->base_addr[i],dev->device_id);
            }
        }
    }


    pci_cleanup(pci);

    return 0;
}

正如您在我的printf行中看到的,我尝试打印一些数据,我成功打印了device_id和base_addr,但是应该包含此设备的PCI区域大小的大小始终为0.我预计,至少有一个来自循环的循环显示尺寸> 0.

我的代码基于一个使用相同代码的Linux应用程序,尽管它使用Linux附带的pci.h头文件(pciutils看起来有相同的API).
显然,Windows(在我的情况下是Windows 7 x64)没有显示此信息,或者至少没有暴露给PCIUtils.

您如何建议我获取此信息?如果有替代pciutils for Windows并提供此信息,我很乐意获得它们的链接.

编辑:我仍然没有找到解决方案.如果我的问题有任何解决方案,也适用于32位Windows,我们将不胜感激.

好的whamma给出了一个非常好的答案[但]有一件事他错了,这是区域大小.区域大小很容易找到,在这里我将展示两种方式,第一种方法是从条形码的地址解密,第二种方式是通过Windows用户界面.

假设E2000000是基址寄存器的地址.如果我们将其转换为二进制,我们得到:
11100010000000000000000000000000

现在总共有32位,如果必须,你可以计算它们.现在,如果你不熟悉这些位
一个BAR被打好了,看这里 – > http://wiki.osdev.org/PCI,特别是“基地址寄存器”,更具体地说
读取“Memory Space BAR Layout”的图像.现在让我们开始读取从右端到左端的位并使用
链接中的图像我指出你作为指导.

因此从右侧开始的第一位(位0)为0,表示这是存储器地址BAR.
位(1-2)为0,表示它是32位(注意这不是大小)内存BAR.
位3为0,表示它不是Prefetchable内存.
现在我们消除了无用的位让我们继续保持良好的位置,位4-31.如果你看看位的4 -31你会
注意第一位是“1”是位24.这是一些数学发挥作用的地方.首先我们必须找到
Bit 24的二进制加权值,即16777216,也是16777216字节,即16 MB,告诉我们
BAR分配的内存大小为16 MB.如果你想知道我如何得到第24位的二进制加权值,它就像这样:2(二进制是基数2)乘以
本身24(位24)次,或2到24的幂,或2 ^ 24.

另一种方法是使用设备管理器:开始 – >“设备管理器” – >显示适配器 – >右键单击视频卡 – >属性 – >资源.标记的每种资源类型“Memory Range”应该是一个内存BAR,你可以看到[start address]到[end address].例如,让我们说它读取[00000000E2000000 – 00000000E2FFFFFF],从[end address]获取[start address]的大小:00000000E2FFFFFF – 00000000E2000000 = FFFFFF,十进制的FFFFFF = 16777215 = 16777215字节= 16MB.

原文地址:https://www.jb51.cc/windows/365043.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐