PCIe Expansion ROMs
目录
1. 为什么需要Expansion ROM
为了将操作系统加载到内存中,系统需要三类设备:
- 存储设备:用于保存操作系统。
- 显示设备:用于显示当前的启动进度。
- 输入设备:用于接收用户输入信息。
在这个阶段,操作系统还没有被加载到内存执行,也就意味着操作系统中对应的设备驱动程序也没有被加载,因此,就需要在Expansion ROM里面存放一份启动阶段使用的设备驱动程序。
说的直接点就是,BIOS阶段向使用一个PCIe设备,但是原始的BIOS不包含这个设备的驱动程序,这个时候就从这个PCIe设备Expansion ROM里获取设备驱动程序代码,并加载到内存中执行。
2. 怎么知道PCIe设备是否包含Expansion ROM
并不是所有PCIe设备都包含Expansion ROM,所以就需要软件进行判定。
在PCIe的配置空间(PCIe Configuration Space)里有个叫“Expansion ROM Base Address Register”的东西,利用它判定Expansion ROM的步骤如下:
- 向Expansion ROM Base Address Register写入0xFFFF FFFF。
- 读取Expansion ROM Base Address Register,如果值是0,那就表示不存在Expansion ROM(Game Over!)。如果读取的值非0,那就表示存在Expansion ROM,但这并不就表明这东西可用了,还需要下面的判定步骤。
- 给PCIe Expansion ROM分配一个合适的地址,把地址的值写入Expansion ROM Base Address Register。
- 将Expansion ROM Base Address Register bit 0置为1,使能Address Decode。
- 读取ROM的前两个字节,如果前两个字节是AA55h,那就表明当前ROM是合法可用的,否则还是Game Over。
3. 怎么知道Expansion ROM的空间大小
在Expansion ROM的判定阶段,有一个过程是向Expansion ROM Base Address Register写入0xFFFF FFFF,然后读取它的值,利用这个值就可以判定出Expansion ROM的空间大小。
假设写入0xFFFF FFFF之后,读出的值是0xFFFE 0000,那么第17位就是非0值的最低位,那么Expansion ROM的大小就是2^17 Bytes= 128KB。PCI文档规定,ROM最大可为16MB,即bit[31:25]必须是可读/可写的。
4. Expansion ROM里存了什么
4.1 不只一份Code Image
就像之前提到的,ROM存了设备的驱动程序代码,专业点叫做code image。实际上,PCI协议规定ROM里可以存放不只一份code image,不同的code image对应不同的处理器架构、同一供应商的不同产品等等。BIOS或者其他软件需要选择最合适的code image提取到内存中执行。
每一份code image包含run-time code image和initialization code image两部分。BIOS或其他上位机软件按照如下步骤使用code image:
- 将最合适的code image拷贝的内存中。
- 将Expansion ROM Base Address Register bit 0置为0,关闭Expansion ROM’s address decoder。
- 执行initialization code。
- 释放initialization code所占用的内存。
- 将剩余的code image所占用的内存部分设置为写保护(write-protected),避免被修改。
4.2 Code Image格式
4.2.1 Header Format
在每个image最开始的地方都有一个Header,因此可以叫它code image header。
下面的表格描述了code image header的格式(第一列的offset是指相对于该image起始位置的偏移):
Offset 02h~17h的位置存放的是处理器相关的数据,其格式如下表:
4.2.2 Data Structure Format
Data structure中包含了设备信息和image信息。
由于code image header中使用两个bytes存放指向data structure的指针,所以data structure只能存放在该code image的前64KB范围内。
当code image中包含run-time code时,data structure必须放在run-time code中。但是在某些情况下,code image可以不包含run-time image,只有initialization code,此时data structure放在initialization code中。
Data Structure格式如下表:
- Vendor ID & Device ID & Class Code :只有当这三个参数与设备匹配时,该image才会被BIOS加载到内存中执行。
- Code Type:表明当前image的执行条件。
- Code Type = 00h:Intel x86 (兼容IBM PC-AT)架构可执行代码。
- Code Type = 01h:符合open firmware标准,可结合OpenBoot使用。
- Code Type = 02h:HP PA/RISC架构可执行代码。
- Code Type = 03h:Extensible Firmware Interface(EFI)
参考资料:《PCI Express System Architecture》