admin 管理员组

文章数量: 1184232

Dxe Driver可以视作UEFI中的一个服务,在entry中通过protocol安装自己的服务,在Bds等位置通过locate protocol使用该服务,不必依赖与具体的硬件。当需要封装某个设备/控制器或总线的时候,对应于具体的物理实现,需要用到UEFI Driver的模型实现。UEFI Driver模型实现设备/总线的检测,安装,卸载,更新,启动,停止等;一个Driver可能适配多个设备,一个设备可能连接管理多个子设备等,因此UEFI Driver还可以多次安装。以下从GraphicsOutput设备为入口来解读UEFI driver的源码。

1. UEFI Driver的实现

源码路径为MdeModulePkg\Universal\Console\GraphicsOutputDxe\GraphicsOutput.c。从driver的入口开始:

InitializeGraphicsOutput (
  IN EFI_HANDLE                        ImageHandle,
  IN EFI_SYSTEM_TABLE                  *SystemTable
  )
{
  // 从PEI阶段的HOB中获取Graphic的信息,如Edid等
  HobStart = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid);
  // 将mGraphicsOutputDriverBinding 安装到Dxe环境里面
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &mGraphicsOutputDriverBinding,
             ImageHandle,
             &mGraphicsOutputComponentName,
             &mGraphicsOutputComponentName2
             );
  return Status;
}

EfiLibInstallDriverBindingComponentName2()根据入参以及实际pcd的配置安装driver的protocol和名字等信息;

       Status = gBS->InstallMultipleProtocolInterfaces (
                       &DriverBinding->DriverBindingHandle,
                       &gEfiDriverBindingProtocolGuid, DriverBinding,
                       &gEfiComponentNameProtocolGuid, ComponentName,
                       &gEfiComponentName2ProtocolGuid, ComponentName2,
                       NULL
                       );

驱动模型的核心通过EFI_DRIVER_BINDING_PROTOCOL实现,通过该protocol判断一个driver是否支持某个控制器,以及启动和停止该控制器;

struct _EFI_DRIVER_BINDING_PROTOCOL {

EFI_DRIVER_BINDING_SUPPORTED  Supported;  //判断driver是否支持该控制器

EFI_DRIVER_BINDING_START      Start;  //安装driver到设备/总线控制器

EFI_DRIVER_BINDING_STOP       Stop;  //卸载设备/总线控制器driver

UINT32                        Version;

EFI_HANDLE                    ImageHandle;   //当前driver的image handle

EFI_HANDLE                    DriverBindingHandle;  //该protocol应该安装到的handle,大部分时候与ImageHandle相同,如果

};

graphicsOutput的实现为:

EFI_DRIVER_BINDING_PROTOCOL mGraphicsOutputDriverBinding = {
  GraphicsOutputDriverBindingSupported,
  GraphicsOutputDriverBindingStart,
  GraphicsOutputDriverBindingStop,
  0x10,
  NULL,
  NULL
};

EFI_COMPONENT_NAME_PROTOCOL/EFI_COMPONENT_NAME2_PROTOCOL 描述Driver的名字,提供获取driver名字和控制器名字的接口,支持的语言类型;

struct _EFI_COMPONENT_NAME2_PROTOCOL {

EFI_COMPONENT_NAME2_GET_DRIVER_NAME      GetDriverName;

EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME  GetControllerName;

CHAR8                                    *SupportedLanguages;

};

graphicsOutput的实现为:

// EFI Component Name Protocol
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  mGraphicsOutputComponentName = {
  GraphicsOutputComponentNameGetDriverName,
  GraphicsOutputComponentNameGetControllerName,
  "eng"
};
// EFI Component Name 2 Protocol
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mGraphicsOutputComponentName2 = {
  (EFI_COMPONENT_NAME2_

本文标签: 是否支持 安装 编程