免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 57968 | 回复: 71

还是不理解IOMMU、北桥、PCI的MMIO和ioremap [复制链接]

论坛徽章:
0
发表于 2008-03-23 17:20 |显示全部楼层
(albcamus案:
作者原题目是:《 还是不太理解mmu和io-map》
修改一下,以符合主要的讨论内容)

该看哪些资料呢?

[ 本帖最后由 albcamus 于 2009-3-27 17:43 编辑 ]

论坛徽章:
0
发表于 2008-03-23 17:51 |显示全部楼层
原帖由 epegasus 于 2008-3-23 17:20 发表
该看哪些资料呢?

我论文终于写完了啦!!!!!!!狂欢喜中,这两个月被这个烦死了!
发个链接,这个是intel的iommu的spec
http://download.intel.com/technology/computing/vptech/Intel(r)_VT_for_Direct_IO.pdf

心情愉快,大概讲一下IOMMU是个啥东西。 注意我说的IOMMU是指位于北桥上的IOMMU,那种设备自带IOMMU的情况我还不了解。
在没有IOMMU的情况下,设备(指32bit或64bit设备,老的16bit的不提)的DMA操作可以访问整个物理地址空间,所以理论上设备可以向操作系统的代码段、数据段等内存区域做DMA,从而破坏整个系统。当然,通常来说不会有这样的设备。IOMMU的出现,可以实现地址空间上的隔离,使设备只能访问规定的内存区域。下面简要说一下intel的IOMMU怎么做到这点的:
目前PC架构最多有256PCI总线,于是IOMMU用一个称为root entry的数据结构描述PCI总线,总共256个root entry构成一张表。每条PCI总线最多允许256个设备,IOMMU用context entry描述一个PCI设备(或者是PCI桥),256个context entry构成一张表。所以就有了如图的关系。我们知道,PCI设备用 {BUSEV:FUNC}(当然,还有个segment,不过似乎PC架构都只有一个segment,这个暂时忽略)描述一个设备。所以对于一个特定设备,用bus号做索引root entry表,用dev号索引context entry表可以找到描述该设备的的context entry。context entry中有一个指针指向一章I/O页表,当设备发起DMA操作时,IOMMU会根据该页表把设备的DMA地址转换成该设备可以访问内存区域的地址。
所以只要为设备建一张I/O页表,就可以使设备只能访问规定的内存区域了。当然,也可以把该页表当成跳板,让只能寻址32bit地址空间的设备访问到64bit地址空间中去。

大概就是这么回事了,似乎写的有点乱,具体问题看spec。
rootentry.jpg

论坛徽章:
0
发表于 2008-03-23 18:32 |显示全部楼层
原帖由 zx_wing 于 2008-3-23 17:51 发表

我论文终于写完了啦!!!!!!!狂欢喜中,这两个月被这个烦死了!
发个链接,这个是intel的iommu的spec
http://download.intel.com/technology/computing/vptech/Intel(r)_VT_for_Direct_IO.pdf

心情 ...

IOMMU对于虚拟化技术由重要的应用,
其中最重要的功能是DMA remapping,
使得外部设备可以如同虚拟机一样使用客户物理地址进行寻址,
这样做就避免了当前I/O虚拟化中常常使用的技术如Xen的split driver model以及device emulation.
另外IOMMU的可以与硬件辅助的内存虚拟化共享页表层次,
大大简化了hypervisor/VMM的设计.
(AMD的IOMMU有一个有趣的特性:其本身就具有可已被虚拟化)

[ 本帖最后由 crspo 于 2008-3-23 18:38 编辑 ]

论坛徽章:
0
发表于 2008-03-24 09:14 |显示全部楼层

回复 #2 zx_wing 的帖子

先加个精华,方便以后找。

不过老大, 我怀疑楼主是问MMU和ioremap ^_^

论坛徽章:
0
发表于 2008-03-24 09:45 |显示全部楼层
如果是一般的mmu管理和ioremap我就不敢麻烦各位老大了。。情景分析和intel 手册上有够详尽的讲解。
我正是为zx_wing 讲的那个困惑,我以前只知道可以通过pci_read_config_dword之类可以读写pci设备上的寄存器,而设备上如果有eeprom之类的东西,那又是如何操作的呢?总不能把pci_read_config_dword这个拿来做ioremap吧。
不过zx_wing 讲的还是不太懂看来要努力了。。
还有,老大可否在答辩后,把论文贴上来,给大家学习?

[ 本帖最后由 epegasus 于 2008-3-24 10:31 编辑 ]

