BIOS开发笔记 21 – RGRT Logo

 一、什么是BGRT?

BGRT(Boot Graphics Resource Table)是ACPI 5.0规范引入的一个ACPI表,其核心目的是实现从BIOS/UEFI启动阶段到操作系统的无缝视觉过渡当系统启动时显示厂商LOGO,BGRT的作用是告诉操作系统:

  • LOGO图像数据存储在内存的什么位置
  • 图像显示在屏幕的哪个位置
  • 图像当前的显示状态

这样操作系统启动时可以无缝延续显示这个LOGO,避免屏幕闪烁或黑屏,实现从固件到操作系统的平滑视觉过渡。

签名标识'B' 'G' 'R' 'T'

二、BGRT表结构

2.1 完整结构定义

根据ACPI规范,BGRT表结构如下:

typedef struct {   
EFI_ACPI_DESCRIPTION_HEADER    Header;        // ACPI标准表头   
UINT16                         Version;       // 版本号   
UINT8                          Status;        // 状态字段   
UINT8                          ImageType;     // 图像类型   
UINT64                         ImageAddress;  // 图像物理地址   
UINT32                         ImageOffsetX;  // X坐标偏移   
UINT32                         ImageOffsetY;  // Y坐标偏移 
} EFI_ACPI_6_5_BOOT_GRAPHICS_RESOURCE_TABLE;

2.2 BGRT特定字段

字段
大小
描述
Version
2 bytes
版本号
Status
1 byte
状态标志位
ImageType
1 byte
图像类型
ImageAddress
8 bytes
图像数据的物理内存地址
ImageOffsetX
4 bytes
图像左上角的X坐标
ImageOffsetY
4 bytes
图像左上角的Y坐标

2.3 Status字段详解

Bit[0]    : Displayed
            0 = 图像未显示或显示已被中断
            1 = 图像当前正在显示 
Bits[2:1] : Orientation Offset (顺时针旋转角度)
            [00] = 0度 (默认方向)
            [01] = 90度
            [10] = 180度
            [11] = 270度 
Bits[7:3] : Reserved (保留,必须为0)

Status字段的使用场景

  • • 当用户进入BIOS Setup界面时,应将Bit[0]清零,表示图像显示已中断
  • • 操作系统检测到此位为0时,不会尝试延续显示LOGO
  • • 支持屏幕旋转的设备可使用Bits[2:1]指示旋转角度(如常见的竖屏平板,通过BIOS旋转为横屏)

2.4 ImageType字段

0   = Bitmap (BMP格式) 
1-255 = Reserved (保留供将来使用)

目前ACPI规范只定义了BMP格式支持。

三、实现流程

3.1 总体流程

步骤0: 系统启动 (Boot Process)
   ↓ 
步骤1: 初始化图形设备 GOP/UGA
        • 设置合适的显示模式
        • 获取屏幕分辨率
   ↓ 
步骤2: 加载并绘制启动LOGO
        • 从固件存储加载图像
        • 转换为帧缓冲格式
        • 计算显示位置并绘制
        • 记录显示坐标
   ↓ 
步骤3: 从显存提取LOGO图像
        • 读取LOGO区域像素数据
        • 转换为24位BMP格式
        • 分配内存存储BMP数据
   ↓ 
步骤4: 构建BGRT表
        • 填充ACPI表头
        • 设置 Version=1, Status=1
        • 设置 ImageType=0 (BMP)
        • 设置 ImageAddress
        • 设置显示坐标
        • 计算校验和
   ↓ 
步骤5: 注册到ACPI
        • 通过ACPI Table Protocol安装
        • 保存表句柄供后续更新
   ↓ 
步骤6: 操作系统接管
        • 读取BGRT表
        • 延续显示LOGO直到启动完成

3.2 关键实现步骤

步骤1:获取图形输出协议

EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; 

gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&Gop); 
UINT32 Width = Gop->Mode->Info->HorizontalResolution; 
UINT32 Height = Gop->Mode->Info->VerticalResolution;

