本文将介绍PCI Expansion ROM相关内容,转载于PCI&PCIE ExpansionOption ROM

1. What is Expansion ROM

Expansion rom是pci/pcie设备可选的一个外接的eprom芯片,用来存储相应pci设备的初始化代码或者系统启动代码。BIOS在POST(Power-on Self Test)阶段,会扫描pci设备是否有expansion rom,有的话将其拷贝到ram中执行。在PCI规范中称为expansion rom,在BIOS术语里面称为option rom。

2. PCI配置空间关于Expansion ROM的定义

The four-byte register at offset 30h in a type 00h predefined header is defined to handle the base address and size information for this expansion ROM.

关于“Expansion rom base address”寄存器的具体定义细节如下:

bit11-bit31定义expansion rom的映射到memeory空间的高位地址bit11-bit31。bit0表示是否使能expansion rom,1使能为使能,需要注意的是expansion rom和pci其他的bar空间是共享地址解码的,所以一旦使能expansion rom就不能对其他的bar空间进行操作。expansion rom空间大小的计算方法和其他的“base address register”一样,往基址寄存器写全1,然后再回读进行计算。

软件把“Expansion rom base address”寄存器的基地址配置成相应的memeory空间地址并使能expansion rom以后,就可以对设备的expansion rom进行读访问了。软件将expansion rom中包含的可执行代码拷贝到ram中执行,不用关心这些可执行代码具体干些什么事情。

3. Expansion ROM的组织结构

Expansion rom的组织结构有相应的规范。一个可能包含多个rom image,可以支持多个不同类型的pci设备,每种设备也可以支持不同架构cpu的可执行代码。多个image在一个expansion rom芯片中的组织如下图所示,其中每份image的开始地址都是以512bytes对齐的:


一份标准的image由两部分组成:PCI Expansion ROM Header Format和PCI Data Structure Format。具体的格式定义如下图:

4. Expansion ROM的初始化过程

BIOS的POST阶段,扫描并执行pci设备的expansion rom的过程大概分以下几步:

  1. 首先判断pci设备是否实现“Expansion rom base address”寄存器,有则进行下一步判断;
  2. 如果有实现了expansion rom的基址寄存器,则配置和使能expansion rom,然后查找expansion rom是否有”AA55”的标示字符,如果有则说明设备有真实的expansion rom芯片存在;
  3. 如果expansion rom已经存在,则扫描是否有适合本设备和本CPU架构的image代码存在;
  4. 如果有适合本环境的image代码存在,则把相应的代码拷贝到ram的合适位置,并跳入header format中指定的初始化入口执行;
  5. 最后关闭expansion rom的使能。

关于image代码的长度有3个概念:一是Image size这部分包括整个image的长度;一是Initialization size,这部分是将expansion rom拷贝到ram中执行,需要拷贝的长度;一是Runtime size,这部分的程序可以驻留在内存中,供运行时系统软件和OS调用。为了降低常驻代码对ram的占用,常用的做法是:在init功能执行完成以后,执行代码自己把长度修改为常驻程序最少需要占用的Runtime size。如果不需要常驻程序,直接把Runtime size修改成0。
对应的关系是:Image size >= Initialization size >= Runtime size。相应的组织架构如下图:


参考资料:

  1. PCI Local Bus Specification Revision 3.0
  2. PCI&PCIE ExpansionOption ROM
  3. BIOS之Option ROM详解
  4. PCI Firmware Specification Revision 3.0