论坛徽章:
0
发表于 2008-03-24 10:57 |显示全部楼层
原帖由 epegasus 于 2008-3-24 09:45 发表
如果是一般的mmu管理和ioremap我就不敢麻烦各位老大了。。情景分析和intel 手册上有够详尽的讲解。
我正是为zx_wing 讲的那个困惑,我以前只知道可以通过pci_read_config_dword之类可以读写pci设备上的寄存器, ...

pci_read_config_dword印象中是用于读取PCI设备的配置空间,主要用于PCI设备的枚举和配置。
ioremap应该是用作mmio,与configure space概念上有所区别。

论坛徽章:
0
发表于 2008-03-24 12:50 |显示全部楼层
原帖由 epegasus 于 2008-3-24 09:45 发表
如果是一般的mmu管理和ioremap我就不敢麻烦各位老大了。。情景分析和intel 手册上有够详尽的讲解。
我正是为zx_wing 讲的那个困惑,我以前只知道可以通过pci_read_config_dword之类可以读写pci设备上的寄存器, ...

汗,这几个问题就真和IOMMU没有关系了。
如crspo所说,pci_read_config_dword是用于读取PCI设备的配置空间的,不是读寄存器的。PCI配置空间的具体信息你可以baidu一下,我就不打字了,但对于上层软件,它最主要的用处是提供interrupt line和PCI bar(PCI base address register)。PCI bar就是该设备可用port i/o和mmio访问的寄存器的基地址。除了寄存器,还有一种称为扩展rom,也是通过mmio访问的。而ioremap的作用就是把pci bar(pci bar是物理地址)映射到虚拟地址空间中。所以它和pci_read_config_dword是下列关系:

pci_read_config_dword得到PCI bar ----> ioremap映射PCI bar到虚拟地址空间, 返回一个虚拟地址,以后通过该地址读写设备的寄存器

上面的内容和IOMMU都没有关系,软件对设备的port I/O和MMIO都不经过IOMMU,访问方式和以前是一样的,见这个帖子http://bbs.chinaunix.net/viewthr ... p;extra=&page=1

IOMMU是对于设备发起DMA操作来说的,你可以理解成设备用于做DMA的地址是一个虚拟地址(这个虚拟地址和我们平时说的那个不一样,是指设备DMA用的地址不是真实的物理地址,没有IOMMU的情况下用的是物理地址)。也有称这个虚拟地址为总线地址的,但我认为不恰当,容易让人误解。

对于eeprom的访问,它又和mmio还有iommu都没有关系。eeprom是个串行设备,它不是被ioremap到虚拟地址空间访问,而是通过PCI bar报告一个eeprom寄存器给操作系统,这个寄存器有一个bit的di(data in)、一个bit的do(data out)、一个bit的clk(时钟)。时钟在下降沿生效,写的时候通过di一个bit一个bit的写,读的时候通过do一个bit一个bit的读。

论文等我答辩完吧,写的很烂的,基本没讲啥子细节,就想糊弄过关。

[ 本帖最后由 zx_wing 于 2008-3-24 12:51 编辑 ]

论坛徽章:
0
发表于 2008-03-24 12:56 |显示全部楼层
原帖由 albcamus 于 2008-3-24 09:14 发表
先加个精华,方便以后找。

不过老大, 我怀疑楼主是问MMU和ioremap ^_^

LZ的帖子原来就叫“ 还是不太理解mmu和io-map”吗!!!???
我怎么记得昨天问的是IOMMU呢,完了,肯定是写论文写傻了,看成IOMMU了。
如果是的话,LZ把关于IOMMU的内容去掉不看,免得干扰。。。汗

论坛徽章:
0
发表于 2008-03-24 12:57 |显示全部楼层
感觉ioremap的用处主要在于为设备内存建立页表 返回可供内核访问的虚拟地址 驱动里面常用
pci_read_config_dword好像用的很少  按照ldd说法就是拿来访问配置空间的
具体也不清楚  搬板凳学习

论坛徽章:
0
发表于 2008-03-24 14:40 |显示全部楼层
zx_wing 老大可否就这段代码讲解一下?

phymem = pci_resource_start(pdev, 0);
    if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "eth")) {
        printk(KERN_ERR "eth_pci: cannot reserve PCI memory region\n");
        goto bad;
    }

    mem = (unsigned long) ioremap(phymem, pci_resource_len(pdev, 0));
    if (!mem) {
        printk(KERN_ERR "eth_pci: cannot remap PCI memory region\n") ;
        goto bad1;
    }
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP