分享

【第四章】《步步为营封 Win7》磁盘控制器

 木秀-- 2012-03-10

【第四章】《步步为营封 Win7》磁盘控制器

 

(一)概念
    关于磁盘控制器驱动,这似乎是个老生常谈的问题了。从大概两年前我就一直在努力的纠正“SATA驱动、串口驱动”这些概念错误,但效果不佳,直至今日仍有部分技术人员将这些具有很大偏颇性的词语挂在嘴边,乃至误导更多的新手。所以今天我会再次重复强调一下“磁盘控制器”和“磁盘控制器驱动”的概念,新手请务必读懂,老手也有必要进行重温。
    什么是磁盘控制器?从字面上也大概可以看出,磁盘控制器的作用是管理和控制磁盘。这里的“磁盘”是一个广义的概念,泛指现在常用的机械硬盘和固态硬盘。磁盘控制器有集成于主板上的,也有独立的(如各类SCSI卡),而且磁盘控制器是由来已久的,不是到“SATA时代”才开始出现的。我们这里一定要搞清楚三个问题:
    1、磁盘控制器与磁盘无关。
    系统是通过磁盘控制器来识别磁盘的,所以磁盘控制器上的磁盘无论是什么样子(无论是PATA、SATA、RAID、SCSI以及等等)系统是绝对不会操心的,系统唯一关心的是它能否识别磁盘控制器,如果能识别磁盘控制器那么磁盘控制器就会告诉系统怎么去管理磁盘。
这就好像以为领导要找一份档案材料,他只要找的到档案室的管理员就可以,至于这个档案室管理员去什么样的档案柜上怎么去找档案材料,领导是无需担心的。就像系统无需操心磁盘类型是一样的。
    原版系统中(无论是WINXP还是WIN7)都会包含一定量的磁盘控制器驱动,这些驱动可以应付部分磁盘控制器,而且一般而言,应付并口磁盘控制器是没有什么问题的。但随着时间的推移,随着新硬件和新磁盘控制器的推出,系统自带的磁盘控制器驱动会越来越显得单薄,这就是为什么我们在系统封装与部署时必须增补额外磁盘控制器驱动的原因。
    2、磁盘控制器驱动是针对磁盘控制器的。
    上文已述,系统并不关心磁盘是什么样的,而系统只需要能够控制磁盘控制器就可以了。那么系统要怎么才能拥有对磁盘控制器的控制能力?答案就是通过驱动程序。系统通过磁盘控制器驱动获得对磁盘控制器的控制能力,从而控制磁盘。
    3、磁盘控制器工作模式与磁盘类型无关。
    现在硬盘的各种标识让人眼花缭乱,而各种关于磁盘控制器工作模式的描述又让人产生各种混淆,SATA、SATAII、AHCI、RAID以及等等,但我这里要说的是,你的硬盘是SATA那么系统就真的把你的硬盘当做SATA了吗?答案为否。
    刚才已经说了,系统通过磁盘控制器了解磁盘,而磁盘控制器又有着多种工作和控制模式。在CMOS里我们可以看到对磁盘控制器的设置,大多磁盘控制器拥有多种工作模式,例如IDE模式、AHCI模式、RAID模式等等。如果你是一个SATA硬盘,而磁盘控制器开启的是IDE模式,那么很遗憾,系统仅仅把你的硬盘当做普通IDE硬盘来对待。建议,如果您的硬盘支持更高级的工作模式,请把CMOS里的设置也相应调整以提高磁盘性能。
    说完这些概念,我请大家在今后不要再谈论所谓“SATA硬盘驱动”了,这句话带有很大的错误性,并容易误导更多的新手!

