Cstyle的UEFI导读之UEFI Driver and Controller Name用Component Name Protocol实现

来源:互联网 发布:软件设计师电话 编辑:程序博客网 时间:2024/06/10 15:38
    今天谈谈driver的名字,任何事物都有一个名字来代表自身的存在,以此来区别于其他的事物,UEFI driver也不例外。在UEFI shell中敲入以下命令 drivers -b /devices -b我们就能得到当前系统中install的所有的实例化了Component Name Protocol 的设备driver及device,可以进行查看,测试。   Component Name Protocols以及Component Name2 Protocols虽然对于UEFI model driver都是可选的,但是一般建议实例化它,它为driver及driver管理的设备提供本地化的不大于40 Unicode characters字符组成的driver名信息。Service Drivers, Root Bridge Drivers, and Initializing Drivers则不需要提供 Component Name Protocols。

Component Name Protocols和Component Name2 Protocols的差异和联系:
        二者提供一模一样的功能,唯一的差别在于这两个protocol一个基于UEFI1.10的spc来实现的,使用ISO 639-2 language codes (i.e. eng, fra).而Component Name 2 Protocol 是基于UEFI2.0的spc来实现,使用 RFC 4646 language codes (i.e. en, en-US, fr).由于这两个protocol唯一的差别在于language code的差异,所以如果driver是基于UEFI2.0的spc来写的话,建议同时实例化两个protocol,这样driver会有比较好的兼容性,以下统称为Component Name Protocol.

Notes:ISO 639-2/RFC 4646这两个标准看起来很陌生,其实不然,翻开我们的BIOS code里面的*.UNI文件里面有许多“en-US”/"eng"这样的关键词来声明的字符串,这些字符串一般作为setup上面的显示或者是post过程中显示在post message,还有的会出现在用户自己定义的app(diagnostic app)在机台上跑的时候,抓出来的字符信息。但是需要注意的是这些都是Unicode而非我们常见的Ascii码。

Component Name Protocol的实现:
    ComponentNameProtocol的实现ComponentName.c文件,通常包含以下的内容:

• Add global variable for the EFI_COMPONENT_NAME_PROTOCOL/EFI_COMPONENT_NAME2_PROTOCOL instance to ComponentName.c.
• EFI_COMPONENT_NAME2_PROTOCOL instance
• Add static table of UEFI Driver names as Unicode strings to ComponentName.c.
• Add static table of controller names as Unicode strings to ComponentName.c.
• Implementation of the GetDriverName() service
• Implementation of the GetControllerName() service
• Install all the Component Name Protocols in the driver entry point.
• If the UEFI Driver supports the unload feature, uninstall all the Component
Name Protocols in the Unload() function.

以下是两个实例,分别是EFI_COMPONENT_NAME_PROTOCOL/EFI_COMPONENT_NAME2_PROTOCOL,可以看出两个Protocol十分相似,不同的地方是language code部分的标准有所差别,从图3可以看出EFI_COMPONENT_NAME_PROTOCOL是多个语言关键词直接相连,中间不添加任何的字符或者是空格,而EFI_COMPONENT_NAME2_PROTOCOL则是多个语言直接用分号隔开,一般要求必须支持的语言是英文,其他的语言是可选项。
实例1:
实例2:
实例3:

Component Name Protocol一般使用BS提供的服务InstallMultipleProtocolInterfaces()来install,同时我们的UefiLib也提供了一些更为简单的方法方便使用,如下,同其他的Protocol一样如果install失败,我们也需要提供Unload的方法来Unload该protocol。
• EfiLibInstallDriverBinding()
• EfiLibInstallAllDriverProtocols()
• EfiLibInstallDriverBindingComponentName2()
• EfiLibInstallAllDriverProtocols2()

三种常见的Component Name Protocols的实现:
1.Component Name Protocols provides the name of the UEFI Driver. 

2. Component Name Protocols provides the name  for a device driver providing both the name of the UEFI Driver and the names of the controllers under UEFI Driver management. 

3. Component Name Protocols provides the name   is that of a bus or a hybrid driver producing names for the UEFI Driver, names for the bus controllers it is managing, and names for the child controllers the driver has produced.

EDK II library UefiLib提供了管理这些Unicode strings表的服务,他们能同时支持ISO 639-2 or RFC 4646语言码:
• LookupUnicodeString()
• LookupUnicodeString2()
• AddUnicodeString()
• AddUnicodeString2()
• FreeUnicodeStringTable()

Component Name Protocols中的GetDriverName()方法的实现:
该方法使用不同的language码,从mAbcDriverNameTable[]表格中查找相应的Unicode字符串,返回给DriverName这个字符串指针。


Component Name Protocols中的 GetControllerName() 方法的实现:
    可以看出这个实现和上面的几乎是如出一辙,实现方法基本一致。但是需要注意的是Component Name Protocols只存在与当前被driver所connected的设备,对于那些unconnected的设备是不需要的。下图是一个示例,通常我们会有两种类型:一种是针对的device driver的,一种是针对bus driver/hybrid drivers的。

Device driver:
    有两种方式,一种是创建静态的device名字,如下图的静态的字符串表格,另外一种是稍微复杂的动态创建的方式:
A.静态方式:
B.动态方式:
    动态的方式需要为每个设备创建私有的数据结构(参考,Cstyle的UEFI导读之Driver中的私有数据结构),动态生成的字符串会在 Driver Binding Protocol Start() service中填写到下图的ControllerNameTable表中。
实例1类型定义:
实例2动态实现:

bus driver/hybrid drivers:
类似于device方式的静态字符:

如何测试 Component Name Protocols:
可在shell下使用devices -b,drivers -b查看device ,driver名字,使用-L参数来选择不同的语言。
 
 
 
以上是个人读书笔记和总结,转载请注明出处,谢谢Cstyle.z.zhou@gmail.com//http://blog.csdn.net/CStyle_0x007