步骤2:计算LOGO显示位置

水平居中,垂直方向按黄金比例(38.2%)定位:

INT32 DestX = (ScreenX - LogoWidth) / 2;                    // 水平居中 
INT32 DestY = (ScreenY * 382 / 1000) - (LogoHeight / 2);    // 垂直38.2%

步骤3:从显存提取图像

EFI_UGA_PIXEL *BltBuffer = AllocatePool(LogoWidth * LogoHeight * sizeof(EFI_UGA_PIXEL)); 
Gop->Blt(Gop, BltBuffer, EfiBltVideoToBltBuffer,          
DestX, DestY, 0, 0, LogoWidth, LogoHeight, 0);

步骤4:转换为BMP格式

关键点:4字节行对齐、BGR顺序、从下到上存储:

UINT32 RowSize = (Width * 3 + 3) & ~3;       // 行字节数(4字节对齐) 
UINT8 *BmpData = AllocatePool(54 + RowSize * Height); // 填充BMP头(54字节): 签名'BM', 24位色深, 无压缩 // 写入像素: 从下到上, BGR顺序, 行末填充对齐

步骤5:构建BGRT表

Table->Version = 1; Table->Status = 1;                               // 已显示 
Table->ImageType = 0;                            // BMP格式 
Table->ImageAddress = (UINT64)BmpData;           // 图像地址 
Table->ImageOffsetX = DestX;                     // X坐标 
Table->ImageOffsetY = DestY;                     // Y坐标 
Table->Header.Checksum = CalculateChecksum();    // 计算校验和

步骤6:安装到ACPI

EFI_ACPI_TABLE_PROTOCOL *AcpiTable; 
gBS->LocateProtocol(&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); 
AcpiTable->InstallAcpiTable(AcpiTable, BgrtTable, TableSize, &TableKey);

四、状态管理

4.1 进入Setup界面

当用户按键进入BIOS Setup时,需要将Status字段清零:

BgrtTable->Status &= ~0x01;                                // 清除Displayed位 
BgrtTable->Header.Checksum = CalculateChecksum(BgrtTable); // 重算校验和 
AcpiTable->InstallAcpiTable(AcpiTable, BgrtTable, Size, &Key); // 重装ACPI表

4.2 Legacy Boot

Legacy BIOS启动时不支持BGRT,应在启动前卸载:

AcpiTable->UninstallAcpiTable(AcpiTable, TableKey);

4.3 动画LOGO处理

如果启动LOGO是动画(如GIF),BGRT应标记为未显示:

BgrtTable->Status = 0;  // 不标记为已显示 
// 操作系统将不会尝试延续显示动画帧

五、内存管理注意事项

5.1 内存分配策略

  • • BMP数据缓冲区:必须在操作系统可访问的物理内存中分配
  • • 内存类型:必须使用 EfiRuntimeServicesData
  • • 地址要求:ImageAddress存储的是物理地址

5.2 内存生命周期

步骤1: 分配BMP缓冲区 (使用ACPI可访问内存类型)
   ↓ 
步骤2: 转换图像数据 (从帧缓冲读取并转换)
   ↓ 
步骤3: 注册BGRT表 (ACPI Table Protocol)
   ↓ 
步骤4: 保持内存有效 (不要释放,留给OS使用)
   ↓ 
步骤5: 操作系统读取

重要:BGRT引用的图像数据内存不能在Boot Services退出前释放,操作系统需要在启动过程中访问这些数据。

 

版权声明:
作者:bin
链接:https://ay123.net/mystudy/1956/
来源:爱影博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
BIOS开发笔记 21 – RGRT Logo
 一、什么是BGRT? BGRT(Boot Graphics Resource Table)是ACPI 5.0规范引入的一个ACPI表,其核心目的是实现从BIOS/UEFI启动阶段到操作系统的无缝视觉过渡。……
<<上一篇
下一篇>>
文章目录
关闭
目 录