(二)磁盘控制器驱动
    封装用磁盘控制器驱动(俗称SRS驱动)和即插即用磁盘控制器驱动还是有区别的。
    封装用磁盘控制器驱动属于系统关键设备驱动,随系统启动而启动,属于不可或缺的驱动,如果没有这个驱动系统就无法控制磁盘控制器,从而无法操作磁盘,结果就是造成系统的宕机。即插即用磁盘控制器驱动则不同,它就像显卡和声卡的驱动一样,不安装仅仅是无法发挥硬件的最大效能而已,例如显卡驱动不装各种效果无法开启、声卡驱动不装会无声音等。但封装用磁盘控制器驱动和即插即用磁盘控制器驱动本身是无区别的,所以这只是同一种驱动的两种工作模式罢了。
    那么封装用磁盘控制器驱动是怎么工作的呢?
    1、系统启动时检测系统关键设备列表,并准备将这个列表中的设备启动起来,这个列表在注册表中的:
    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase
    打开CriticalDeviceDatabase键,其下是所有系统关键设备的硬件ID。而我们看一个一硬件ID名命名的键,一般包括ClassGUID和Service子键,键值为拥有此硬件ID的设备的设备所属类和所调用的系统服务。
    如果当前磁盘控制器存在于系统关键设备中,那么就根据磁盘控制器硬件ID的Service键去寻找它所需要使用的服务。而如果当前磁盘控制器不存在于系统关键设备中,则直接蓝屏宕机。
    2、使用磁盘控制驱动服务,系统的所有服务都位于:
    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services
    当然也包括磁盘控制器驱动的服务。而如果当前磁盘控制器所需要的驱动服务并不存在,则直接蓝屏宕机。
    我们打开一个磁盘控制器驱动的服务,这个服务包括很多子键,但其中较为重要的是ImagePath和Start,它们分别规定了本服务要加载哪个驱动文件和本服务的启动方式。
    3、加载磁盘控制器驱动文件,启用磁盘控制器。由启动的磁盘控制器驱动服务决定加载哪个驱动文件,这些驱动文件一般都位于C:\Windows\System32\drivers中,而如果这个驱动文件在被加载的时候不存在,则直接蓝屏宕机。
    通过如上描述,我们发现了如下一个过程:
    系统关键设备-->设备驱动服务-->设备驱动文件。
    (1)当前磁盘控制器是否属于系统关键设备,不属于则宕机,属于则根据系统关键设备列表中的相应描述,去寻找这个磁盘控制器所对应的驱动服务;
    (2)如果找不到这个磁盘控制器所对应的驱动服务,则宕机,找得到则根据驱动服务中规定的驱动文件,去寻找这个磁盘控制器所对应的驱动文件;
    (3)如果找不到驱动文件,则宕机,找得到则使用此驱动控制磁盘控制器。
    这是个连贯的过程,哪一个环节出现问题,最终的结果都是宕机。


(三)INF阅读术
      阅读驱动的INF文件需要一定的经验积累,同样也需要一定的尝试和失败,所以我这里只能以制作封装用磁盘控制器驱动为目的的INF阅读方法。
      以下我以INTEL AHCI磁盘控制器驱动为例介绍,INTEL的驱动写的标准且简介,而且INTEL驱动本身是最为稳定的,建议新手练手时选取INTEL的驱动。
      1、读出驱动所属类

  1. [version]
     
  2. CatalogFile=iaAHCI.cat
     
  3. Signature="$WINDOWS NT$"
     
  4. Class=hdc
     
  5. ClassGuid={4D36E96A-E325-11CE-BFC1-08002BE10318}
     
  6. Provider=%INTEL%
     
  7.  
  1. DriverVer=06/04/2009,8.9.0.1023
复制代码

version段一般在驱动INF的开头处,Class即为本驱动所属类,而ClassGuid是这个类的GUID。驱动所属类是个重要的信息,在我们制作封装用磁盘控制器驱动的系统关键设备部分有着很重要的地位。
      2、读出哪些硬件ID对应本驱动,而每个硬件ID又使用了哪个驱动服务
      这一般需要去读两个段,一个是:

  1. [Manufacturer]
     
  2.  
  1. %INTEL%=INTEL_HDC,ntx86
复制代码

