- 空间积分
- 0
- 信誉积分
- 239
- UID
- 7526085
- 阅读权限
- 50
- 积分
- 2288
- 帖子
- 9971
- 精华
- 1
- 可用积分
- 2288
- 专家积分
- 47
- 在线时间
- 1469 小时
- 注册时间
- 2004-12-28
- 最后登录
- 2012-02-03
 
- 帖子
- 9971
- 主题
- 1233
- 精华
- 1
- 可用积分
- 2288
- 专家积分
- 47
- 在线时间
- 1469 小时
- 注册时间
- 2004-12-28
- 最后登录
- 2012-02-03
- 论坛徽章:
- 0
|
发表于 2009-04-13 11:01:29
|显示全部楼层
<pci体系结构>这本书里讲的很清楚了.
第一次写进去的全一,读出来为非1,那么高几位连续的1就是可编程的,首先他代表了映射区域的最小"分片",这个写的过程其实也是在编程BAR,既是说已经把设备内存做了一次映射,而且是映射到最大的可能地址.从而这个写-读的过程是不应该出现在系统后期的,否则他改变了系统的总线地址(或物理地址),很容易发生地址冲突.
知道几个为1的位后就可以对它编程写入其他值,这些值就是从新设置新的起始地址,由于其他位不可编程,当然起始地址就是个离散值.
那些为0的位实际上是硬件电路接发直接定死的.
为什么是2G呢?所有的设备是都用同一4G的存储空间,那么最大就是2G一个段了,因为如果是4G的话,就没必要用PCI总线了,一个设备已经独占了4G.
从而linux代码对总线的操作和PCI BIOS没有本质不同.
原帖由 Solaris12 于 2009-3-17 00:06 发表 
OpenSolaris的add_reg_props的代码就是这么做的。
OpenSolaris的add_reg_props函数里,首先是将BAR读出备份,然后写全1,然后读,结果存在value里,再将备份BAR写回,
/* determine ...
通常是是物理地址,我想如果动态的改BAR也可以,不过之前做的很多工作要从新做.
最起码的是在重新探测的过程不能执行存储器和IO的交易.
不过不明白你说的机器地址是什么意思.
[ 本帖最后由 epegasus 于 2009-4-13 12:50 编辑 ] |
|