系统表6部分:
1.表头
typedef struct {
UINT64 Signature;
UINT32 Revision;
UINT32 HeaderSize;
UINT32 CRC32;
UINT32 Reserved;
} EFI_TABLE_HEADER;
2.固件信息
3.标准输入,输出,错误控制台
typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL {
EFI_INPUT_RESET Reset;//清除输入流内容,将输入流置空。
EFI_INPUT_READ_KEY ReadKeyStroke;//按键事件发生后读取输入的字符
EFI_EVENT WaitForKey;//等待事件
} EFI_SIMPLE_TEXT_INPUT_PROTOCOL;//*ConIn用来控制输入
typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
EFI_TEXT_RESET Reset;//函数重置文本输出设备硬件
EFI_TEXT_STRING OutputString;//输出
EFI_TEXT_TEST_STRING TestString;//确认所有字符能否输出
EFI_TEXT_QUERY_MODE QueryMode;//返回输出设备支持的可用文本模式的信息。
EFI_TEXT_SET_MODE SetMode;//将输出设备设置为指定模式。
EFI_TEXT_SET_ATTRIBUTE SetAttribute;//Sets the background and foreground colors for
//theOutputString() and ClearScreen() functions
EFI_TEXT_CLEAR_SCREEN ClearScreen;//清空屏幕
EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition;//设置光标位置
EFI_TEXT_ENABLE_CURSOR EnableCursor;//光标是否可视
SIMPLE_TEXT_OUTPUT_MODE *Mode;
} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;//*ConOut 用来控制输出
ConIn用于从输入控制台ConsoleInHandle读取字符,ConOut用于向输出控制台ConsoleOutHandle输出字符串,StdErr用于向标准错误控制台StandardErrorHandle输出字符串。
4.启动服务表
提供八类服务。其中内存管理:跨页常用于内核和驱动开发。
生存期:DxeMain与gBS->ExitBootServices之间。
5.运行时服务表
生存期:进入DXE阶段直到操作系统结束,向上层提供服务。
时间服务:读取/设置硬件时间,读取/设置唤醒定时器。
系统变量:读取,新建,更新,遍历。系统变量中可设置属性,可写入非易失性寄存器,关机后仍有效。
6.系统配置表
因为UEFI只有一个地址空间所以可以直接使用系统表。
鼠标位置抓取
用于获取鼠标输入的是简单指针协议(Simple Pointer Protocol),此指针指的是指针设备而不是内存。
定义:
typedef struct _EFI_SIMPLE_POINTER_PROTOCOL {
EFI_SIMPLE_POINTER_RESET Reset;//重置设备
EFI_SIMPLE_POINTER_GET_STATE GetState;//检索指针设备的当前状态。X,Y,X,左键,右键。对一般鼠标
//而言z恒为0.
EFI_EVENT WaitForInput;//等待鼠标输入事件。
EFI_SIMPLE_INPUT_MODE *Mode;
} EFI_SIMPLE_POINTER_PROTOCOL;
程序原理:首先用 LocateProtocol 取得EFI_SIMPLE_POINTER_PROTOCOL (这里假设系统中只有一个),然后做一次 Reset ,通过这个动作也确定设备是否可以使用。之后,不断使用 GetState 轮询,如果发现前后两次获得的信息不同那么就输出解析结果,打印当前鼠标的状态。之后通过键盘退出。
EFI_STATUS
testMouseSimple()
{
EFI_STATUS Status;
EFI_SIMPLE_POINTER_PROTOCOL* mouse = 0;
EFI_SIMPLE_POINTER_STATE State;
EFI_EVENT events[2]; // = {0, gST->ConIn->WaitForKey};//键盘,鼠标事件
//显示光标
gST->ConOut->EnableCursor (gST->ConOut, TRUE);
//根据GUID找出鼠标设备
Status = gBS->LocateProtocol(
&gEfiSimplePointerProtocolGuid,
NULL,
(VOID**)&mouse
);
// 重置鼠标设备
Status = mouse->Reset(mouse, TRUE);
// 将鼠标事件放到等待事件数组
events[0] = mouse->WaitForInput;
// 将键盘事件放到等待数组
events[1] = gST->ConIn->WaitForKey;
while(1)
{
EFI_INPUT_KEY Key;
UINTN index;
// 等待events中的任一事件发生
Status = gBS->WaitForEvent(2, events, &index);
if(index == 0){
// 获取鼠标状态并输出
Status = mouse->GetState(mouse, &State);
Print(L"X:%d Y:%d Z:%d L:%d R:%d\n",
State.RelativeMovementX,
State.RelativeMovementY,
State.RelativeMovementZ,
State.LeftButton,
State.RightButton
);
} else{
//按键事件发生后读取键盘
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
// 按’q’键退出
if (Key.UnicodeChar == 'q')
break;
}
}
return EFI_SUCCESS;
}