VBIOS原理学习及修改方法。
GOP与VBIOS原理
GOP与VBIOS区别
VBIOS是由IBM PC衍生的Video BIOS,用于初始化显卡,为加载显卡驱动之前的基本视频输出提供INT 10h中断和VESA BIOS扩展。作为常见的Option ROM,在POST后由BIOS执行。
GOP(Graphics output protocol)——图形输出协议,GOP提供对硬件帧缓冲区的访问,提供显示的基本功能。为取代VGA BIOS,并在没有CSM的情况下使用。
Intel的GOP会放在BIOS中,主要包括三部分:
- IntelGopDriver.efi:GOP的DXE驱动
- IntelGraphicsPeim.efi:PEI阶段的GOP
- VBT:GOP配置文件
调用阶段如下:
在OS启动过程中,OS Loader会通过 ExitBootervices()通知 Driver 退出,这时 GOP 会在从系统中卸载。但是 Intel GFX Driver会继续使用 VBT 提供的配置信息。
显卡VBIOS结构
独显中的VBIOS通常会包括VBIOS和GOP两个镜像,和UEFI BIOS中的VBIOS一样,是一个PCI Expansion PROM的结构。
PCIR头和数据结构定义
PCIR头通常为28个字节的数据,其定义如下:
byte offset | value | description |
---|---|---|
00 | 55 | PROM signature |
01 | aa | PROM signature |
02-03 | 33 00 | SPARC reserved value(可扩展处理器架构保留值) |
04-17 | 00 00 | 为特有的处理器架构保留的数据 |
18-19 | 1c 00 | 指向PCI数据结构的指针 |
1a-1b | 00 00 | 填充 |
PCIR数据结构通常为24个字节,其定义如下:
Byte Offset | Description/(Hex. value) |
---|---|
00-03 | Signature : P C I R (50 43 49 52) |
04-05 | Vendor ID |
06-07 | Device ID |
08-09 | product data指针 |
0A-0B | PCI data structure 长度(18 00) |
0C | PCI data structure 版本号 |
0D | 编程接口代码 |
0E | 子类代码 |
0F | 类代码 |
10-11 | image length in 512 bytes |
12-13 | Revision level of code/data |
14 | Code type |
15 | 标识字节,如果是最后一个镜像则值为0x80 |
16-17 | 保留值 |
注意这里的标识字节,现代显卡一般会包含两个PCI ROM,分别对应VBT和GOP,如RX550的VBIOS:
这个GOP的PCI ROM的标识字节就为0x80,如果要禁用GOP,那么就可以把ATOMBIOS的标识字节改为0x80。
但是修改后要不要修改CRC校验和,还是个问题。校验块的位置似乎不包括这个头的数据。
以上是对于通用VBIOS的PCIR头和结构定义,而AMD显卡的VBIOS——Atombios,在此基础上又有细分了几个表的定义。
PCIR头后跟了一段ATI magic,用于标识Atombios:
Offset | Size | Description |
---|---|---|
0x00 | Word | BIOS Magic, should be 0xAA55 |
0x02 | byte | Image SIZE = value * 512 |
0x30 | 10 bytes | ATI Magic, should be ” 761295520″ |
0x48 | Word | Atom ROM Table Base |
如RX550的VBIOS:
0x48字节处的值(0x234)指向了ATOM ROM表的偏移:
0x02字节处标识ATOMBIOS IMAGE的大小,如:
0x73 * 512 = 0xE600
同时PCIR头的0x10-0x11偏移处也标识了IMAGE的大小,计算方法同上:
ATOM ROM table
ATOM ROM表定义如下:
Offset | Size | Description |
---|---|---|
0x00 | 4 bytes | Common header |
0x04 | 4 bytes | Atom Magic, should be “ATOM” |
0x08 | Word | BIOS运行时的段地址 |
0x0A | Word | Protected Mode Info Offset |
0x0C | Word | Config Filename Offset |
0x0E | Word | CRC Block Offset |
0x10 | Word | Name String offset(可为0,最大512bytes) |
0x12 | Word | Int 10 offset |
0x14 | Word | PCI总线设备初始化代码 |
0x16 | Word | IO基址 |
0x18 | Word | Subsystem Vendor ID |
0x1A | Word | Subsystem ID |
0x1C | Word | PCI Info Offset |
0x1E | Word | Command Table Base |
0x20 | Word | Data Table Base |
0x22 | Byte | Extended Function Code |
0x23 | Byte | Reserved |
根据该表定义可以看出下面还定义了好几个表的偏移地址。需要注意的是,这个偏移是针对整个镜像文件开始的位置,而不是ATOM ROM表开始的位置
大多数表使用的头定义如下:
Common header
Offset | Size | Description |
---|---|---|
0x00 | Word | 表定义结构的长度 |
0x02 | Byte | 表格式修订,当解析器不向后兼容时更改 |
0x03 | Byte | 表内容修订 |
command table
Offset | Size | Description |
---|---|---|
0x00 | 4 bytes | Common Header |
0x04 | x words | Array offsets of commands |
command format
命令格式定义:
Offset | Size | Description |
---|---|---|
0x00 | Word | Command Length |
0x02 | Word | Reserved |
0x04 | Byte | WS? |
0x05 | Byte | PS – Parameter Stack |
0x06-0x???? | ?? | Command bytecode |
RX550的command table偏移:
该表定义了结构的大小为A6个字节,以及各个命令数组的偏移:
Data table
Offset | Size | Description |
---|---|---|
0x00 | 4 bytes | Common Header |
0x04 | Word | UtilityPipeline |
0x06 | Word | MultimediaCapabilityInfo |
0x08 | Word | MultimediaConfigInfo |
0x0A | Word | StandardVesa_Timing |
0x0C | Word | FirmwareInfo |
0x0E | Word | PaletteData |
0x10 | Word | LCD_Info |
0x12 | Word | DIGTransmitterInfo |
0x14 | Word | AnalogTV_Info |
0x16 | Word | SupportedDevicesInfo |
0x18 | Word | GPIO_I2C_Info |
0x1A | Word | VRAM_UsageByFirmware |
0x1C | Word | GPIO_Pin_LUT |
0x1E | Word | VESA_ToInternalModeLUT |
0x20 | Word | ComponentVideoInfo |
0x22 | Word | PowerPlayInfo |
0x24 | Word | CompassionateData |
0x26 | Word | SaveRestoreInfo |
0x28 | Word | PPLL_SS_Info |
0x2A | Word | OemInfo |
0x2C | Word | XTMDS_Info |
0x2E | Word | MclkSS_Info |
0x30 | Word | Object_header |
0x32 | Word | IndirectIOAccess |
0x34 | Word | MC_InitParameter |
0x36 | Word | ASIC_VDDC_Info |
0x38 | Word | ASIC_InternalSS_Info |
0x3A | Word | TV_VideoMode |
0x3C | Word | VRAM_Info |
0x3E | Word | MemoryTrainingInfo |
0x40 | Word | IntegratedSystemInfo |
0x42 | Word | ASIC_ProfilingInfo |
0x44 | Word | VoltageObjectInfo |
0x46 | Word | PowerSourceInfo |
command表后紧接着就是data表,包含了各类信息表的偏移:
INT 10H中断
该中断处理程序用于提供视频显示服务,包括设置视频模式、字符和字符串输出以及在图形模式下的读取和写入像素。
VBIOS提取
用mmtool可提取VBIOS/VBT:
实际上就是CSMCORE RAW里的部分内容。
hex查看提取的内容:
version OROM VBIOS:HASWELL 2173
version VBT:AA 00 -> AA(v1.70)
size VBT: ff 10 -> 10ff (4351 byte)
使用Intel BMP工具可编辑VBIOS镜像,需要选择对应版本的BSF脚本:
显卡VBIOS读写
GPU-Z可查看显卡信息,并读取VBIOS:
A卡使用amdvbflash工具,-i参数读取适配器id:
写入VBIOS:amdvbflash.exe -p -f [id] <*.rom>
A卡使用GopInfoX.exe可查看GOP信息:
VBIOS修改
修改CRC对刷写工具的解析有影响,未修改的固件无法识别ID,而修改后的可以:
修改方式为把ATOMBIOS尾部的FF修改为7F,平衡CRC校验和(0xFF-0x80=0x7F):
把GOP镜像全填充为FF,并在最后0x1000个字节处填充csminsert数据。但这样就无法修改单个数据来平衡校验和了。
修改校验和,用PolarisBIOSEditor打开,会提示未修改校验和,点确定,再SAVE AS另存为文件后即可修复校验和:
另外一提,这个校验和的位置为0x21的偏移处:
用amdvbflash写入时可以正常识别ID了:
不出所料,这样暴力修改后刷进去显卡就变砖了。
恢复方法
找个能设置集显优先输出的主板,在插入了RX 550的情况下,从集显进入系统,使用amdvbflash -i可以识别到适配器id,刷回原版固件即可。
如MSI B360M MORTAR的设置:
近期评论