GOP协议文档可以参考:
https://uefi.org/specs/UEFI/2.11/12_Protocols_Console_Support.html#graphics-output-protocol
GOP是一种UEFI协议规定的统一的图形界面协议
Blt Buffer
这是GOP中最基本的图像操作用到的帧缓冲区,它是一种针对不同显示器硬件的软件抽象封装。Buffer将显示器抽象为一个像素组,每个像素在屏幕上的位置由X、Y坐标定义,每个点都代表一个32位的像素值。像素值的颜色分量使用EFI_GRAPHICS_OUTPUT_BLT_PIXEL中定义的PixelBlueGreenRedReserved8BitPerColor的格式,在代表红、绿、蓝三个颜色分量的字节值代表颜色强度,强度取值范围为 0(最低强度)到 255(最高强度)。

GUID
这是用于EFI系统表进行locate定位时的标识码,它的结构如下:
#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
{0x9042a9de,0x23dc,0x4a38,\
{0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a}}Protocol Interface
这是用于协议调用的接口,它的struct结构如下:
typedef struct EFI_GRAPHICS_OUTPUT_PROTCOL {
EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
} EFI_GRAPHICS_OUTPUT_PROTOCOL;其中各个参数的含义为:
1、QueryMode
返回图形设备及当前活动的视频输出设备所支持的可用图形模式的信息,其具体结构为:
typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
);这里的ModeNumber是一种显示器描述,给的数值也是一个最大值。比如,如果获取到的MaxMode为5,那么就可以SetMode方式将其设置为0、1、2、3、4。你可以通过这个函数去获取显示器实际的mode情况,也可以通过*Mode的指针直接去解析当前内存中保存的设备情况。
2、SetMode
将视频设备设置为指定模式,并将输出显示器的可见区域清除为黑色,其具体结构为:
typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
);具体实现由UEFI固件内部完成,跟实际从显示器获取到的信息有直接关系。
3、Blt
用于在视频设备帧缓冲区上进行绘制的软件抽象层,其具体定义为:
typedef struct {
UINT8 Blue;
UINT8 Green;
UINT8 Red;
UINT8 Reserved;
} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
typedef enum {
EfiBltVideoFill,
EfiBltVideoToBltBuffer,
EfiBltBufferToVideo,
EfiBltVideoToVideo,
EfiGraphicsOutputBltOperationMax
} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta
);在blt这里,具体定义了很多屏幕设置相关的具体参数。
*BltBuffer:代表一个指向PIXEL数组的指针
BltOperation:代表一个描述具体操作类型的枚举,BltOperation为EfiBltVideoFill时代表使用单一颜色填满整个区域、EfiBltVideoToBltBuffer代表当前Video传到Buffer、EfiBltBufferToVideo指向分配的数组指针、EfiBltVideoToVideo显存内部进行数据复制,可以将上一个区域的图像复制到下一个区域、EfiGraphicsOutputBltOperationMax代表枚举的一种边界值,用于验证参数合法性和循环遍历。
SourceX/SourceY:指代源像素位置
DestinationX/DestinationY:指代目的像素位置,这两组变量跟你的BLT操作数有关
Width/Height:指代当前区域大小(跟source与destination打配合的)
Delta:代表行间距
4、*Mode
指向 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE 数据的指针,如果按照下面的方式解析,就可以直接查看当前的mode状态:
typedef struct {
UINT32 MaxMode;
UINT32 Mode;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
UINTN SizeOfInfo;
EFI_PHYSICAL_ADDRESS FrameBufferBase;
UINTN FrameBufferSize;
} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;如何使用EFI系统表调用下篇文章再讲吧,写不动了,但从这篇文章大概能看出UEFI裸机编程的一些思路了,未来至少还有gfxterm、渲染器、EFI系统表调用三方面要说的。