1、什么是ExpansionOption ROM?
Expansion rom是pci/pcie设备可选的一个外接的eprom芯片,其中用来存储相应pci设备的初始化代码或者系统启动代码(比如pxe或者pci boot)。BIOS在POST(Power-on Self Test)阶段,会扫描pci设备是否有expansion rom,有的话将其拷贝到ram中执行。在PCI规范中称为expansion rom,在BIOS术语里面称为option rom。
例如,我们系统启动阶段可以看到网卡和LSI SAS芯片的option rom执行过程,显卡也有相应的option rom不过我们在kvm上不好抓住。
2、PCI配置空间关于Expansion ROM的定义:
在pci/pcie设备的配置空间中关于expansion rom的定义在30h寄存器:
关于“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然后再回读,回读为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的过程大概分以下几步:
- a、首先判断pci设备是否实现“Expansion rom base address”寄存器,有则进行下一步判断;
- b、如果有实现了expansion的基址寄存器,则配置和使能expansion rom,然后查找expansion rom是否有”AA55”的标示字符,如果有则说明设备有真实的expansion rom芯片存在;
- c、如果expansion rom已经存在,则扫描是否有适合本设备和本CPU架构的image代码存在;
- d、如果有适合本环境的image代码存在,则把相应的代码拷贝到ram的合适位置,并跳入header format中指定的初始化入口执行;
- e、最后关闭expansion rom的使能。
关于image代码的长度有3个概念:一是Image size这部分包括整个image的长度;一是Initialization size,这部分是将expansion rom拷贝到ram中执行,需要拷贝的长度;一是Runtime size,这部分的程序可以驻留在内存中,供运行时系统软件和OS的调用。为了节约常驻代码的对ram的占用,常用的做法是,在init功能执行完成以后,执行代码自己把长度修改为常驻程序需要最少占用的Runtime size。如果不需要常驻程序,直接把Runtime size修改成0。
对应的关系是:Initialization size >= Initialization size >= Runtime size。相应的组织架构如下图: