当前位置:网站首页 > R语言数据分析 > 正文

vgasave驱动(vgadriver是什么驱动)



从功能上划分,UEFI驱动可以分为以下类别:

  1. 符合UEFI驱动模型的驱动,包括总线驱动、设备驱动和混合驱动,一般用来驱动对应的硬件设备
  2. 服务性驱动,这类驱动不管理任何设备,一般用来产生Protocol
  3. 初始化驱动,不产生任何句柄,也不增加任何Protocol到系统数据库,主要用来进行一些初始化操作,操作完就会从系统内存中卸载
  4. 根桥型驱动,用来初始化平台上的根桥控制器,并产生一个设备地址Protocol,以及访问总线设备的Protocol,一般通过总线驱动访问设备。

在UEFI模块中驱动有两种类型:DXE_DRIVER 和 UEFI DRIVER,

驱动程序包含有硬件设备的信息,有了这些信息计算机就可以和设备进行通信,一个完整的驱动框架至少要完成以下任务:

  1. 找到支持的硬件设备
  2. 安装驱动到此硬件设备
  3. 从硬件设备卸载驱动

UEFI驱动模型的核心是通过EFI Driver Binding Protocol管理驱动程序,一个完整的驱动程序包含两个核心部分:EFI Driver Binding Protocol以及驱动服务本身。作为一个用户友好的驱动程序,通常它还要包括一个EFI Component Name Protocol。

首先来看UEFI驱动模型是如何管理驱动的。在UEFI驱动的入口函数函数中,安装EFI Driver Binding Protocol(EDBP)到某个Handle(大部分是自身,即ImageHandle),这个EBDP实例会常驻内存,用于驱动的安装和卸载。使用EBDP使得我们可以多次操作(查找设备、安装卸载)驱动。其代码原型为:

 
  

(1)Supported函数

 Supported函数用于检查一个设备控制器是否支持该驱动。其函数原型为:

 
  

(2)Start函数

 Start函数用来将驱动安装到设备上并启动硬件设备,在函数中最重要的事情是调用InstallProtocolInterface()或者InstallMutipleProtocolInterface()在ControllerHandle上安装驱动protocol,其函数原型为:

 
  

(3)Stop函数

 Stop函数用于停止硬件设备并卸载驱动(调用UninstallProtocolInterface()或UninstallMultipleProtocolInterfaces()从ControllerHandle卸载驱动协议)。其代码原型为:

 
  

UEFI驱动程序框架:

 
  

 加载驱动的整体过程为:首先在Shell中使用命令load将驱动文件加载到内存,加载后UEFI会调用gBS->StartImage()执行DriverImage的入口函数,在入口函数里面,Driver Binding被加载到Handle上(Driver Image handle或者其它的Controller handle),然后UEFI会遍历所有的控制器,为每个控制器调用CoreConnectSingleController中会调用EDBP的Supported函数测试驱动是否支持该控制器,如果支持,则调用Start()安装驱动。

UEFI驱动加载后,会枚举设备,然后调用UEFI Driver Binding Protocol(EFI_DRIVER_BINGDING_PROTOCOL) 的support()函数,用来判断驱动是否支持枚举的这个Controllerhandle,如果支持就调用EFI_DRIVER_BINGDING_PROTOCOL的Start()函数,这个函数申请内存资源和初始化内部变量,安装需要的Protocol和初始化硬件。

通常驱动都还有一个可打印的名字,便于向用户显示驱动的信息。这个可打印名字是由EFI Component Name Protocol (ECNP)或EFI Component Name2 Protocol (ECN2P)提供的,这两个不是驱动必需的Protocol,但建议驱动开发者提供这个protocol,其函数原型为

 
  
 
  

驱动可以分为两部分,一部分是硬件相关的部分,这部分是驱动的内容,用于硬件设备,为用户提供服务,以协议的形式,如DiskIO、BlockIo;另一部分是驱动的框架部分,需要实现Driver Binding Protocol,主要是三个接口(Supported、Start和Stop),这部分用于实现框架部分。

以AC97为例来介绍驱动的编写:

驱动的硬件部分主要是驱动的内容,定义PROTOCOL,提供PROTOCOL中定义的服务函数的原型、PROTOCOL的私有数据结构体、PROTOCOL的服务函数的实现 

audio.h 定义EFI_AUDIO_ROTOCOL相关结构体,

