pci_resource_start 是如何得到PCI的物理地址的

_Wayne_ 2015-03-16 02:14:50
主要是针对linux系统。
#define pci_resource_start(dev,bar) ((dev)->resource[(bar)].start)

设备的resource是在什么时候被初始化的?这个值又是从哪里得到的呢?
根据网上一些资料我说一下我的理解:linux系统启动时pci核心模块扫描到外面的PCI设备然后根据其配置空间基地址得到要申请的内存空间大小,然后CPU根据pci_resource_start返回的物理地址映射一块内存空间并将内存块的基地下写回到pci的配置空间。然后CPU操作该内存空间就可以操作pci的寄存器了。那么现在的问题就是,pci_resource_start这个返回的物理地址到底是怎么得来的呢???
...全文
5067 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
_Wayne_ 2015-03-16
  • 打赏
  • 举报
回复 2
引用 1 楼 lee244868149 的回复:
在硬件加电初始化时,BIOS固件同统一检查了所有的PCI设备, 并统一为他们分配了一个和其他互不冲突的地址,让他们的驱动程序可以向这些地址映射他们的寄存器,这些地址被BIOS写进了各个设备的配置空间,因为这个 活动是一个PCI的标准的活动,所以自然写到各个设备的配置空间里而不是他们风格各异的控制寄存器空间里。当然只有BIOS可以访问配置空间。当操作系统 初始化时,他为每个PCI设备分配了pci_dev结构,并且把BIOS获得的并写到了配置空间中的地址读出来写到了pci_dev中的resource 字段中。这样以后我们在读这些地址就不需要在访问配置空间了,直接跟pci_dev要就可以了,我们这里的四个函数就是直接从pci_dev读出了相关数 据,代码在include/linux/pci.h中。定义如下:

#define pci_resource_start(dev,bar) ((dev)->resource[(bar)].start)
#define pci_resource_end(dev,bar) ((dev)->resource[(bar)].end)

这里需要说明一下,每个PCI设备有0-5一共6个地址空间,我们通常只使用前两个,这里我们把参数1传给了bar就是使用内存映射的地址空间。

如果要更具体,查看pci_dev结构的初始化过程


我这用的linux系统没有bios,bootloader启动过程的打印看出貌似两个pcie接口都没有初始化。

而且物理地址是64位的,PCI的配置功能的基地址只有32位,而且还不全是地址位,应该保存不了您上面提到的BIOS分配的物理地址。而且我在内核中也打印出了基地址0和1的两个32位的数,和真正的物理地址对不上。现在就是很困惑,不知道这个应该怎么解释?
奔跑的路 2015-03-16
  • 打赏
  • 举报
回复 2
在硬件加电初始化时,BIOS固件同统一检查了所有的PCI设备, 并统一为他们分配了一个和其他互不冲突的地址,让他们的驱动程序可以向这些地址映射他们的寄存器,这些地址被BIOS写进了各个设备的配置空间,因为这个 活动是一个PCI的标准的活动,所以自然写到各个设备的配置空间里而不是他们风格各异的控制寄存器空间里。当然只有BIOS可以访问配置空间。当操作系统 初始化时,他为每个PCI设备分配了pci_dev结构,并且把BIOS获得的并写到了配置空间中的地址读出来写到了pci_dev中的resource 字段中。这样以后我们在读这些地址就不需要在访问配置空间了,直接跟pci_dev要就可以了,我们这里的四个函数就是直接从pci_dev读出了相关数 据,代码在include/linux/pci.h中。定义如下: #define pci_resource_start(dev,bar) ((dev)->resource[(bar)].start) #define pci_resource_end(dev,bar) ((dev)->resource[(bar)].end) 这里需要说明一下,每个PCI设备有0-5一共6个地址空间,我们通常只使用前两个,这里我们把参数1传给了bar就是使用内存映射的地址空间。 如果要更具体,查看pci_dev结构的初始化过程

1,324

社区成员

发帖
与我相关
我的任务
社区描述
主要是开发驱动技术
社区管理员
  • 驱动程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