阅读:4222回复:8
谁能讲一下枚举的全过程?
哪位大侠能给我讲解一下枚举的全过程?要详细些?我对整个过程
不是很清楚? 谢谢了,我很急。 |
|
最新喜欢:![]() |
板凳#
发布于:2001-09-01 13:01
[QUOTE]原本由 lvyingf 发表
[B]gung: 我想知道系统启动的枚举过程,怎么你不来了啊? [/B][/QUOTE] 抱歉抱歉,我来迟了,其实我对枚举也没有很深入的了解,下面贴出一些有关的资料供大家参考,希望对大家有用: ---------------------------------------------------- In the first instance, the PnP Manager has a built-in "driver" for a "root" bus that doesn't actually exist. The root bus conceptually connects the computer to all hardware that can't electronically announce its presence―including the primary hardware bus (such as PCI). The root bus driver gets information about the computer from the registry, which was initialized by the Windows 2000 Setup program. Setup got the information by running an elaborate hardware detection program and by asking the end user suitable questions. Consequently, the root bus driver knows enough to create a PDO for the primary bus. The function driver for the primary bus can then enumerate its own hardware electronically. The PCI bus, for example, provides a way of accessing a special configuration space for each attached device, and the configuration space contains a description of the device and its resource requirements. When a bus driver enumerates hardware, it acts in the guise of an ordinary function driver. Having detected a piece of hardware, however, the driver switches roles: it becomes a bus driver and creates a new PDO for the detected hardware. The PnP Manager then loads drivers for this device PDO, as previously discussed. It might happen that the function driver for the device enumerates still more hardware, in which case the whole process repeats recursively. The end result will be a tree like that shown in Figure 2-2, wherein a bus device stack branches into other device stacks for the hardware attached to that bus. from "Programing the WDM" -------------------------------------------------------- 关于PCI总线枚举: 当机器第一次上电时,配置软件必须扫描在系统中的不同总线(PCI及其他),确定什么设备存在和他们有什么配置要求。这个过程常常是: [*] 扫描总线 [*] 激活总线 [*] 检查总线 [*] 发现过程 [*] 总线枚举 执行pci总线扫描的程序常称为pci总线枚举。 为了实现这个过程,每个pci功能必须实现由pci规范定义的一组配置寄存器。依赖其操作特性,功能还可以实现由pci规范定义的其他要求的或可选的配置寄存器。另外,规范保留许多附加的配置单元,以实现功能指定的配置寄存器。 配置软件读取设备配置寄存器的子集,以确定功能的出现及类型。在确定设备出现后,软件访问功能的其他配置寄存器,确定设备要求的许多存储器和/或io空间。然后他编程设备的存储器和/或io地址译码器,反映分配给其它系统设备的存储器和/或io地址范围,他们保证互相排斥。 如果功能表示使用pci中断请求引脚(通过一个配置寄存器),配置软件利用路由信息对它编程,指出功能的pci中断请求引脚通过系统路由到什么系统中断请求线(irq)。 。。。。。。 摘自《pci系统结构》 --------------------------------------------------------- 关于pci设备枚举的程序实现: BOOLEAN pciScanIteratePCI( IN BOOLEAN First, IN unsigned int pciVendorId, IN unsigned int pciDeviceId, IN OUT PCI_SLOT_NUMBER *returnSlotData, IN OUT PCI_COMMON_CONFIG *returnPciData, IN OUT unsigned int *returnBusNumber ) /*++ Routine Description: This function is called by the driver to find the next PCI card and initialize the adapter's configuration. Arguments: IN BOOLEAN First - TRUE if scan is to start with first device FALSE to increment to the next device IN unsigned int pciVendorId - Specified vender ID, or 0xFFFF for all venders IN unsigned int pciDeviceId - Specified device ID, or 0xFFFF for all devices IN OUT PCI_SLOT_NUMBER *returnSlotData - Slotdata for found device (starting point for first == FALSE) IN OUT unsigned int *returnBusNumber - Bus number for found card Return Value: ULONG --*/ { PCI_SLOT_NUMBER slotData; PCI_COMMON_CONFIG pciData; BOOLEAN nextBus = FALSE; ULONG busNumber = 1; ULONG bytesReturned; BOOLEAN firstFunction; BOOLEAN firstDevice; KdPrint( ("pciScan: FindPCI \n") ); // // iterate over all PCI slots // firstFunction = First; firstDevice = First; slotData.u.AsULONG = 0; if (!First) { /* continuation */ // // if not the first we want to point after the last device we found // returnSlotData->u.bits.FunctionNumber++; if (PCI_MAX_FUNCTION <= returnSlotData->u.bits.FunctionNumber) { /* next device */ returnSlotData->u.bits.FunctionNumber = 0; returnSlotData->u.bits.DeviceNumber++; if (PCI_MAX_DEVICES <= returnSlotData->u.bits.DeviceNumber) { /* next bus */ returnSlotData->u.bits.DeviceNumber = 0; *returnBusNumber++; } /* next bus */ } /* next device */ } /* continuation */ // // iterate over all PCI busses looking for devices // for ( busNumber = First?0:*returnBusNumber; busNumber < 256; busNumber++, firstDevice = TRUE) { /* busses loop */ unsigned int DeviceNumber; nextBus = FALSE; // // Iterate over all devices // for ( DeviceNumber = firstDevice?0:returnSlotData->u.bits.DeviceNumber; DeviceNumber < PCI_MAX_DEVICES ; DeviceNumber++, firstFunction = TRUE ) { /* devices loop */ unsigned int FunctionNumber; slotData.u.bits.DeviceNumber = DeviceNumber; // // Iterate over all functions // for ( FunctionNumber = firstFunction?0:returnSlotData->u.bits.FunctionNumber; FunctionNumber < PCI_MAX_FUNCTION ; FunctionNumber++) { /* functions loop */ slotData.u.bits.FunctionNumber = FunctionNumber; KdPrint( ("pciScan: FindPCI - call HalGetBusData DeviceNumber= %x, Function = %x, busNumber = %x ", slotData.u.bits.DeviceNumber, slotData.u.bits.FunctionNumber, busNumber) ); RtlZeroMemory(&pciData, sizeof(PCI_COMMON_CONFIG)); bytesReturned = HalGetBusData( PCIConfiguration, busNumber, slotData.u.AsULONG, &pciData, sizeof(PCI_COMMON_CONFIG)); if (2 == bytesReturned) // device/function does not exist { /* no device/function */ KdPrint( (" - no match 2 returned pciData.VendorID = %x %x\n", pciData.VendorID, slotData.u.AsULONG) ); // // MUST CONTINUE WITH LOOP -- // functions do not have to be consective // } /* no device/function */ else if (0 == bytesReturned) // bus does not exist { /* no bus */ KdPrint( (" - no match 0 returned pciData.VendorID = %x %x\n", pciData.VendorID, slotData.u.AsULONG) ); // // We can skip to next bus // set flag to break out of device loop // and break out of function loop // nextBus = TRUE; break; } /* no bus */ else if (0xffff == pciData.VendorID) { /* invalid vendor ID */ KdPrint( (" - no match PCI_INVALID_VENDER_ID HalGetBusData pciData.VendorID = %x\n", pciData.VendorID) ); } /* invalid vendor ID */ else if ( ((0xFFFF == pciVendorId) || ( pciData.VendorID == pciVendorId )) && ((0xFFFF == pciDeviceId) || ( pciData.DeviceID == pciDeviceId))) { /* found next */ // Found it this is the next instance of // this card type KdPrint( ("\npciScan: ( busNumber, device, function ) = ( %x, %x, %x )\n", busNumber, slotData.u.bits.DeviceNumber, slotData.u.bits.FunctionNumber)); dumpPciConfig( pciData ); KdPrint( ("\n\n") ); *returnSlotData = slotData; *returnPciData = pciData; *returnBusNumber = busNumber; KdPrint( ("pciScan: exiting\n") ); return TRUE; } /* found next */ else { /* does not match */ KdPrint( (" - no match pciData.VendorID = %x %x\n", pciData.VendorID, slotData.u.AsULONG) ); } /* does not match */ } /* functions loop */ if (nextBus) break; // break to next bus } /* devices loop */ } /* busses loop */ KdPrint( ("pciScan: exiting\n") ); return FALSE; } // end pciScanFindPCI() 摘自osr.com的pciscan例程 [gung 编辑于 2001-09-01 13:12] |
|
地板#
发布于:2001-08-31 09:10
[QUOTE]原本由 lvyingf 发表
[B]gung: 我想知道系统启动的枚举过程,怎么你不来了啊? [/B][/QUOTE] 大概会有很多内容吧? |
|
|
5楼#
发布于:2001-08-30 18:36
USB设备具体枚举过程是:
1、HOST发获取描述符请求,设备返回8字节的设备描述符,成功之后,HOST会发给设备设置地址的请求,给你一个设备地址,你要将设备地址写入接口芯片的寄存器,以后设备就按此地址给你请求 2、HOST发获取设备描述符请求,设备将返回18字节的设备描述符,成功之后,HOST发获取配置描述符,然后设备将所有描述符返给HOST,成功之后,PC将出现找到新硬件,并要求你安装相应驱动程序的画面。也就是完成了枚举的过程。 |
|
|
7楼#
发布于:2001-08-26 17:37
不清楚你是想知道整个计算机启动时检测各设备及装载各设备驱动过程的枚举,还是想知道如何在特定总线上(如usb,pci总线上)通过自己的驱动程序枚举各设备。
对于前者,总归是由系统虚拟设备root根据注册表枚举各总线等无法自动声明自己存在的基本设备,然后由各总线通过电气连接各自检测枚举自己的设备啦。这些在walter oney书中第二章有些描述。 如果是后者,我只知道pci设备的枚举方法。 如果你需要,我可以贴上原文或程序。 |
|
8楼#
发布于:2001-08-25 16:17
不知道什么是枚举
[winter 编辑于 2001-08-26 15:03] |
|
|