Manufacturer段规定了如下哪个段是用来记录驱动描述、所用服务、驱动ID的。“INTEL_HDC”是主段名,“,”后面的是附加段名。例如在这个描述中,如下可能有两个段包括驱动描述、所用服务和驱动ID信息:INTEL_HDC段,或INTEL_HDC. ntx86段。
      INTEL的磁盘控制器是一体化的驱动,从XP到WIN7用的驱动是相同的,所以它的Manufacturer段的内容比较简单。有些驱动针对不同系统是分开的,可能会有针对XP和WIN7的不同设置,请根据实际情况进行应变。
      另一个需要我们阅读的段十分重要,这个段也是由Manufacturer段规定出来的:

  1. [INTEL_HDC.ntx86]
     
  2. %PCI\VEN_8086&DEV_2681&CC_0106.DeviceDesc% = iaStor_Inst, PCI\VEN_8086&DEV_2681&CC_0106
     
  3. %PCI\VEN_8086&DEV_27C1&CC_0106.DeviceDesc% = iaStor_Inst,PCI\VEN_8086&DEV_27C1&CC_0106
     
  4. %PCI\VEN_8086&DEV_27C5&CC_0106.DeviceDesc% = iaStor_mobl_Inst,PCI\VEN_8086&DEV_27C5&CC_0106
     
  5. %PCI\VEN_8086&DEV_2821&CC_0106.DeviceDesc% = iaStor_Inst, PCI\VEN_8086&DEV_2821&CC_0106
     
  6. %PCI\VEN_8086&DEV_2829&CC_0106.DeviceDesc% = iaStor_mobl_Inst, PCI\VEN_8086&DEV_2829&CC_0106
     
  7. %PCI\VEN_8086&DEV_2922&CC_0106.DeviceDesc% = iaStor_Inst, PCI\VEN_8086&DEV_2922&CC_0106
     
  8. %PCI\VEN_8086&DEV_2929&CC_0106.DeviceDesc% = iaStor_mobl_Inst, PCI\VEN_8086&DEV_2929&CC_0106
     
  9. %PCI\VEN_8086&DEV_3A02&CC_0106.DeviceDesc% = iaStor_Inst, PCI\VEN_8086&DEV_3A02&CC_0106
     
  10. %PCI\VEN_8086&DEV_3A22&CC_0106.DeviceDesc% = iaStor_Inst, PCI\VEN_8086&DEV_3A22&CC_0106
     
  11. %PCI\VEN_8086&DEV_3B29&CC_0106.DeviceDesc% = iaStor_mobl_Inst, PCI\VEN_8086&DEV_3B29&CC_0106
     
  12. %PCI\VEN_8086&DEV_3B2F&CC_0106.DeviceDesc% = iaStor_mobl_Inst, PCI\VEN_8086&DEV_3B2F&CC_0106
     
  13.  
  1. %PCI\VEN_8086&DEV_3B22&CC_0106.DeviceDesc% = iaStor_Inst, PCI\VEN_8086&DEV_3B22&CC_0106
复制代码

“=”前的部分是关于这个驱动的文字描述,我们可以在INF的String段里看到,不过这个对我们制作封装用磁盘控制器驱动基本没什么作用。
“=”后的部分,“,”前是针对本硬件ID哪些段对它进行了处理,例如“iaStor_Inst”,如下各段中凡以此开头的,都是针对本硬件ID的处理,包括为本硬件ID添加哪个服务。
“=”后的部分,“,”后是磁盘控制器的硬件ID,如“PCI\VEN_8086&DEV_3B29&CC_0106”。
      这些磁盘控制器的硬件ID将在随后被我们添加到封装用磁盘控制器驱动的系统关键设备中,而它们所对应的服务将是我们下一步阅读的目标。
      3、读出硬件所对应的服务。
      在刚才的INTEL_HDC.ntx86段中,我们获得了本驱动可支持的硬件ID列表,现在我们要把这些ID对应的服务找出来。例如:
      %PCI\VEN_8086&DEV_3A22&CC_0106.DeviceDesc% = iaStor_Inst, PCI\VEN_8086&DEV_3A22&CC_0106
      规定了PCI\VEN_8086&DEV_3A22&CC_0106的各类操作由iaStor_Inst相关段决定,那我们就去寻找iaStor_Inst的相关段,直到找到:

  1. [iaStor_Inst.Services]
     
  2.  
  1. AddService = iaStor, %SPSVCINST_ASSOCSERVICE%, iaStor_Service_Inst, iaStor_EventLog_Inst
