Linux那些事儿 之 我是PCI(1)PCI,我们来了
来源:互联网 发布:笔记本强制散热软件 编辑:程序博客网 时间:2024/05/14 23:20
现在这段时间最火的工程是什么?当然不会是PCI这个系统工程了,你即使不是党员也总归是个中国人,是中国人都要毫不犹豫的回答“探月工程”。不过,如果你在两年前就这么问我的话,俺会面带羞涩的回答你,是“中国芯工程”,谁让汉芯偏偏就是俺们交大的那,谁让汉芯又偏偏是假的那,俺无法回答你,俺陈进手下的哥们儿也无法回答你。到现在俺还依稀记得,在2002年的那个秋天,俺刚到交大就遇到陈进时的情景,旁边儿一见多识广的哥们儿指着一个瘦高瘦高文质彬彬的帅哥说:“看,那小伙儿就是陈进,搞汉芯的,博导,大牛!”俺无比激动的望过去,差点崇拜的华丽丽的摔倒,就没诚想到了05年就什么都成假的了,这要放到宪哥的节目里,肯定是最难的一期真的假不了。不过搞计算机的再怎么敢玩儿虚的,搞航空航天的都不敢这么玩儿,所以说一会儿航天飞机一会儿探月工程,和那个中国芯工程比起来是冰火两重天,特提神儿。
Greg大侠没那么媚俗,对这种小图片儿提不起兴趣,在LDD3里也就将它给一笔带过了,俺不同,本就是大俗人一个,所以这里替他展开来说一下。其实这张图是非常偷工减料的,并不足以揭示整个PCI系统的细节,但说明问题还是足够了。里面的几个Bridge,也就是桥,是用来将多个PCI总线,或者PCI总线与ISA等其它总线连接起来的东东。各种桥里比较特殊的一个是Host Bridge,它连接的是CPU和PCI总线0,说Host Bridge你可能丈二摸不着头脑,但是说北桥你就明白了,不然你都不好意思说你会玩儿电脑,更别说会玩儿linux了,有北桥自然就有南桥,大名鼎鼎的南北桥谁都知道,就像在江湖上行走的都得知道南北少林一样。而南北桥合起来就叫做芯片组,芯片组里距CPU最近的一个就是北桥,它是位于天子脚下呼风唤雨的重臣。北桥里通常还集成着内存控制器,所以CPU和内存之间的交流也要依靠它来完成,如果是那种集成显卡的板子,显示芯片也要呆在它里边儿。CPU和北桥之间的连接靠的是FSB,就是俗称前端总线的那个,FSB的速度即是咱们通常所说的外频,外频的高低直接影响了CPU对内存的存取。基于北桥的这种显赫的江湖地位,江湖里一般尊称它为Host Bridge,也就是主桥。实际上,芯片组的名称就是以北桥的名称来命名的,像intel 875P芯片组的北桥芯片是82875P等等。那么上边儿图里的哪个桥对应着南桥那?左瞅瞅右看看,还就ISA Bridge有点像,一般来说,PCI-ISA桥就称为南桥,但它并不是仅仅是为了连接PCI总线和ISA总线这么简单,它里边儿会集成很多东东,比如中断控制器、IDE控制器、DMA控制器等,咱们在USB那块大书特书的USB控制器一般也集成在它里边儿。
明白了Host Bridge,再看看PCI bus0,也就是primary PCI bus,主PCI总线。至于有没有PCI bus1,PCI bus2等等俺不好说,但是只要你的系统里有PCI总线,这个PCI bus0总是得存在的。一个系统自然是可以拥有多个PCI总线的,这多个PCI总线之间的连接要靠另外一种桥,PCI-PCI桥。通过PCI-PCI桥,整个PCI系统就构成了一个层次的、树状的结构,类似的树咱们在讲USB Core时就遇到过了,不过不同的是USB那棵大树是靠HUB搭建的,而这里的PCI树是靠PCI-PCI桥搭建的,日后再有人问你“这是什么树?”,你就不能仅仅回答“大树”了,要拍拍胸脯慷慨激昂的回答“USB树”或者“PCI树”。就像HUB同时也是USB设备一样,PCI-PCI桥、CardBus桥等等这些五花八门的桥也都是PCI设备,当然,不用我说你也知道,PCI设备不仅仅是指这些桥。每个PCI总线上都可以支持32个PCI设备,每个设备又可以支持8种功能,不要被设备和功能这两个词儿给绕晕了,这里所谓的设备一般指那种PCI接口卡,更确切的说是指PCI总线的接口芯片,每块PCI接口卡上可以有若干个功能模块,它们共用了同一个PCI接口芯片,这样可以降低成本,满足节约型社会的要求。从逻辑的角度说,每个功能模块都是一个逻辑设备,既然都说是逻辑了,自然就只能意会不能言传了。江湖上将只拥有一个功能模块(逻辑设备)的设备称为单功能设备,拥有多个的就称为多功能设备,当然再多不能多过8个。
这么多的PCI设备,不管它是桥,还是其它的,都必须得有那张表示配置寄存器的表,表当然是要拿来用的,要想将它给拿出来,就得去访问设备,可事实是系统一开始只有那条PCI bus0能够访问,其它的PCI总线和设备一切都还是未知,那么如何才能使未知变成已知?这就又回归到前面的问题“总线枚举”了。系统引导时,对于PCI子系统来说,会首先有个总线枚举的阶段,从PCI bus0开始扫描,遇到一个设备是PCI-PCI桥,就指定一个新的总线号,比如1,这样PCI bus1就有了,也就可以访问了,如果遇到一个其它PCI设备,也要将它记录在案,直到将所有的PCI-PCI桥和PCI设备给晾出来,组成一棵PCI树,不过现在这个树是软件意义上的,前面刚提到的那棵PCI树是硬件意义上的。
经过这么一个漫长曲折的总线枚举过程,PCI树就从只有PCI bus0这么一个小牙儿长成了枝枝丫丫的参天大树,树里每个设备的那张配置寄存器的内容也明明白白的晾在那里了,而且,里面的一些内容,比如中断线什么的也给酌情设置好了,该映射的地址也都给映射了,总之,往白了说,总线枚举的过程就是内核里的PCI树成长的过程。大树底下好乘凉,有了这么一棵大树,写PCI驱动的才能吃的香睡的沉。
已经绕了大老远的了,也该绕回去了,这个总线枚举和PCI access mode又有嘛关系?这还要再说说PCI BIOS。基于PCI总线在整个计算机世界里特殊的江湖地位,BIOS中也专门提供了针对PCI总线的操作,这些操作里就包括了总线枚举的整个过程。在系统加电以后自检时,就会完成对PCI总线的枚举,之后对PCI设备的访问就都是通过BIOS调用的形式进行,提供有这些功能和服务的BIOS就称之为PCI BIOS。其实这就是PCI access mode里的那个BIOS选项所表达的意思,但是,一些旧的主板上,BIOS并不买PCI的账,不支持这么做,还有一些嵌入式系统里甚至于根本就没有BIOS的存在,为了适应各种革命形式的需要,linux就自己实现了包括总线枚举在内的一整套PCI总线操作,而不再去依赖BIOS,这就是那个Direct选项的由来。当然在64位的平台上,是没有什么PCI BIOS的,采用的总是Direct方式,你使用make menuconfig配置内核的时候也就根本看不到有PCI access mode这么一项给你选。提到这里,顺便说一下,俺的机子还不是64位的,所以最开始使用make menuconfig得到的那张图,还有以后会讲到的与架构有关的代码都是针对32位平台的,但是里面的道道儿都是一样的。
至于MMConfig方式,是PCI Express才用得上的。关于PCI Express,俺这里的原则是,会提到,但不会过多的去关注它。不过这个MMConfig因为与Direct有着千丝万缕的关系,俺会在日后遇到合适的机会时去详细的说一下,这里暂时留下个悬念吧。
回到开篇的那张图,第三项是“PCI Express support”,它还有它下边儿紧接着的三项都是有关PCI Express的,选不选看你了,它们的细节就飘过了,但是PCI的进化历程还是有必要了解一下的。先看一看从PCI的老巢PCI SIG的主页上抓下来的一张图
这张图够婀娜多姿的,看来PCI SIG的那帮家伙和俺一样的媚俗,不过它到是很能形象的表示从PCI到PCI-X再到PCI Express这么一个PCI的发展历程,至于中间的那个IOV,即I/O VIRTUALIZATION,也就是江湖人称的那个I/O虚拟化技术,离咱们的主题差个十万八千里,我不用说,你也不用问,让它随风而去吧。至于这里所谓的PCI,往狭义里讲就是最初的传统的PCI规范,每种事物都有它存在的目的和意义,PCI就是为了替代ISA而生的,上世纪90年代初,在咱们这些人还在情窦初开暗恋小女生的时候,PCI一出现就统一了VESA、ISA等当时并存的多种I/O总线,来势不可谓不凶,它能够得到江湖老大的地位,当然有它的独到之处,它使用了比ISA更高的时钟频率,可以达到33MHz或66MHz,优势是显而易见的。但是随着历史车轮的向前推进,随着咱们从一个嘴上没毛的小屁孩儿长成一个嘴上有毛的小混混,仅仅暗恋已经不能满足内心的需求,这样的时钟频率也已经不能满足某些应用的需要,于是就衍生出来了PCI-X和AGP等这样的东东,但是PCI-X带来的复杂度和高成本并不符合节约型经济型社会的要求,所以PCI Express就顺应时代潮流,登上了历史舞台,至于PCI Express是靠什么上位的,八卦记者才会去关心这个,俺这里就飘过了。
接下来就是第四项,“Message Signaled Interrupts (MSI and MSI-X)”,关于MSI中断的。到了21世纪,什么都在爆炸,知识在爆炸,连满大街看到的发型都是爆炸式的,谁让咱们苦命那,反抗不了命运就只有接受这些无穷尽的名词儿吧。了解MSI之前,先普及一下中断。狭义的说,内核就是用来管理各种设备的,要管理就得需要交流,就得明白点儿管理的艺术掌握点儿管理的技巧,这个技巧有两种,一是轮询,定期的去探访设备,体恤设备的民情,看有没有什么需要处理的,就像逢年过节时要给低保户孤寡老人送温暖,不逢年过节时要给另外某些人送温暖一样。二是中断,设备需要的时候主动向内核发信号,通知内核说自己有需要了,快来满足我。对内核来说,这两种方式两种技巧,哪一种为优哪一种为劣?很明显,你说那么多孤苦伶仃的人要一个个定时定期的去嘘寒问暖,公仆们累不累,公仆也是人啊,而且这样也够低效,每次只能解决暂时的问题,局部的问题,同时也占用了公仆们大量的时间。而第二种方式就不一样了,哪个设备有需要了向上报告一声,内核就会明白设备的心声就会安排酌情处理。当然,现实是残酷的,形式是复杂的,公仆们可能更多的采用第一种方式,第二种方式使用起来就不是那么高效了,不过我们要理解,第一种方式已经耗费了他们大量的时间和精力,他们也是血肉之躯,嗯,我们要理解。
上边儿是从世俗的角度说的,现在再从物理的角度上看一看,中断就是一种电信号,设备在希望获得处理器关注的时候就可以发送这么一个信号,并直接送入中断控制器(如8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己手头儿的工作,转而去处理中断。此后,处理器会通知内核已经产生中断了,这样,内核就可以对这个中断进行适当的处理。内核要处理一个中断,也不是说只要这个中断产生就可以了,还需要一个对应的中断处理函数,不然就会像你的很多呼声一样石沉大海了。这个所谓的中断处理函数是需要提前注册好放在内核里边儿的,和特定的中断信号线绑定在一起,中断信号线就是标识每个中断的一个值,是比较稀缺的资源,属于重点保护对象。那么究竟稀缺到什么程度?这要看使用的是什么中断控制器。
俺只说X86上面儿的,常见的中断控制器一个是PIC,一个是APIC,PIC就是Programmable Interrupt Controller,可编程中断控制器的意思,那APIC就是高级可编程中断控制器,这种文字游戏咱们见得多了。PIC是由两片8259A级联在一起组成的,每个可以处理8个不同的IRQ,两个加一块儿8加8等于几?答16就错了,是15个,因为级联时还要去掉用于连接的那个。这么多设备嗷嗷待哺的总共才有15个中断请求线,你说稀缺不稀缺?
APIC就要好一点儿了,不然怎么敢称高级。PIC只能用于一个处理器的系统,在多处理器系统上,处理器之间也可能会产生中断,这种情况PIC就不能应对了。很好理解,谁说公仆们互相之间就不能有需要了?不然那句官官相护是怎么得来的?而APIC就能够用在多处理器的系统上,解决多个处理器之间的互相需要,同时它支持的中断请求线的数目也有了很大幅度的提高,可以达到255个,不过,即使这样,中断请求线仍然还是属于稀缺的需要保护的资源。当然,单处理器系统也是可以使用APIC的了,这个时候它虽然没有了处理器之间互相需要的情况,但对中断请求线总是多多益善的。不过,这样就产生了一个兼容性的问题,就像经济的发展离不开房地产,计算机的发展也离不开兼容,APIC就可以兼容PIC,按照标准的8259A的工作方式来工作,这要归咎于APIC的组织结构。
对于APIC来说,能够将中断传递给系统中的每个CPU至关重要,所以它通常都要包含两个部分,Local APIC和I/O APIC。系统中的每个CPU都会有一个Local APIC(那种超线程的CPU是不止包括一个Local APIC的),负责将中断信号传递到指定的处理器。而I/O APIC则负责收集中断信号并将它们转发给各个Local APIC,它也可以有多个。APIC就是这么一个多级的体系结构,如果要模拟8259A,只需要将Local APIC给禁止掉,再进行适当的配置,I/O APIC就可以按照PIC的工作方式工作了。你可以通过查看/proc/interrupts文件来获悉系统有没有在使用I/O APIC,
localhost:/usr/src/linux/ # cat /proc/interrupts
CPU0
0: 20565961 IO-APIC-edge timer
1: 3763 IO-APIC-edge i8042
6: 4 IO-APIC-edge floppy
7: 0 IO-APIC-edge parport0
8: 1 IO-APIC-edge rtc
9: 0 IO-APIC-level acpi
12: 3095 IO-APIC-edge i8042
15: 737432 IO-APIC-edge ide1
169: 11066 IO-APIC-level eth0
177: 0 IO-APIC-level uhci_hcd:usb1, es1371
185: 19441 IO-APIC-level ioc0
NMI: 0
LOC: 19332194
ERR: 0
MIS: 0
如果你在上面的结果里瞅见了IO-APIC这样的字眼,就说明你的系统正在使用APIC。
社会总是要向前发展的,咱们经济发展的支柱是房地产,同时还会有其它杂七杂八的柱子,北大经济学院的院长刘伟就说了:“我把堵车看成是一个城市繁荣的标志,是一件值得欣喜的事情。如果一个城市没有堵车,那它的经济也可能凋零衰败。1998年特大水灾刺激了需求,拉动增长,光水毁房屋就几百万间,所以水灾拉动中国经济增长1.35%。”那技术发展的支柱是什么?这个可以往现实的地方想也可以往高尚的地方想,反正总归不会是水灾了,不过不管它是什么,都不影响PCI Spec v2.2开始提出一种全新的中断方式,也就是前面看到的Message Signaled Interrupts,翻成中文咋看咋别扭,所以就原汁原味儿的使用英文名称了,还好它有个简短的简称MSI。MSI通过向一个预定义的内存地址写入一个已经预定义好的Message来提出中断请求,这个Message到达主桥时,主桥会将它转换为具体的中断,发送到处理器。对PCI设备来说,这就消除了对中断引脚电路的需要,但是PCI Spec里还是要求支持MSI的设备最好同时也要具有中断引脚。另外再友情提醒一下,你如果选上MSI,还得同时选上CONFIG_X86_LOCAL_APIC才能正常工作,如果你的CPU的datasheet上已经写明了没有实现APIC,那你也就不用再操心MSI了。至于MSI-X则是MSI的增强型,不予关心,飘过。
在MSI之后,紧接着的一项是“PCI Debugging”,调试用的。
下面一项,“Interrupts on hypertransport devices”,hypertransport是AMD在99年提出的一种总线技术,细节就不说了,飘过。
接下来与咱们讲的主题有关的就是最后一项的那个PCI Hotplug支持,道儿上混的都知道热插拔是嘛意思,那么PCI热插拔的意思也就是明摆着的。
加菲猫说过,每个成功男人的背后,都有一个女人,每个不成功男人的背后,都有两个,每个menuconfig的背后都有无数个Kconfig,按照习俗,开篇那张图背后的那些个Kconfig应该到drivers/pci目录下去找,
1 #
2 # PCI configuration
3 #
4 config ARCH_SUPPORTS_MSI
5 bool
6 default n
7
8 config PCI_MSI
9 bool "Message Signaled Interrupts (MSI and MSI-X)"
10 depends on PCI
11 depends on ARCH_SUPPORTS_MSI
12 help
13 This allows device drivers to enable MSI (Message Signaled
14 Interrupts). Message Signaled Interrupts enable a device to
15 generate an interrupt using an inbound Memory Write on its
16 PCI bus instead of asserting a device IRQ pin.
17
18 Use of PCI MSI interrupts can be disabled at kernel boot time
19 by using the 'pci=nomsi' option. This disables MSI for the
20 entire system.
21
22 If you don't know what to do here, say N.
23
24 config PCI_DEBUG
25 bool "PCI Debugging"
26 depends on PCI && DEBUG_KERNEL
27 help
28 Say Y here if you want the PCI core to produce a bunch of debug
29 messages to the system log. Select this if you are having a
30 problem with PCI support and want to see more of what is going on.
31
32 When in doubt, say N.
33
34 config HT_IRQ
35 bool "Interrupts on hypertransport devices"
36 default y
37 depends on PCI && X86_LOCAL_APIC && X86_IO_APIC
38 help
39 This allows native hypertransport devices to use interrupts.
40
41 If unsure say Y.
这么短短数十行就是drivers/pci/Kconfig文件的全部内容,它只包括了寥寥几项,远远不能涵盖那张图里的内容,像PCI access mode等项都没在这里边儿提到。咋办?到arch/i386/Kconfig文件里找,当然,如果你的平台不是X86 32位的,就要到arch目录下对应的子目录里找了。下面就看下它里边儿与前面所讲有关系的那些内容
1058 menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
1059
1060 config PCI
1061 bool "PCI support" if !X86_VISWS
1062 depends on !X86_VOYAGER
1063 default y if X86_VISWS
1064 select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
1065 help
1066 Find out whether you have a PCI motherboard. PCI is the name of a
1067 bus system, i.e. the way the CPU talks to the other stuff inside
1068 your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
1069 VESA. If you have PCI, say Y, otherwise N.
1070
1071 The PCI-HOWTO, available from
1072 <http://www.tldp.org/docs.html#howto>, contains valuable
1073 information about which PCI hardware does work under Linux and which
1074 doesn't.
1075
1076 choice
1077 prompt "PCI access mode"
1078 depends on PCI && !X86_VISWS
1079 default PCI_GOANY
1080 ---help---
1081 On PCI systems, the BIOS can be used to detect the PCI devices and
1082 determine their configuration. However, some old PCI motherboards
1083 have BIOS bugs and may crash if this is done. Also, some embedded
1084 PCI-based systems don't have any BIOS at all. Linux can also try to
1085 detect the PCI hardware directly without using the BIOS.
1086
1087 With this option, you can specify how Linux should detect the
1088 PCI devices. If you choose "BIOS", the BIOS will be used,
1089 if you choose "Direct", the BIOS won't be used, and if you
1090 choose "MMConfig", then PCI Express MMCONFIG will be used.
1091 If you choose "Any", the kernel will try MMCONFIG, then the
1092 direct access method and falls back to the BIOS if that doesn't
1093 work. If unsure, go with the default, which is "Any".
1094
1095 config PCI_GOBIOS
1096 bool "BIOS"
1097
1098 config PCI_GOMMCONFIG
1099 bool "MMConfig"
1100
1101 config PCI_GODIRECT
1102 bool "Direct"
1103
1104 config PCI_GOANY
1105 bool "Any"
1106
1107 endchoice
1108
1109 config PCI_BIOS
1110 bool
1111 depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
1112 default y
1113
1114 config PCI_DIRECT
1115 bool
1116 depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
1117 default y
1118
1119 config PCI_MMCONFIG
1120 bool
1121 depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
1122 default y
1123
1124 source "drivers/pci/pcie/Kconfig"
1125
1126 source "drivers/pci/Kconfig"
1127
1128 config ISA_DMA_API
1129 bool
1130 default y
1131
1132 config ISA
1133 bool "ISA support"
1134 depends on !(X86_VOYAGER || X86_VISWS)
1135 help
1136 Find out whether you have ISA slots on your motherboard. ISA is the
1137 name of a bus system, i.e. the way the CPU talks to the other stuff
1138 inside your box. Other bus systems are PCI, EISA, MicroChannel
1139 (MCA) or VESA. ISA is an older system, now being displaced by PCI;
1140 newer boards don't support it. If you have ISA, say Y, otherwise N.
1141
1142 config EISA
1143 bool "EISA support"
1144 depends on ISA
1145 ---help---
1146 The Extended Industry Standard Architecture (EISA) bus was
1147 developed as an open alternative to the IBM MicroChannel bus.
1148
1149 The EISA bus provided some of the features of the IBM MicroChannel
1150 bus while maintaining backward compatibility with cards made for
1151 the older ISA bus. The EISA bus saw limited use between 1988 and
1152 1995 when it was made obsolete by the PCI bus.
1153
1154 Say Y here if you are building a kernel for an EISA-based machine.
1155
1156 Otherwise, say N.
1157
1158 source "drivers/eisa/Kconfig"
1159
1160 config MCA
1161 bool "MCA support" if !(X86_VISWS || X86_VOYAGER)
1162 default y if X86_VOYAGER
1163 help
1164 MicroChannel Architecture is found in some IBM PS/2 machines and
1165 laptops. It is a bus system similar to PCI or ISA. See
1166 <file:Documentation/mca.txt> (and especially the web page given
1167 there) before attempting to build an MCA bus kernel.
1168
1169 source "drivers/mca/Kconfig"
1170
1171 config SCx200
1172 tristate "NatSemi SCx200 support"
1173 depends on !X86_VOYAGER
1174 help
1175 This provides basic support for National Semiconductor's
1176 (now AMD's) Geode processors. The driver probes for the
1177 PCI-IDs of several on-chip devices, so its a good dependency
1178 for other scx200_* drivers.
1179
1180 If compiled as a module, the driver is named scx200.
1181
1182 config SCx200HR_TIMER
1183 tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
1184 depends on SCx200 && GENERIC_TIME
1185 default y
1186 help
1187 This driver provides a clocksource built upon the on-chip
1188 27MHz high-resolution timer. Its also a workaround for
1189 NSC Geode SC-1100's buggy TSC, which loses time when the
1190 processor goes idle (as is done by the scheduler). The
1191 other workaround is idle=poll boot option.
1192
1193 config K8_NB
1194 def_bool y
1195 depends on AGP_AMD64
1196
1197 source "drivers/pcmcia/Kconfig"
1198
1199 source "drivers/pci/hotplug/Kconfig"
1200
1201 endmenu
Kconfig的语法在Documentation/kbuild/kconfig-language.txt里,挺直白挺简单,也挺有意思的,1058行的menu就表示生成一个下级菜单,这个菜单的内容直到1201行的endmenu结束。1076的choice到1107的endchoice就生成了一个“PCI access mode”的单项选择题。每个config都生成一个菜单项。1126行的source就将前面的drivers/pci/Kconfig文件内容导入到这里边儿。
- Linux那些事儿 之 我是PCI(1)PCI,我们来了
- Linux那些事儿 之 我是PCI(1)PCI,我们来了
- Linux那些事儿之我是UHCI(2)PCI,我们来了!
- Linux那些事儿 之 我是PCI(2)PCI全接触
- Linux那些事儿 之 我是PCI(2)PCI全接触
- Linux那些事儿 之 我是PCI(0)引子
- Linux那些事儿 之 我是PCI(4)初始化(一)
- Linux那些事儿 之 我是PCI(5)初始化(二)
- Linux那些事儿 之 我是PCI(0)引子
- Linux那些事儿 之 我是PCI(4)初始化(一)
- Linux那些事儿 之 我是PCI(5)初始化(二)
- Linux那些事儿 之 我是PCI(3)PCI的那些内核参数
- Linux那些事儿 之 我是PCI(3)PCI的那些内核参数
- Linux那些事儿之我是EHCI(3) pci match 和 probe
- Linux那些事儿之我是EHCI(3) pci match 和 probe
- Linux那些事儿之我是EHCI(3) pci match 和 probe
- Linux那些事儿之我是U盘(17)冬天来了,春天还会远吗?(一)
- Linux那些事儿之我是U盘(18)冬天来了,春天还会远吗?(二)
- [ASP/ASP.NET]Request.ServerVariables各参数说明集合
- ASP类的定义[转]
- 用快捷方式锁定计算机(lock computer)
- 博文视点官方博客http://blog.csdn.net/bvbook
- [asp]Scripting.Dictionary的使用
- Linux那些事儿 之 我是PCI(1)PCI,我们来了
- ASP调用存储过程的方法
- 多线程编程 好玩的.你能想到吗?
- 关于ASP编码问题|注册dll组件
- ASP文件下载代码
- 经典..javascript+正则表达式 验证必须是整数和保留三位的小数..
- Linux必学的网络操作命令
- Response.ContentType 所有类型
- 使用Python 3.0a1 调用外部应用程序