菜单

kaoqi
kaoqi
发布于 2026-08-20 / 12 阅读
0
0

UEFI的GOP协议

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系统表调用三方面要说的。


评论