uefi driver
来源:互联网 发布:淘宝刷手一天真实收入 编辑:程序博客网 时间:2024/06/11 02:56
uefi drivers 是指在inf中将MODULE_TYPE指定为UEFI_DRIVER。例如inf的例子
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DiskIoDxe
MODULE_UNI_FILE = DiskIoDxe.uni
FILE_GUID = 6B38F7B4-AD98-40e9-9093-ACA2B5A253C4
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeDiskIo
从这个inf中可以看到这个uefi的driver name为DiskIoDxe,其入口函数为InitializeDiskIo
在uefi driver中一般会用到EFI_DRIVER_BINDING_PROTOCOL/EFI_COMPONENT_NAME_PROTOCOL/EFI_COMPONENT_NAME2_PROTOCOL/EFI_DRIVER_DIAGNOSTICS2_PROTOCOL 这四个protocol.
如下所示:
EFI_STATUS
EFIAPI
InitializeDiskIo (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install driver model protocol(s).
//
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gDiskIoDriverBinding,
ImageHandle,
&gDiskIoComponentName,
&gDiskIoComponentName2
);
ASSERT_EFI_ERROR (Status);
return Status;
}
在其入口函数InitializeDiskIo 中通过EfiLibInstallDriverBindingComponentName2 注册driver,
EFI_STATUS
EFIAPI
EfiLibInstallDriverBindingComponentName2 (
IN CONST EFI_HANDLE ImageHandle,
IN CONST EFI_SYSTEM_TABLE *SystemTable,
IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
IN EFI_HANDLE DriverBindingHandle,
IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL
IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL
)
{
EFI_STATUS Status;
ASSERT (DriverBinding != NULL);
//
// Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol
//
DriverBinding->ImageHandle = ImageHandle;
DriverBinding->DriverBindingHandle = DriverBindingHandle;
if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {
if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentName2ProtocolGuid, ComponentName2,
NULL
);
}
} else {
if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentNameProtocolGuid, ComponentName,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentNameProtocolGuid, ComponentName,
&gEfiComponentName2ProtocolGuid, ComponentName2,
NULL
);
}
}
//
// ASSERT if the call to InstallMultipleProtocolInterfaces() failed
//
ASSERT_EFI_ERROR (Status);
return Status;
}
我们这里的ComponentName和ComponentName2 都不是NULL,因此走else的case,即
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentName2ProtocolGuid, ComponentName2,
NULL
);
通过gBS的InstallMultipleProtocolInterfaces,向DriverBinding->DriverBindingHandle注册两个guid。这里的DriverBinding->DriverBindingHandle也是在EfiLibInstallDriverBindingComponentName2 中赋值
DriverBinding->ImageHandle = ImageHandle;
DriverBinding->DriverBindingHandle = DriverBindingHandle;
这里的DriverBindingHandle也就对应InitializeDiskIo中的ImageHandle也就是这个binary本身.
这样当调用 gBS->loadImage将驱动文件加载到内存后,再调用 Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);就会call到入口函数
StartImage从是通过 Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);调用到入口函数的,针对本例就是调用InitializeDiskIo。
而InitializeDiskIo 最重要的是实现了gDiskIoDriverBinding,
EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding = {
DiskIoDriverBindingSupported,
DiskIoDriverBindingStart,
DiskIoDriverBindingStop,
0xa,
NULL,
NULL
};
gDiskIoDriverBinding 实现了三个函数,DiskIoDriverBindingSupported用与见识是否支持这个driver,如果支持的话,就调用DiskIoDriverBindingStart,在DiskIoDriverBindingStart 中就可以将驱动安装到设备上并启动硬件设备
DiskIoDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
//
// Install protocol interfaces for the Disk IO device.
//
if (Instance->BlockIo2 != NULL) {
Status = gBS->InstallMultipleProtocolInterfaces (
&ControllerHandle,
&gEfiDiskIoProtocolGuid, &Instance->DiskIo,
&gEfiDiskIo2ProtocolGuid, &Instance->DiskIo2,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
&ControllerHandle,
&gEfiDiskIoProtocolGuid, &Instance->DiskIo,
NULL
);
}
}
在DiskIoDriverBindingStart 中一般会调用InstallMultipleProtocolInterfaces或者InstallProtocolInterfaces来在ControllerHandle 上安装protocol.
后面的其他程序就可以通过gEfiDiskIoProtocolGuid 或者 gEfiDiskIo2ProtocolGuid来得到Instance->DiskIo或者Instance->DiskIo2。
例如下面的例子
Status = gBS->OpenProtocol (
Entry->PartitionHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
ASSERT_EFI_ERROR (Status);
Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image);
就通过gEfiDiskIoProtocolGuid 来调用DiskIo->WriteDisk
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DiskIoDxe
MODULE_UNI_FILE = DiskIoDxe.uni
FILE_GUID = 6B38F7B4-AD98-40e9-9093-ACA2B5A253C4
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeDiskIo
从这个inf中可以看到这个uefi的driver name为DiskIoDxe,其入口函数为InitializeDiskIo
在uefi driver中一般会用到EFI_DRIVER_BINDING_PROTOCOL/EFI_COMPONENT_NAME_PROTOCOL/EFI_COMPONENT_NAME2_PROTOCOL/EFI_DRIVER_DIAGNOSTICS2_PROTOCOL 这四个protocol.
如下所示:
EFI_STATUS
EFIAPI
InitializeDiskIo (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install driver model protocol(s).
//
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gDiskIoDriverBinding,
ImageHandle,
&gDiskIoComponentName,
&gDiskIoComponentName2
);
ASSERT_EFI_ERROR (Status);
return Status;
}
在其入口函数InitializeDiskIo 中通过EfiLibInstallDriverBindingComponentName2 注册driver,
EFI_STATUS
EFIAPI
EfiLibInstallDriverBindingComponentName2 (
IN CONST EFI_HANDLE ImageHandle,
IN CONST EFI_SYSTEM_TABLE *SystemTable,
IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
IN EFI_HANDLE DriverBindingHandle,
IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL
IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL
)
{
EFI_STATUS Status;
ASSERT (DriverBinding != NULL);
//
// Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol
//
DriverBinding->ImageHandle = ImageHandle;
DriverBinding->DriverBindingHandle = DriverBindingHandle;
if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {
if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentName2ProtocolGuid, ComponentName2,
NULL
);
}
} else {
if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentNameProtocolGuid, ComponentName,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentNameProtocolGuid, ComponentName,
&gEfiComponentName2ProtocolGuid, ComponentName2,
NULL
);
}
}
//
// ASSERT if the call to InstallMultipleProtocolInterfaces() failed
//
ASSERT_EFI_ERROR (Status);
return Status;
}
我们这里的ComponentName和ComponentName2 都不是NULL,因此走else的case,即
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverBinding->DriverBindingHandle,
&gEfiDriverBindingProtocolGuid, DriverBinding,
&gEfiComponentName2ProtocolGuid, ComponentName2,
NULL
);
通过gBS的InstallMultipleProtocolInterfaces,向DriverBinding->DriverBindingHandle注册两个guid。这里的DriverBinding->DriverBindingHandle也是在EfiLibInstallDriverBindingComponentName2 中赋值
DriverBinding->ImageHandle = ImageHandle;
DriverBinding->DriverBindingHandle = DriverBindingHandle;
这里的DriverBindingHandle也就对应InitializeDiskIo中的ImageHandle也就是这个binary本身.
这样当调用 gBS->loadImage将驱动文件加载到内存后,再调用 Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);就会call到入口函数
StartImage从是通过 Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);调用到入口函数的,针对本例就是调用InitializeDiskIo。
而InitializeDiskIo 最重要的是实现了gDiskIoDriverBinding,
EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding = {
DiskIoDriverBindingSupported,
DiskIoDriverBindingStart,
DiskIoDriverBindingStop,
0xa,
NULL,
NULL
};
gDiskIoDriverBinding 实现了三个函数,DiskIoDriverBindingSupported用与见识是否支持这个driver,如果支持的话,就调用DiskIoDriverBindingStart,在DiskIoDriverBindingStart 中就可以将驱动安装到设备上并启动硬件设备
DiskIoDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
//
// Install protocol interfaces for the Disk IO device.
//
if (Instance->BlockIo2 != NULL) {
Status = gBS->InstallMultipleProtocolInterfaces (
&ControllerHandle,
&gEfiDiskIoProtocolGuid, &Instance->DiskIo,
&gEfiDiskIo2ProtocolGuid, &Instance->DiskIo2,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
&ControllerHandle,
&gEfiDiskIoProtocolGuid, &Instance->DiskIo,
NULL
);
}
}
在DiskIoDriverBindingStart 中一般会调用InstallMultipleProtocolInterfaces或者InstallProtocolInterfaces来在ControllerHandle 上安装protocol.
后面的其他程序就可以通过gEfiDiskIoProtocolGuid 或者 gEfiDiskIo2ProtocolGuid来得到Instance->DiskIo或者Instance->DiskIo2。
例如下面的例子
Status = gBS->OpenProtocol (
Entry->PartitionHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
ASSERT_EFI_ERROR (Status);
Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image);
就通过gEfiDiskIoProtocolGuid 来调用DiskIo->WriteDisk
阅读全文
0 0
- uefi driver
- UEFI Drivers & UEFI Driver Model
- UEFI Drivers & UEFI Driver Model
- UEFI Drivers & UEFI Driver Model
- UEFI Driver编写
- UEFI driver & Option Rom
- UEFI PCI Bus Driver分析
- Cstyle的UEFI导读之UEFI Driver Configuration
- Cstyle的UEFI导读之Driver Diagnostics
- UEFI PCI Host Bridge Driver分析
- Cstyle的UEFI导读之Driver中的私有数据结构
- Cstyle的UEFI导读之PCI Driver Stack
- Cstyle的UEFI导读之USB Driver Stack
- Cstyle的UEFI导读之ATA Driver Stack
- Cstyle的UEFI导读之Mass Storage Driver Stack
- Cstyle的UEFI导读之Load File Driver Protocol
- Cstyle的UEFI导读之Text Console Driver Stack
- Cstyle的UEFI导读之Graphics Driver Stack
- 如何解决ios SIGPIPE 导致的崩溃
- C++:函数指针
- RedHat下安装Mysql及字符集配置
- 【正解】Openjudge 至少有多少只恼人的大青蛙 (dfs 剪枝 好题)
- 2017年最流行的15个数据科学Python库
- uefi driver
- 学习博客
- 关于运算符(三目运算符)和运算过程中的优先关系
- 第三方模块的手动安装
- error C2084 函数“”已有主体
- 【Android】使用Kotlin在Android Studio上开发App
- 文章标题
- Android asynctask源码跟踪(android 4.42 API 19)
- 我要长高 UESTC CDOJ