免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 30067 | 回复: 41
打印 上一主题 下一主题

[硬件及驱动] 关于PCIE、主桥、BAR、驱动、MMU、IOMMU、地址翻译 [复制链接]

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:49:45IT运维版块每日发帖之星
日期:2016-07-29 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-23 18:37 |只看该作者 |倒序浏览
本帖最后由 冬瓜头 于 2013-12-24 12:07 编辑

最近学习了一下PCIE,牵扯不少名词,网络上不少blog和文章,对虚拟地址、物理地址、翻译过程理不清头绪,在这里尝试总结一下问题,并给出自己的理解(大部分是基于推导猜测),希望了解这块的大侠们纠正,有些问题自己也不懂,希望能够得到指点。谢谢!

1. BIOS或者内核在初始化PCIE的时候,BAR里写入的基地址到底是虚拟存储器域地址,还是物理存储器域地址,还是pcie总线域地址?
答:PCIE总线域地址,内核自己记录每个设备的主存物理地址--PCIE总线域地址映射。

2. 那好,那么初始化好之后,该设备驱动加载时,据说要做ioremap,这是怎么回事?
答:保护模式下,谁都绕不过MMU和页表(内核自身也绕不过么?),必须使用虚拟地址,包括内核自身(比如Linux下高1GB和Windows下高2GB或1GB)。驱动必须把内核初始化好的这些BAR物理基地址ioremap()为内核虚拟空间的虚拟地址。之后读写IO端口也必须使用虚拟地址。

3. 那好,ioremap之后,映射关系被保存在了哪里,是页表里么?
答:是的,由于内核虚拟空间被每个用户进程公用,所有进程页表的内核空间映射都是共享的,就被保存在这里,也要经过MMU,所以陷入内核不需要更新CR3寄存器。

4. 那好,驱动发出某个虚拟地址读写设备某寄存器,经过MMU翻译之后,北桥怎么知道这地址是发给该物理设备的?PCIE设备DMA的时候不是必须发出PCIE总线物理地址么,如果它发出的驱动告诉它的主存虚拟地址,怎么解?
答:内核初始化PCIE的时候,会对北桥编程,将所有外设的地址范围保存在北桥的缓存里,所以北桥知道,并且知道哪些地址是应该交给PCIE控制器,也就是PCIE主桥处理的。至于第二个问题,不清楚。。

5. 那好,PCIE主桥收到对应地址的访问之后,做了什么?
答:主桥直接在PCIE地址总线上放置收到的地址信号,次级桥或者bus0总线上的EP终端设备都会解析这个地址,如果发现是自己BAR+Limit地址范围之内的,就会认领这个信号,从而启动数据传输周期。

6. 那么PCIE主桥屁事不干就管转发信号?
答:这个不清楚,之前看到的是主桥负责把主机物理地址翻译长PCIE总线地址,按照上述过程,根本不用翻译,每个PCIE设备都知道自己负责响应哪块地址段,因为各自都知道各自的BAR基地址和limit,看不出哪里需要翻译。而且至今也不理解所谓“PCIE总线地址”原生是个什么概念,是不是那意思是说每个PCIE设备在没被初始化之前都认为自己的BAR基地址是从0开始。。不清楚所谓“主桥地址翻译”在什么时候翻译了谁。。

7. 那好,PCIE设备从主机端内存DMA数据进来,是走PCIE数据总线么?
答:是的,PCIE串行+并行方式传输数据。

8. 那好,PCIE设备上的DMA控制器是和北桥上的DMA控制器在电路级连通么?
答:不清楚,猜测是连接到PCIE主桥,经过翻译之后,再访问内存控制器。

9. 那好,PCIE设备要启动DMA,它怎么知道去哪个地址DMA?
答:驱动在初始化该设备的时候,会把主存里的数据缓存、指令队列等基地址写到设备的专用寄存器里,并保持恒久不变。设备通过访问该基地址得到指令以及SGL内存段描述表,从而知道去哪里DMA。

10. 那好,驱动通知给设备的这些地址,是硬件物理地址还是虚拟地址?
答:一定是虚拟地址,因为驱动写入这些寄存器里的地址虽然是地址,但是是作为数据形式写入的,MMU不会感知到“数据”里面保存的是地址。

11. 那好,设备通过DMA控制器把要访问的虚拟地址发送给北桥DMA控制器,北桥DMA控制器是要通过MMU翻译成物理地址么?
答:理论上应该是这样,但是据说有个叫做IOMMU的东西,专门负责DMA时候的地址翻译。但是这里我也不明白,IOMMU会把虚拟地址翻译成物理地址么?为何不用MMU,单独搞一个IOMMU?

