Cstyle的UEFI导读之Driver Diagnostics

来源:互联网 发布:淘宝开店手机认证流程 编辑:程序博客网 时间:2024/06/10 17:13
      Driver Diagnostics Protocols 是UEFI driver model的driver可选实现的一个protocol,其他的类型的driver则不需要实现它。实现了这个protocol之后,就可以通过UEFI driver management来诊断和调试设备。
      之前在Driver binding protocol章节中有提到过,start服务需要对设备做简单的快速的检测和诊断,判断该driver是否可以管控该设备,为了不影响post时间,我们一般尽可能把诊断的动作放在一个单独的protocol中来实现,这样就不需要再每次boot的时候都进行大量的diagnosis,造成post时间过长。
     Driver Diagnostics由两个不同的protocol来实现,Driver Diagnostics Protocol(1.1)/ Driver Diagnostics 2 Protocol(2.0)他们有几乎一模一样的接口,唯一的差别是在于他们支持的语言编码不太一样。他们在显示诊断信息的时候,一个是使用ISO 639-2另外一个则是RFC 4646语言码。但是由于他们二者几乎一致,所以一般driver会同时实现两个protocol这样还可以共享算法和诊断信息。
    Driver Diagnostics Protocol会在其Driver entrypoint被install到drive的image Handl上,并且会被UEFI Boot Manager或者其他的APP来调用和执行。也可以在shell下使用drvdiag命令来查看那些设备有实现了Driver Diagnostics Protocol,并且用它来诊断该设备。一个设备也可能同时被几个driver所控制,每个driver都有实现了Driver Diagnostics Protocol,这个时候就需要选择一个来执行。

Driver Diagnostics Protocol 的实现:
和其的protocol类似,我们一般需要完成下面几个任务,在UDK中DriverDiagnostics.c有参考是实现示例:
1.Add global variable for the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance to DriverDiagnostics.c.
2.Add global variable for the EFI_DRIVER_DIAGNOSTICS2_PROTOCOL instance to DriverDiagnostics.c.
3. Add Static table of diagnostics result messages as Unicode strings to DriverDiagnostics.c.
4. Implementation of the RunDiagnostics() service
5. Install all the Driver Diagnostics Protocols in the driver entry point.
6. If the UEFI Driver supports the unload feature, uninstall all the Driver Diagnostics Protocols in the Unload() function.
   
以下是两种protocol的类型定义数据结构的声明和定义:

        Driver Diagnosis protocol的实现会根据driver的不同有些许差别,device driver是最为简单和常见的,bus driver 或者 hybrid driver由于不仅要在bus controller上而且还要在 child controllers上实现Driver diagnosis protocol,所以就相对比较复杂。Driver Diagnostics protocol一般被使用BS服务InstallMultipleProtocolInterfaces()来install到driver的image handle上,同一个driver可以安装多个protocol到不同的handle上。但同时我们也可以使用 EDK II library UefiLib中提供的库函数EfiLibInstallAllDriverProtocols()/EfiLibInstallAllDriverProtocols2()来操作。如果install失败的话,会返还错误码,并且如果实现了Unload()服务,就调用该服务来Unload Driver Diagnosis protocol。参考代码在DriverDiagnostics.c中有实现。

RunDiagnostics() 的实现:
    RunDiagnostics() 服务是真正的对被driver所管理的的在安装了Driver Diagnosis的controller进行诊断,对于那些为了加快post时间而没被connected的device则不能使用,为了配置整个平台的driver,进入平台配置模式就必须要在UEFI boot manager中connecte所有的driver到device上。 RunDiagnostics() 不允许调用任何的和console-IO 的protocols而是通过一个buffer把诊断结果返回到这个buffer中,这个buffer是由RunDiagnostics() 使用 AllocatePool()服务来申请内存,由调用者来觉得是log该诊断结果还是显示它并负责释放申请的内存。

两种常见的实现方式:
1.Device Driver
2.Bus & Hybrid Driver
    和上面的device driver类似,bus driver和hybrid driver需要为bus控制器和子控制器都install一个diagnostic protocol。

测试Diagnostic Protocol:
1.RunDiagnostics() as a UEFI Application
    把RunDiagnostics()实现成一个app,然后使用BS提供的LoadImage(),StartImage()服务来运行,debug。
2.Testing Driver Diagnostics Protocols under shell
    在shell下使用 drvdiag命令的各种参数来进行debug。

转载请注明出处 Cstyle.z.zhou@gmail.com     http://blog.csdn.net/CStyle_0x007
原创粉丝点击