复制代码

本段中决定要添加一个服务(AddService),名为“iaStor”,添加方法由“iaStor_Service_Inst”段决定,添加的事件日志由“iaStor_EventLog_Inst”段决定。随后我们找到“iaStor_Service_Inst”段。

  1. [iaStor_Service_Inst]
     
  2. DisplayName    = %*PNP0600.DeviceDesc%
     
  3. ServiceType    = %SERVICE_KERNEL_DRIVER%
     
  4. StartType      = %SERVICE_BOOT_START%
     
  5. ErrorControl   = %SERVICE_ERROR_NORMAL%
     
  6. ServiceBinary  = %12%\iaStor.sys
     
  7. LoadOrderGroup = SCSI Miniport
     
  8.  
  1. AddReg         = iaStor_parameters_AddReg
复制代码

DisplayName,服务的显示名,这对我们制作封装用磁盘控制器驱动没太大关系。
ServiceType,服务的类型,这里是“内核级驱动”。
StartType,服务启动类型,这里是“随系统启动”。
ErrorControl,报错类型,这里是“一般性报错”。
ServiceBinary,这个其实是驱动文件的位置,%12%代表System32\drivers,则完整驱动文件路径为“System32\drivers\iaStor.sys”。
LoadOrderGroup,驱动所属的组。
AddReg,这一般是为本服务额外添加的注册表键和键值。
      通过阅读这些,我们知道了硬件ID为“PCI\VEN_8086&DEV_3A22&CC_0106”的设备所需服务的基本概况,特别是我们得知了这个驱动服务所加载的驱动文件名称及位置。以此类推,解决其他的硬件ID。
      从INF里读到了这些信息,我们就可以着手制作WIN7的封装专用磁盘控制器驱动了。


(四)制作封装专用磁盘控制器驱动
      制作封装专用磁盘控制器驱动其实就是一个将INF转成REG的过程,曾经有过这种工具,但我个人并不建议大家使用。如果使用者并不明白INF转REG的真正原理,就很难了解这项技术的真正内在本质,更难于在出现问题时能够独立解决,这个技术的公共交流带来了很多不便。本节内容我会和大家一起亲手将INTEL AHCI磁盘控制器驱动的INF转成封装用的REG文件,以让大家更加了解这项技术的本质。
      上文中,我们已经介绍了INF阅读的基本方法,下面我们来对INF进行一下转化。
      1、系统关键设备部分
      这部分的注册表键和键值遵守如下样式:

  1. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\(硬件ID)]
     
  2. "ClassGUID"="(类的GUID)"
     
  3.  
  1. "Service"="(对应的服务名)"
复制代码

硬件ID,读取自INTEL_HDC.ntx86段,例如“PCI\VEN_8086&DEV_2922&CC_0106”
类的GUID,读取自version段,“ClassGuid={4D36E96A-E325-11CE-BFC1-08002BE10318}”
对应的服务名,读取自INTEL_HDC.ntx86段,由“PCI\VEN_8086&DEV_2922&CC_0106”对应的iaStor_Inst段所派生的iaStor_Inst.Services决定服务名,为“iastor”。
      那么“PCI\VEN_8086&DEV_2922&CC_0106”的系统关键设备部分注册表应该写为:

  1. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\ PCI#VEN_8086&DEV_2922&CC_0106]
     
  2. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  3.  
  1. "Service"=" iastor "
复制代码