12. 那好,PCIE设备是不是只能访问主机端主存在BAR里定义的地址段?
答:之前看过一些文章说不管是CPU访问外设地址还是外设访问主存地址,都是限制在BAR里的地址段的,都不能越界访问。但是现实中好像根本不是这么回事。外设DMA主存的时候可以访问任意地址空间,有4GB可用,那么一定是虚拟空间了,我之前也理解外设访问主存也必须限制在BAR规定的地址段内,可能被深深误导了。但是既然SGL里通告的是虚拟地址,那么为何DMA不是用MMU来映射回物理地址呢?非要再搞个IOMMU为何呢?

13. 那好,请告诉我既然有“PCIE域总线地址”,那么PCIE插槽针脚上,地址线连接在哪里?
答:PCIE总线使用数据针脚复用地址和数据信号,分周期,先地址,后数据。但是,也请明白的告诉我,传送64位地址的话,一个时钟周期传完,起码要64根导线,PCIE插槽上如果是4个Lane的,没有64线吧,那是不是要分多个周期传送了。

14. 好吧。那么所谓“PCI设备在向主存DMA的时候使用的也是PCIE总线域地址而不是主存地址”,能否解释一下这句话?死活想不通,PCIE设备怎么能使用PCIE总线域地址向主存DMA?这不相当于刻舟求剑么?驱动告诉它去哪DMA,它就去应该去哪DMA,完全不懂。
答:不要问了,我已经疯了。

15. 哦。那请告诉我书上说“BAR内存放的是PCIE总线域的地址而不是存储器域的地址”,我也要疯了,内核初始化PCIE的时候,不是把其分配的存储器域的基地址写入到BAR内么?怎么就不是存储器域的地址了呢?难道“正统”做法应该是写入PCIE总线域地址,然后再由PCIE主桥进行翻译?
答:哎?尼玛,你可能还真说对了。的确“正统”的做法,就是为每个PCIE设备分配各自的PCIE域的总线基地址并保证不冲突,然后为每个PCIE域的基地址映射存储器域的基地址,然后记录在PCIE初始化那个树结构里,并且把这个地址翻译表保存在北桥。。。

16. 哦?尼玛太好了。那么请解释一下书上说的“PCIE设备在DMA的时候也只能使用PCIE总线地址,而且不能访问未被映射的地址空间”。
答:晕了。这完全颠覆了我的认知。PCIE设备应该是可以完全DMA主存的虚拟地址空间,但是如果BAR里如果只分配了1MB地址,按照“书”上说的,它和寻址4GB虚拟空间? “书”中的描述为何不能啰嗦和通俗一些呢?愁死了。

完。

评分

参与人数 1可用积分 +8 收起 理由
Godbach + 8 赞一个!

查看全部评分

论坛徽章:
1
水瓶座
日期:2013-09-28 21:40:25
2 [报告]
发表于 2013-12-23 19:20 |只看该作者
顶,这个问答形式不错,逻辑性、顺序性也很强。

11. IOMMU就是转门给设备用的MMU。CPU透过MMU来看Memory, Device则通过IOMMU来看Memory。至于为啥不直接用已有的MMU,我想到了三点原因,供大家讨论:一是MMU可以和CPU Cache进行关联做一些优化,但是设备IOMMU基本上目前没这个需求;二是连个MMU可以将同一地址映射到CPU和设备的不同虚地址上;三是TLB条目的索引方式不太相同,MMU跟进程关联,而IOMMU基本上跟设备ID关联。

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
3 [报告]
发表于 2013-12-23 20:48 |只看该作者
本帖最后由 asuka2001 于 2013-12-23 20:53 编辑

回复 1# 冬瓜头

首先需要明白CPU域的物理地址空间和PCI域的地址空间的区别。而PCI域的地址空间又分成配置空间,内存地址空间,IO地址空间。

一般容易混淆的是CPU域的物理地址和PCI域的内存地址空间的地址,因为x86上它们数值上相等,因此很多时候就认为两者等同,其实是不同的。

比如32位的CPU域物理地址空间可能只有4G,但是PCI域的内存地址空间可以达到2^64大小。。。远远大于CPU域物理地址空间。

从CPU域物理地址空间到PCIE域的内存地址空间的映射,即将PCI设备的bar + size这么一段pcie域的内存地址空间映射到CPU域上对应数值的物理地址空间。

而从PCIE域的内存地址空间到CPU域物理地址空间的映射,则是iommu的工作。如果没有,那么同样是直接映射。

CPU发起访问是,使用的是自己的物理地址,通过pcie root complex转换成PCI域的内存地址空间的地址。而一旦在PCIE总线上,存在的寻址全部使用PCIE域的地址。

同样设备发起访问时,使用的是PCI域的地址,不会使用CPU域的物理地址。当有iommu时,就可以做到PCIE设备访问的是连续的PCI域的地址,但是通过iommu将它翻译为了不连续的CPU域物理地址。

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:49:45IT运维版块每日发帖之星
日期:2016-07-29 06:20:00
4 [报告]
发表于 2013-12-23 23:51 |只看该作者
asuka2001 发表于 2013-12-23 20:48
回复 1# 冬瓜头

