PAYATHON 2026

如何在 BIOS Bootloader 中获取显示器的首选分辨率?

数据阿明

可以使用 VBE/DDC 读取显示器的 EDID,再根据首选时序中的分辨率选择 VBE 模式。读取显示器能力和设置显卡输出是两个步骤,EDID 报告的分辨率不一定能通过 BIOS 设置。

VBE、DDC 和 EDID 分别负责什么?

  • VBE 提供查询和设置显卡视频模式的 BIOS 接口。
  • DDC 提供读取显示器信息的通信途径,BIOS 可以通过 VBE/DDC 暴露相关服务。
  • EDID 是显示器能力的数据格式,包含分辨率、时序等信息。

实际操作时,先读取 EDID,确定首选时序,再与 BIOS 返回的 VBE 模式列表匹配。VBE/DDC 的功能号是 4F15h,其中子功能 01h 用于读取 EDID。VESA VBE 2.0 规范

1. 在 BIOS 阶段读取 EDID 基础块

建议在进入 x86_64 long mode 前完成查询和模式设置。进入 long mode 后,不能直接将 INT 10h 作为传统实模式 BIOS 服务调用。

以下调用读取第一个 EDID 块。代码假定已准备好有效的 ES:DI,指向至少 128 字节的可写实模式缓冲区,且缓冲区不会跨越段边界:

BITS 16

mov ax, 0x4F15
mov bx, 0x0001       ; BL = 01h: Read EDID
xor cx, cx          ; Query the primary controller
xor dx, dx          ; Read the base block
int 0x10
cmp ax, 0x004F      ; Continue only on success

也可以先使用 BL=00h 查询 DDC 能力。读取失败时应走回退路径,不能继续解析缓冲区。寄存器约定可参照显卡厂商的 VBE/DDC 接口说明。

2. 从 EDID 中解析首选分辨率

先检查基础块:

  • 头部是否为 00 FF FF FF FF FF FF 00。
  • 128 字节之和是否满足 sum % 256 == 0。
  • 0x12、0x13 处的版本和修订号是否属于解析器支持的格式。

EDID 1.3 要求第一个 Detailed Timing Descriptor(DTD)描述首选时序。该描述符从基础块偏移 0x36 开始,占 18 字节。对于 LCD,这通常对应面板的原生时序,但不能将所有设备的首选模式都视为物理原生分辨率。VESA E-EDID 1.3 规范,第 3.10 节

确认描述符是有效 DTD 后,可以这样提取水平和垂直有效像素数:

const uint8_t *dtd = edid + 0x36;

unsigned width  = dtd[2] | ((unsigned)(dtd[4] & 0xF0) << 4);
unsigned height = dtd[5] | ((unsigned)(dtd[7] & 0xF0) << 4);

这段代码只提取字段,并非完整的 EDID 解析器。DTD 的前两个字节是小端序 pixel clock;两者均为零时,该块不是详细时序,不能按上述方式解析。初版 Bootloader 可以只接受非隔行 DTD,遇到隔行标志时回退,以免错误解释垂直尺寸。

EDID 1.4 同样使用第一个描述符提供首选时序,但 0x18 的 bit 1 表示该时序是否包含显示器的原生像素格式和首选刷新率,不能直接沿用旧版本对该位的解释。VESA E-EDID 1.4 规范,第 3.6 节

3. 将分辨率匹配到可用的 VBE 模式

获取目标宽高后,按以下顺序处理:

  1. 调用 AX=4F00h 获取 VBE Controller Information,并读取 VideoModePtr。
  2. 遍历模式列表,直到遇到 0xFFFF。该指针是实模式远指针,需要正确转换或访问。
  3. 对每个模式调用 AX=4F01h,比较 XResolution、YResolution,并检查模式可用、属于图形模式且像素格式受内核支持。
  4. 如果使用 Linear Frame Buffer,还要检查 ModeAttributes 的 bit 7。
  5. 找到合适模式后,调用 AX=4F02h 设置模式;请求 Linear Frame Buffer 时,将模式号与 0x4000 按位或。

模式号应从固件返回的列表中获取。设置成功后,将 framebuffer 物理地址、宽高、每行字节数和颜色掩码传给内核。绘制时使用返回的 pitch,不要假定每行大小就是宽度乘以每像素字节数。VESA VBE 3.0 规范,Functions 00h、01h、02h

找不到匹配模式时怎么办?

EDID 不会为 BIOS 添加新模式。如果首选分辨率没有出现在可用 VBE 模式列表中,就不能仅凭读到的宽高强制设置它。

早期开发时可以保留回退策略:优先选择显示器声明支持、VBE 提供且内核能处理的模式,并允许手动指定模式。EDID 不可用时,也应明确将所选模式视为回退选择。

宽高匹配只代表分辨率相同,输出刷新率不一定与 EDID 的首选时序完全一致。VBE 3.0 提供自定义 CRTC 时序的机制,但仍受硬件和固件能力限制,不能保证创建任意分辨率。需要完整控制显示输出时,应在后续实现对应显卡的原生驱动。VESA VBE 3.0 规范,刷新率控制

备注:内容仅供参考。