定义EFI_AUDIO_PROTOCOL的GUID,

定义protocol提供的服务的函数原型,其中包括Reset、Play、Volume

在accdriver.c中,定义 用于标识音频播放的上下文的数据结构,一般命名为X_PRIVATE_DATA。在上下文中,要包含一个驱动实例,以及其他的设备相关信息。具体到EFI_AUDIO_PROTOCOL,在上下文中要包含EFI_AUDIO_PROTOCOL实例、设备的EFI_PCI_IO_PROTOCOL实例和BufferDescriptor:

定义一个私有数据结构体,用来存储PROTOCOL的私有数据,通过建立私有数据的结构,并将This指针包含其中,所有的接口函数都可以通过This指针发现私有数据的内存位置,从而获得需要共享的私有数据。

定义一个EFI_AUDIO_PROTOCOL模板,这个模板用于初始化EFI_AUDIO_PROTOCOL实例:

定义AUDIO_PRIVATE_DATA_FROM_THIS宏,用于根据This指针找到设备上下文

 
  

 下面实现EFI_AUDIO_PROTOCOL中定义的三个服务,每个成员函数(服务)的第一个参数是This指针,在函数里面根据This指针获得上下文Private,然后根据上下文执行相应操作。

 

 

 驱动的框架部分主要完成三个功能:

  1. 实现EFI_DRIVER_BINDING_PROTOCOL(EDBP)
  2. 实现Component Name Protocol 和 Component Name2 Protocol
  3. 在模块的初始化函数中安装EDBP、ECNP和ECN2P

(1)实现EFI_DRIVER_BINDING_PROTOCOL(EDBP) 

 关键是实现EDBP的三个服务:Surpported、Start和Stop。

首先产生一个EDBP实例并初始化:

 然后实现三个核心服务(Supported、Start和Stop)

实现Supported服务

函数AC97DriverBindingSupported实现了Supported服务,当检测的设备是AC97控制器时,返回EFI_SUCCESS,否则返回错误代码。其处理流程为:

        判断Controller是否有EFI_PCI_IO_PROTOCOL,若没有,则返回错误

        读取PCI配置空间,根据配置空间的ClassCode判断设备是否是AC97驱动器

实现Start服务

 AC97DriverBindingStart实现了Start服务,其功能是启动AC97设备并安装EFI_AUDIO_PROTOCOL。启动过程包括三个部分:

        打开EFI_PCI_IO_PROTOCOL

        为AC97控制器上下文分配内存

        在ControllerHandle上安装AC97驱动Protocol,即EFI_AUDIO_PROTOCOL

实现Stop服务

 AC97DriverBindingStop函数实现了Stop服务,同Start函数相对应,其主要过程包括三部分:

        关闭设备控制器上的PCI IO Protocol

        卸载ControllerHandle上的Audio IO Protocol

        释放资源

(2)实现ECNP和ECN2P

作为一个完整的、对用户友好的驱动程序,我们还要提供ECNP和ECN2P

(3)安装EDBP、ENCP和EN2CP

最后要在模块的入口函数内安装EDBP、ENCP和ECN2P这三个Protocol

 

EfiLibInstallDriverBindingComponentName2是UefiLib提供的用于安装Driver Binding Protocol、Component Name Protocol 及 Component Name2 Protocol的函数

然后编写AC97驱动的工程文件 

到此这篇vgasave驱动(vgadriver是什么驱动)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • orecal甲骨文(orecal甲骨文是干嘛的)2025-08-14 10:18:04
  • spring的入门程序详细过程(spring integration入门)2025-08-14 10:18:04
  • spring教程 w3school(spring教程视频推荐)2025-08-14 10:18:04
  • ar怎么读英语(architect怎么读英语)2025-08-14 10:18:04
  • entware命令(enable命令的作用)2025-08-14 10:18:04
  • emr和aes区别(emea和ema)2025-08-14 10:18:04
  • ifstream读取文件相对路径怎么写(ifstream 读取文件)2025-08-14 10:18:04
  • ifstream读取文件相对路径怎么写(ifstream fin读取)2025-08-14 10:18:04
  • redis 连不上(redis 连不上 wsl)2025-08-14 10:18:04
  • bytebuffer.position()的用法(bytebuffer.duplicate)2025-08-14 10:18:04
  • 全屏图片