首先需要明白CPU域的物理地址空间和PCI域的地址空间的区别。而PCI域的地址空间又分成配 ...


谢谢,已明白了地址翻译。请教一下,PCIE回访主存,是否可以超出BAR内的地址范围访问?

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
5 [报告]
发表于 2013-12-24 08:59 |只看该作者
回复 4# 冬瓜头

可以,之所以需要os设置bar,是因为CPU域的物理地址空间有限,而且不能产生冲突。

而PCI域的地址空间大,专属于pci设备。完全可以将CPU域的物理地址空间整个映射进来(因为是直接映射,内存等占据的PCI域地址空间必然不会有PCI设备占据)


   

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17
6 [报告]
发表于 2013-12-24 09:33 |只看该作者
mmio和dma的理解是不对的

mmio是寄存器, 为了给cpu访问的; dma是内存, 为了给dev访问的。 二者完全不相干。

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:49:45IT运维版块每日发帖之星
日期:2016-07-29 06:20:00
7 [报告]
发表于 2013-12-24 11:57 |只看该作者
asuka2001 发表于 2013-12-24 08:59
回复 4# 冬瓜头

可以,之所以需要os设置bar,是因为CPU域的物理地址空间有限,而且不能产生冲突。


请问这个把PCIE空间映射到主存空间的过程,是否在内核代码里有体现?或者说因为x86是简单的相等关系,所以写死了不需要代码做什么事情了?下面的输出中并没有找到这种反向映射关系。。


01:00.0 Serial Attached SCSI controller: Adaptec Device 8088 (rev 06)
        Subsystem: Adaptec Device 0800
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0, Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 16
        Region 0: Memory at f7d50000 (64-bit, non-prefetchable) [size=64K]
        Region 2: Memory at f7d40000 (64-bit, non-prefetchable) [size=64K]
        Region 5: Memory at f7d00000 (32-bit, non-prefetchable) [size=256K]
        Expansion ROM at f7c00000 [disabled] [size=1M]
        Capabilities: [80] Power Management version 3
                Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [88] Vital Product Data
                Unknown large resource type 20, will not decode more.
        Capabilities: [90] MSI: Enable- Count=1/32 Maskable+ 64bit+
                Address: 0000000000000000  Data: 0000
                Masking: 00000000  Pending: 00000000
        Capabilities: [b0] MSI-X: Enable+ Count=64 Masked-
                Vector table: BAR=0 offset=00000400
                PBA: BAR=0 offset=00000800
        Capabilities: [c0] Express (v2) Endpoint, MSI 00
                DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <4us, L1 <1us
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset+
                DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
                        RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+ FLReset-
                        MaxPayload 256 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr- TransPend-
                LnkCap: Port #0, Speed unknown, Width x8, ASPM L0s L1, Latency L0 <1us, L1 <1us
                        ClockPM- Surprise- LLActRep- BwNot-
                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed unknown, Width x8, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range B, TimeoutDis+
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
                LnkCtl2: Target Link Speed: Unknown, EnterCompliance- SpeedDis-, Selectable De-emphasis: -6dB
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance De-emphasis: -6dB
                LnkSta2: Current De-emphasis Level: -6dB
        Capabilities: [100] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UESvrt: DLP+ SDES+ TLP+ FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
                AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
        Capabilities: [150] Device Serial Number 00-00-00-00-00-00-00-00
        Capabilities: [160] Power Budgeting <?>
        Capabilities: [1b0] Latency Tolerance Reporting
                Max snoop latency: 0ns
                Max no snoop latency: 0ns
        Capabilities: [1c0] #16
        Capabilities: [274] Transaction Processing Hints
                Interrupt vector mode supported
                Device specific mode supported
                Steering table in TPH capability structure
        Capabilities: [300] #19
        Capabilities: [400] Vendor Specific Information <?>

论坛徽章:
1
水瓶座
日期:2013-09-28 21:40:25
8 [报告]
发表于 2013-12-24 12:29 |只看该作者
回复 6# 帅绝人寰


    mmio不应该局限为寄存器,设备上的Memory也可以通过mmio来访问,比如PCIE显卡的显存。

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
9 [报告]
发表于 2013-12-24 13:11 |只看该作者
回复 7# 冬瓜头

额抱歉,这里说错了,真正设置bar的不是os而是bios。os做pci总线枚举时已经是直接利用bios设置完毕的成果了!

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:49:45IT运维版块每日发帖之星
日期:2016-07-29 06:20:00
10 [报告]
发表于 2013-12-24 13:56 |只看该作者
asuka2001 发表于 2013-12-24 13:11
回复 7# 冬瓜头

额抱歉,这里说错了,真正设置bar的不是os而是bios。os做pci总线枚举时已经是直接利用b ...


我理解不是的。Linux 0.11之后的内核都是内核自行初始化,完全不依靠BIOS,BIOS那块内存直接被内核回收了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP