阅读:2413回复:8
2k是按照ServiceGroupOrder+GroupOrderList的顺序先加载完驱动,再构建设备树;还是在构建设备树时需要相应的驱动,再加载驱动?
谢谢大家解答我的疑惑。
|
|
最新喜欢:![]() |
沙发#
发布于:2005-06-01 13:22
这个要具体问题具体分析,对于wdm硬件驱动,显然是构建设备树的时候加载相应的驱动。对于象文件系统,ndis,tdi这种nt架构的驱动,就要按照sevicegruoporder+grouporderlist来加载了,也不存在象wdm那种设备树。windows内核的程序,都统称为驱动程序,但
但象文件系统,协议栈的程序,和那种一般意义上的驱动,差的很远了,当然在nt系列的平台上都要符合irp这种架构 |
|
板凳#
发布于:2005-06-01 17:39
但是我用icesword看到的加载顺序是,在加载pci.sys后,并没有继续构建设备树,而是加载了一些遗留的驱动,就好像是构建设备树和加载遗留驱动交叉进行,但总体还是依照sevicegruoporder+grouporderlist的顺序加载。是这样的吗?
|
|
驱动老牛
![]() |
地板#
发布于:2005-06-02 09:36
谢谢大家解答我的疑惑。 对于标准的设备驱动(如磁盘,打印机等)程序,这个是没用的。 |
|
地下室#
发布于:2005-06-02 09:42
都不是....
说起来很复杂 用我的用户名搜索 我有写一个device tree的构建过程 既便是legacy driver比如file system这些 他也是位于device tree里面的 你可以试着向系统的root device发送一个query bus relationship的irp瞧瞧他都返回了些什么东西..... 会发现ndis,file system这些东西都历历在目 以上 |
|
5楼#
发布于:2005-06-02 15:51
仔细读了你的文章《device tree的搭建过程》,设备树的构建过程基本弄清楚了,但我的主要问题在驱动的加载过程。用icesword看到的驱动加载顺序和想象并不一样。legacy driver当然也在设备树中,实际上是挂在pnpmanager下,包括pnp设备的根ACPI_HAL也都挂在pnpmanager下。按照想象pnpmanager应先玫举pnp设备构建设备树,并按相应的顺序加载驱动;然后玫举legacy driver,并按相应的顺序加载驱动,但加载驱动的顺序并不是这样。这是为什么呢?
|
|
6楼#
发布于:2005-06-02 16:10
猜测是这样:pnpmanager先玫举设备树,当某一类设备被玫举完,设备树的构建暂停,pnpmanager就玫举它的下一类legacy设备,然后再继续构建设备树。为什么要插入legacy设备的玫举呢?是因为后来玫举的设备可能要被上面的legacy设备管理。比如 NDIS.SYS 的加载就在 网卡驱动 的前面,因为 网卡 要被 NDIS 管理。
是这样的吗? |
|
7楼#
发布于:2005-06-03 13:51
整个的过程是这样的
首先明确几个步骤概念 加载....表示把文件加载到内存 调用driverentry..如名 调用adddevice 发送IRP_MN_START_DEVICE,以及后续及前导的其他的PNP request 这几个步骤基本不是一次完成的(指系统启动的过程) 然后..希望你手头上有win2k的源代码...可以对比跟踪 首先是加载过程 被标记成boot start的驱动是由osloader.exe加载的.这个文件是作为一个组件(这样翻译?)被放置在ntldr里面了,可惜ms没有提供这个pdb文件下载. 这些boot start的driver跟hal.dll和ntoskrnl.exe一同被加载 如果你有设置noguiboot的话.能看到加载的顺序的.顺便你还能看到几个非驱动文件被加载比如drvmain.sdb 当内核ntoskrnl开始执行以后,经过漫长的过程来到IoInitSystem这个函数.然后调用IopInitializeBootDrivers这个函数 所谓boot driver就是指由osloader.exe加载的驱动 这个函数首先把诸多的boot drivers按照他们的group:tag顺序排序 然后一一调用IopInitializeBuiltinDriver这个函数. 注意这里的group:tag起的作用 在IopInitializeBuiltinDriver函数里面..调用这个driver的入口函数,也就是driverentry 函数IopInitializeBuiltinDriver完成,回到IopInitializeBootDrivers函数 接着调用IopAddDevicesToBootDriver这个函数.为刚刚创建的driver调用他的adddevice函数.然后返回 接着IopInitializeBootDrivers这个函数调用IopRequestDeviceAction从root开始枚举每个节点 为每个没有被处理的节点分配资源.然后start这个节点 start了以后再发送IRP_MN_QUERY_DEVICE_RELATIONS的bus relation去枚举子节点.并企图为这个子节点adddevice.并再企图start 这个子节点.并发送query bug relation到这个子节点,并递归的处理子节点的子节点.并一直递归...这个动作要特别注意 当系统在执行IopInitializeBootDrivers的时候是不能从磁盘上加载驱动的.所以在企图加载driver的时候除非这个driver object已经被创建了.才会成功.否则会失败.既便是当前这个driver的image已经位于内存里面了. 源代码里面使用的是driverObject = IopReferenceDriverObjectByName(&unicodeDriverName);这个语句来获取当前这个driver object是否已经存在..显然只有在driver entry被调用了以后他才会存在.(IopCallDriverAddDeviceQueryRoutine这个函数里面) 如果当前的driver object不存在,而且又不能加载驱动.那么这个递归的过程就结束了.一路返回到IopInitializeBootDrivers这个函数 这个函数继续按照group:tag的顺序走下一个驱动.调用driver entry调用adddevice 企图start device企图枚举他的孩子.. 这里还要特别注意的时候.IopRequestDeviceAction这个函数始终是从root节点开始的.这样就存在这样的情况 比如 acpi.sys要先于pci.sys被调用driverentry acpi的driverentry调用了以后,adddevice被接着调用,然后是start device.然后被query bus relation.他返回一个pdo是pci.sys的 内核企图为新返回的pci.sys的pdo adddevice.当然失败了.因为pci.sys的driverentry并没有被调用.acpi的调用结束回到IopInitializeBootDrivers函数,他开始尝试下一个要被处理的boot driver,这里我们简单起见假设下一个就是pci.sys,可能实际上排在acpi.sys后面的并不一定就是pci.sys 接着pci.sys被调用driverentry,接着adddevice,然后是start,然后被query bus rel,假设pci返回了一个pdo是pciide.sys的.当然企图为pciide调用adddevice还是失败了.又回到了IopInitializeBootDrivers函数..开始尝试下一个group:tag组合 最终IopInitializeBootDrivers函数一一遍历了全部的boot driver 这个时候device tree上可能有很多的节点并没有被调用adddevice..因为在这个过程中是不能加载驱动的. 等全部的boot driver都被初始化好了.IoInitSystem调用IopInitializeSystemDrivers函数俩完成那些标记成system start的驱动加载过程 IopInitializeSystemDrivers函数首先处理当前device tree那些没有被adddevice的节点..从root节点开始调用IopProcessAddDevices但是这一次设置了loadDriver = TRUE,也就是说如果在上面的流程里面企图adddevice却发现driver object不存在的时候,就不再是简单的返回一个错误了.而是开始尝试加载image文件,调用driver entry 然后继续..这个步骤里..很多的设备驱动都被加载进来了.基本的pnp device tree在这个步骤里面基本成形. 完成了上面的工作以后 IopInitializeSystemDrivers安装group:tag的顺序收集所有被标记成system start的驱动.一一加载image文件,调用driverentry调用adddevice(如果有的话,因为system start多是一些软件驱动,一般都没有adddevice) 这些都完成了以后..基本驱动加载就完毕了 最后剩一个auto start的类型..那是由scm加载的. 整个过程是比较复杂的 希望手头准备好win2k的源代码.然后使用windbg一点点跟踪调试. 大致就能明白整个过程了.这里特别推荐windbg.softice会错过很多东西...呵呵...windbg能在ntoskrnl.exe执行之前就断点.而且windbg调试的时候你也能很方便的对比win2k的源代码. 以上 |
|
8楼#
发布于:2005-06-06 16:08
领悟中...
谢谢tiamo的解答,谢谢大家的解答。 |
|