8

UEFI开发探索69- YIE001PCIe开发板(05 UEFI驱动)

 3 years ago
source link: http://yiiyee.cn/blog/2021/01/16/uefi%e5%bc%80%e5%8f%91%e6%8e%a2%e7%b4%a269-yie001%e5%bc%80%e5%8f%91%e6%9d%bf%ef%bc%8805-uefi%e9%a9%b1%e5%8a%a8%ef%bc%89/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

UEFI开发探索69- YIE001PCIe开发板(05 UEFI驱动)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

上一篇中,驱动BlankDrv完成了核心的EFI_DRIVER_BINDING_PROTOCOL,以及获取驱动名Protocol的处理后,整个UEFI驱动框架还有两项工作等待完成:

  • 安装UEFI驱动所提供的Protocol;
  • 驱动加载后是常驻内存的,应该提供UEFI驱动的卸载函数,以支持将驱动系统中移除的功能。

1 完成驱动框架

安装Protocol可以使用InstallMultipleProtocolInterfaces()函数,由于BlankDrv中有三种Protocol需要安装,所以使用了库函数EfiLibInstallDriverBindingComponentName2()来安装所有的Protocol。如示例1所示。

【示例1】安装BlankDrv所提供的Protocol

EFI_STATUS EFIAPI UefiMain(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS          Status;
  …..
//安装需要提供的三种Protocol
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gBlankDrvDriverBinding, 
             ImageHandle,
             &gBlankDrvComponentName,
             &gBlankDrvComponentName2
             );
  return Status;
}

驱动的卸载函数,在使用UEFI Shell命令unload的时候会被调用。此函数的入口在UEFI工程的INF文件中添加,由[Defines] Section的UNLOAD_IMAGE字段给出。在示例工程BlankDrv的BlankDrv.inf中,按照如下方式进行了定义:

[Defines]
  ……
ENTRY_POINT                    = UefiMain         //驱动的入口函数
UNLOAD_IMAGE                   = DefaultUnload   //驱动的卸载函数

从中可以看出,BlanDrv的卸载函数为DefaultUnload(),它定义在源文件BlankDrv.c中。在函数中,它主要实现了如下功能:

  • 遍历系统的句柄数据库,并将所有设备句柄存储在缓冲区数组中;
  • 对缓冲区数组中的句柄,也即对系统中所有设备句柄进行判断,如果使用了驱动,则将其与控制器断开连接;
  • 卸载驱动安装的所有Protocol。包括EFI_DRIVER_BINDING_PROTOCOL、EFI_COMPONENT_NAME_PROTOCOL和EFI_COMPONENT_NAME2_PROTOCOL的卸载。

DefaultUnload()函数的代码较长,在此就不列出了,可以直接去源文件中查看其实现。

至此,UEFI驱动模型的框架就完成了。将BlankDrv的工程文件复制到文件夹RobinPkg\Drivers下,并在RobinPkg.dsc的[Components] Section中添加编译路径:

RobinPkg/Drivers/BlankDrv/BlankDrv.inf

启动UEFI的编译环境,运行如下命令即可编译IA32的UEFI驱动。

C:\UEFIWorkspace>build -t VS2015x86 -p RobinPkg\RobinPkg.dsc \
-m RobinPkg\Drivers\BlankDrv\BlankDrv.inf -a IA32

2 测试驱动

与服务型驱动不同,在BlankDrv中提供了卸载驱动的功能。因此,可以使用unload命令卸载驱动。

由于此框架并没有指定硬件设备,因此仍然可以在EDK2的模拟器中测试。测试中除了用到

UEFI开发探索67介绍的UEFI Shell命令load和dh外,还要用到命令drivers和unload,这两个命令的使用方法介绍如下。

  • drivers命令用于列出系统的驱动,其语法格式为:

drivers [-l XXX] [-sfo]

参数-l用于指定所使用的语言代码,比如ISO 639-2;参数-sfo使用标准格式化输出显示信息。drivers命令是以列表的形式,将符合UEFI驱动模型的驱动信息打印出来。打印的信息中,包括如下项的显示:

DRV项表示驱动句柄的编号;
VERSION项表示驱动的版本号;
TYPE项表示驱动的类型,B为总线驱动,D为色板驱动;
CFG项表示该驱动是否支持Driver Configuration Protocol;
DIAG项表示该驱动是否支持Driver Diagnostics Protocol;
#D项显示该驱动控制的设备的数量;
#C项表示子设备的数量;
DRIVER NAME项表示驱动名称;
IMAGE PATH表示驱动来源。 

  • unload命令用于卸载UEFI驱动,其语法格式为:

unload [-n] [-v|-verbose] Handle

此命令用于将驱动从内存中清除,所要清除的驱动,由其加载后的句柄表示。unload命令提供了两种参数,“-n”表示执行过程中跳过所有提示信息;“-v”则在执行过程中列出指定句柄相关的信息,包括驱动文件名、驱动文件的符号文件、镜像加载基地址等。

启动EDK2的模拟器,使用load命令加载驱动,然后可以使用drivers或dh命令查看驱动加载情况,最后使用unload命令卸载驱动。运行情况示例2所示。

【示例2】在EDK2模拟器中测试BlankDrv

FS0:\> load BlankDrv.efi   //加载驱动
Image ‘FS0:\BlankDrv.efi’ loaded at 6211000  – Success
FS0:\> drviers            //列举系统中所有驱动
……                          //其他驱动信息
87 0000000A ? – –  –  – My Blank Driver               \BlankDrv.efi
FS0:\> dh 87              //显示设备句柄的信息
87: ComponentName2 ComponentName DriverBinding ImageDevicePath
(..8881,00000000)\BlankDrv.efi) LoadImage(\BlankDrv.efi)
FS0:\> unload 87        //卸载驱动
Unload – Handle [52E0290].  [y/n]?
y
Unload – Handle [52E0290] Result Success

至此,对UEFI驱动模型介绍完成。BlankDrv并没有实现什么实际的功能,主要是提供了一个比较完整的驱动框架。下一篇中,以一个开源的UEFI驱动GopRotate为例,为其构建测试用的UEFI应用,演示有趣的屏幕变换功能。

为方便大家进行实验,BlankDrv的源码放在了gitee仓库中了。

Gitee地址:https://gitee.com/luobing4365/uefi-exolorer
项目代码位于:/
69 BlankDrv/BlankDrv.zip

54 total views, 1 views today

210c9a4d410d265665667a36fbe0f529?s=49&d=identicon&r=g作者 罗冰(Robin)发布于 2021年1月16日2021年1月21日分类 BIOS/UEFI


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK