免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6884 | 回复: 18

为什么PCI桥的枚举用这样一种奇怪的顺序? [复制链接]

论坛徽章:
0
发表于 2007-10-25 17:13 |显示全部楼层
初始状态:PCI桥的树中,BIOS已经初始化了部分PCI桥,分配了总线号;另一部分,BIOS未初始化,需kernel来分配总线号。

那么,我们需要做的,是两次深度优先遍历PCI桥的树。
第一次: 一旦遇到BIOS未初始化的PCI桥,既向上返回一层,目的是统计BIOS分配到的最大总线号;
第二次: 一旦遇到BIOS已初始化的PCI桥,既向下深入一层,目的是继续分配总线号;

既两次遍历,但每个节点只处理一次,要么在第一次中被统计,要么在第二次中被分配总线号。


但是kernel不是这么做的,它只是一次遍历PCI桥的树。
pci_do_scan_bus中的两次遍历只是个假象,因为pass是个局部变量,只有当子节点的两遍都完成后才向上返回父节点。

我画了一个图,对PCI桥的结构做了一些简化,希望更突出本质问题。

圆圈表示BIOS已初始化的PCI桥;
黑蛋表示BIOS未初始化,需要kernel来初始化的PCI桥;
数字表示递归的各层中pass的值,如“112”表示递归进行到了第三层。并且第一层中pass==1,第二层中pass==1,第三层中pass==2。

kernel遍历的过程是这样的:1(统计) -->11(统计) -->111(统计) --> 112(分配) -->12(分配) -->122(分配) --> 122(分配) --> 2(分配).................................

这棵树只被遍历了一次,而且112,12,122,122时,为PCI桥分配总线号都是错误的。因为在我画的图中,右子树全部是黑蛋,但是实际情况中,右子树完全可能都是圆圈,既还有BIOS已分配的总线号未统计上来。这样,在统计完右子树之前,就为左子树中的黑蛋分配了总线号。完全可能造成总线号重复的情况。

只有在2,22,222时,既递归的每层中,pass都等于2时,才能证明已经遍历了所有圆圈,统计出来黑蛋应该使用那些总线号。

[ 本帖最后由 motalelf 于 2007-10-25 17:20 编辑 ]
litter.gif

论坛徽章:
0
发表于 2007-10-25 17:21 |显示全部楼层
抱歉,我的绘画造诣有待提高~~~~~

论坛徽章:
0
发表于 2007-10-25 19:56 |显示全部楼层
原帖由 motalelf 于 2007-10-25 17:21 发表
抱歉,我的绘画造诣有待提高~~~~~

本来想说的。。。老兄的逻辑思维远强与形象思维哦

论坛徽章:
0
发表于 2007-10-25 22:47 |显示全部楼层
这个问题我也一直没搞懂。如果bios初始化了某个pci桥,以该桥为根的子树中所有的pci桥都应被bios初始化,否则内核不能正确地设置总线号

论坛徽章:
0
发表于 2007-10-26 08:46 |显示全部楼层
所以是否有一种约定,bios要么一个都不初始化,要么全部初始化?bios不应该执行随机的初始化吧

论坛徽章:
0
发表于 2007-10-26 14:34 |显示全部楼层
原帖由 motalelf 于 2007-10-25 17:13 发表
初始状态:PCI桥的树中,BIOS已经初始化了部分PCI桥,分配了总线号;另一部分,BIOS未初始化,需kernel来分配总线号。

那么,我们需要做的,是两次深度优先遍历PCI桥的树。
第一次: 一旦遇到BIOS未初始化的 ...

这样的顺序lz是怎么的来的?
BIOS扫描总线时会枚举所有设备,为它们分配资源。不会枚举几个,剩几个不枚举。
操作系统通常是不需要再去扫描总线的,通常他们都用BIOS的配置。只有当有热插拔的设备时,OS才会重新扫描总线,对重新MMIO空间排序分配空间,以避免过多的热插拔造成的hole。同样,扫描的时候也是全枚举。

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
发表于 2007-10-26 15:42 |显示全部楼层
我是指的在开机时的哪次扫描,假设我们的机器中不存在热插拔。

BIOS可能确实有未完全枚举的情况存在,否则pci_scan_bridge这个函数就失去了意义。这个函数有对PCI_BUS分配总线号的操作,如果BIOS完全枚举,何必分配,只要单纯的读BIOS分配值就好了

论坛徽章:
0
发表于 2007-10-26 17:15 |显示全部楼层
>>只有当有热插拔的设备时,OS才会重新扫描总线,对重新MMIO空间排序分配空间,以避免过多的热插拔造成的hole。

it's not the case.     pci_do_scan_bus的声明中有__init,这个函数是在开机初始化时才执行

论坛徽章:
0
发表于 2007-10-26 23:03 |显示全部楼层
原帖由 塑料袋 于 2007-10-26 15:42 发表
我是指的在开机时的哪次扫描,假设我们的机器中不存在热插拔。

BIOS可能确实有未完全枚举的情况存在,否则pci_scan_bridge这个函数就失去了意义。这个函数有对PCI_BUS分配总线号的操作,如果BIOS完全枚举,何 ...

我不知道BIOS在什么时候有未完全枚举的情况,实际上我认为BIOS在扫描总线的时候会枚举所有设备并填写设备的configure space来分配资源。OS只要使用BIOS分配的资源即可。
pci_scan_bridge并非是在系统引导时候使用的,它是一个内核导出的函数,应该是提供个dirver在需要重新扫描总线时使用的,我们可以在几个driver中看到它的身影,例如drivers\pci\hotplug\Acpiphp_glue.c 。

论坛徽章:
0
发表于 2007-10-26 23:05 |显示全部楼层
原帖由 gta 于 2007-10-26 17:15 发表
>>只有当有热插拔的设备时,OS才会重新扫描总线,对重新MMIO空间排序分配空间,以避免过多的热插拔造成的hole。

it's not the case.     pci_do_scan_bus的声明中有__init,这个函数是在开机初始化时才执行

pci_do_scan_bus的关键字是__devinit,它应该是提供给dirver使用而非内核引导时用的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP