UEFI Console Splitter 2nd
来源:互联网 发布:网络空间独立宣言 编辑:程序博客网 时间:2024/06/16 01:22
为了巩固对 Console Splitter 这只driver 认知上的巩固,这么篇文章我们会写一个虚拟的简单的输入设备。具体的思路是以下几点:
- 经过上篇文章对Splitter 这只driver 的分析,我们知道,如果想让Splitter 能够管理一个device,那么这个device至少应该安装了gEfiConsoleInDeviceGuid && gEfiSimpleTextInProtocolGuid 所以我们应该让我们这个device被安装上这两个GUID。
- gEfiSimpleTextInProtocolGuid 是每个driver 独立实现自己的protocol 所以这个GUID我们可以自己手动给安装。但是gEfiConsoleInDeviceGuid 是另外一只driver (ConPlatform.c )给自己能support的device handle上安装的GUID ,那么ConPlatromr.c 这只driver support 哪些device呢 。我们上篇也做过简单地介绍就ConPlatform 这只driver 它能够管理的device 是这些device handle 上安装了 gEfiSimpleTextInProtocolGuid, gDevicePathProtocolGuid, 并且该device的path 记录ConIn在这个变量里(热插拔设备除外)。
- 因为在应用程序里,我们用ReadKeyStorke 和 WaitForKey,所以我们要给这个虚拟device 实例化一个SimpleTextInProtocol 。为了让程序尽量简单,我们只是不停的汇报一个字母‘A’。
经过上述分析,我们知道我们这个device 上要手动安装一个SimpleTextInProtocol 和 EfiDevicePathProtocol (这个path 必须在ConIn 里,或者是一个热插拔的device path)然后我们EDK 里的ConPlatform.c 这只driver 就会给这个虚拟的device 安装一个gEfiConsoleInDeviceGuid 最后,这个device就会满足我们Con Splitter.c 这只driver support函数的要求,我们虚拟device 就会动起来。可能说起来会有点啰嗦,看个流程图就一目了然了。
(待画,第一次用CSDN 不太会画流程图)
看code
#include <Uefi.h>#include <Library/UefiBootServicesTableLib.h>#include <Library/DebugLib.h>#include <Library/UefiLib.h>#include <Library/BaseLib.h>#include <Protocol/SimpleTextIn.h>#include <Library/UefiDriverEntryPoint.h>#include <Protocol/DevicePath.h>#include <Library/DevicePathLib.h>#include "NonDriver.h"VHidDev *gVirHidDev;EFI_KEY Buffer[10];UINT8 Keyflag;VOIDEFIAPICallBack ( IN EFI_EVENT Event, IN VOID *Context ){ gBS->SignalEvent (Event);}STATIC vPath_T gvHidDevPath = { { { MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP, { (UINT8) (sizeof (USB_WWID_DEVICE_PATH)), (UINT8) (sizeof (USB_WWID_DEVICE_PATH) >> 8) } }, 0x01, 0xaa, 0xbb }, { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { (UINT8) (END_DEVICE_PATH_LENGTH), (UINT8) (END_DEVICE_PATH_LENGTH >> 8) } }};EFI_STATUSEFIAPIvReadKeyStroke ( IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key ){ Key->UnicodeChar = L'A'; return EFI_SUCCESS; }EFI_STATUSEFIAPITestNonDriver ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ){ EFI_STATUS Status; DEBUG((EFI_D_INFO, " NonDriver Test Start\n")); Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (VHidDev), (void **)&gVirHidDev ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "allocate pool %r\n", Status)); return EFI_OUT_OF_RESOURCES; } gVirHidDev->vConIn.Reset = NULL; gVirHidDev->vConIn.ReadKeyStroke = vReadKeyStroke; gVirHidDev->Handle = NULL; Status = gBS->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY, CallBack, NULL, &gVirHidDev->vConIn.WaitForKey ); if (EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR, "Create Event %r\n", Status)); return Status; } Status = gBS->InstallMultipleProtocolInterfaces( &gVirHidDev->Handle, &gEfiDevicePathProtocolGuid, &gvHidDevPath, &gEfiSimpleTextInProtocolGuid, &gVirHidDev->vConIn, NULL ); return EFI_SUCCESS;}
其实有了上述分析,我们看code就会很容易,简单地分析一下。首先我们先给我们的虚拟device分配一个地址空间,我们会实例化一个SimpleTextInProtocol在ReadKeyStroke函数里只是简单地向Splitter driver 汇报字母A。然后我们会创建一个Event,上篇我们提到过,如果我们想读用户输入,我们会把程序阻塞住,直到这个Event被Signal起来。所以我们在虚拟device里把这个Event的Callback只是简单地实现一个Signal Event,好让用户程序结束阻塞,继续运行。最后我们会给这个device安装一个device path protocol 好让蒙过ConPlatform.c 这只driver检查那一关,为了简单,我们把这个device模拟成一个USB WWID 那么就不会对这个device path 和 ConIn 记录里的path 进行比对。 主函数大概就是这样,如果想下载code,下面是链接地址
程序下载地址
最后我们可以把这个虚拟device 加入EDK source code 里,我这边是用Linux 下的模拟器,所以把.inf 档放进Emulator.dsc 和 Emulator.fdf 里,然后开虚拟我们就会看到屏幕上一直出现字符A。
- UEFI Console Splitter 2nd
- UEFI Console Splitter
- CUE Splitter v1.2
- Using the MPEG-2 Splitter
- Cstyle的UEFI导读之Text Console Driver Stack
- LAV Filter 源代码分析 2: LAV Splitter
- UEFI
- 2nd Day
- 2nd Night
- Code Complete 2nd
- 2nd post
- September 2nd Wednesday
- November 2nd Monday
- poj-2159 2nd
- poj-1083 2nd
- 2nd place Understan
- BestCoder 2nd Anniversary
- BestCoder 2nd Anniversary
- hdu 1466计算直线的交点数
- 欢迎使用CSDN-markdown编辑器
- pAdPt-0 Android平台(jdk + AS)搭建
- 【算法】快速排序/数组第K小的元素
- SSH协议与SSH免登陆
- UEFI Console Splitter 2nd
- Programming with OC --Defining Classes
- C#学习笔记 委托
- hdfs shell命令
- iOS中UIWebview中网页宽度自适应的问题
- leetcode之Range Sum Query - Immutable
- lintcode: Sqrt(x)
- Linux命令(文件处理命令)
- hdu 1394 Minimum Inversion Number 最小逆序数