(注意硬件ID中的“\”变为“#”)
      以此类推,将其他硬件ID的系统关键设备的注册表键和键值写完。
      2、驱动服务部分
      上文说过,驱动服务部分由iaStor_Service_Inst来定,服务部分的注册表写起来比较容易,但要注意对应关系,即INF中的名字和REG中的名字不同。
      回顾一下iaStor_Service_Inst段,依据此段写封装用磁盘控制器驱动的驱动服务时,不是所有的部分都需要,我将它简化一下:

  1. [iaStor_Service_Inst]
     
  2. ServiceType    = %SERVICE_KERNEL_DRIVER%
     
  3. StartType      = %SERVICE_BOOT_START%
     
  4. ErrorControl   = %SERVICE_ERROR_NORMAL%
     
  5. ServiceBinary  = %12%\iaStor.sys
     
  6.  
  1. LoadOrderGroup = SCSI Miniport
复制代码

INF中带有“%%”的部分,在INF的String段有期对应的值,最简单的方法可以全文搜索一下两个“%”之间的内容,即会找到他们对应的值。如本例中,替换为值后为:

  1. [iaStor_Service_Inst]
     
  2. ServiceType    = 1
     
  3. StartType      = 0
     
  4. ErrorControl   = 1
     
  5. ServiceBinary  = system32\drivers\iaStor.sys
     
  6.  
  1. LoadOrderGroup = SCSI Miniport
复制代码

这些部分在注册表中分别对应:
      INF中的ServiceType对应注册表中的Type;
      INF中的StartType对应注册表中的Start;
      INF中的ErrorControl对应注册表中的ErrorControl;
      INF中的ServiceBinary对应注册表中的ImagePath;
      INF中的LoadOrderGroup对应注册表中的Group。
而服务部分的一般样式为:

  1. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\(服务名)]
     
  2. "ErrorControl"=
     
  3. "Group"=""
     
  4. "ImagePath"=""
     
  5. "Start"=
     
  6.  
  1. "Type"=
复制代码

则我们转化后为:

  1. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\iaStor]
     
  2. "ErrorControl"=dword:00000001
     
  3. "Group"="SCSI Miniport"
     
  4. "ImagePath"="system32\drivers\IaStor.sys"
     
  5. "Start"=dword:00000000
     
  6.  
  1. "Type"=dword:00000001
复制代码

这样,服务部分我们也搞定了。
      3、驱动文件
      差点忘记了,不要忘记把驱动程序文件“IaStor.sys”也提取出来,在执行系统封装时复制到“ImagePath”所规定的位置即可。
经过全部过程后,我们可以制作出来一份INTEL AHCI磁盘控制器的封装用磁盘控制器驱动了!这份驱动的注册表文件为:

  1. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_2681&CC_0106]
     
  2. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  3. "Service"="iaStor"
     
  4. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_27C1&CC_0106]
     
  5. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  6. "Service"="iaStor"
     
  7. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_27C5&CC_0106]
     
  8. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  9. "Service"="iaStor"
     
  10. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_2821&CC_0106]
     
  11. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  12. "Service"="iaStor"
     
  13. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_2829&CC_0106]
     
  14. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  15. "Service"="iaStor"
     
  16. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_2922&CC_0106]
     
  17. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  18. "Service"="iaStor"
     
  19. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_2929&CC_0106]
     
  20. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  21. "Service"="iaStor"
     
  22. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_3A02&CC_0106]
     
  23. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  24. "Service"="iaStor"
     
  25. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_3A22&CC_0106]
     
  26. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  27. "Service"="iaStor"
     
  28. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_3B29&CC_0106]
     
  29. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  30. "Service"="iaStor"
     
  31. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_3B2F&CC_0106]
     
  32. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  33. "Service"="iaStor"
     
  34. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#VEN_8086&DEV_3B22&CC_0106]
     
  35. "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
     
  36. "Service"="iaStor"
     
  37. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\iaStor]
     
  38. "ErrorControl"=dword:00000001
     
  39. "Group"="SCSI Miniport"
     
  40. "ImagePath"="system32\drivers\IaStor.sys"
     
  41. "Start"=dword:00000000
     
  42.  
  1. "Type"=dword:00000001
复制代码

至此,我们学会了制作封装用磁盘控制器驱动的方法。制作封装用磁盘控制器驱动需要长期的实践和总结,也需要经历无数的失败才能成就最后的成功!


INTEL WIN7 磁盘控制器驱动: INTEL.rar (367.07 KB)

NTEL WIN7 封装用磁盘控制器驱动: Intel.rar (168.89 KB)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多