PCIe Expansion Roms

PCIe Expansion ROMs

目录

  • PCIe Expansion ROMs
    • 1. 为什么需要Expansion ROM
    • 2. 怎么知道PCIe设备是否包含Expansion ROM
    • 3. 怎么知道Expansion ROM的空间大小
    • 4. Expansion ROM里存了什么
      • 4.1 不只一份Code Image
      • 4.2 Code Image格式
        • 4.2.1 Header Format
        • 4.2.2 Data Structure Format

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格式

PCIe Expansion Roms_第1张图片

4.2.1 Header Format

在每个image最开始的地方都有一个Header,因此可以叫它code image header。

下面的表格描述了code image header的格式(第一列的offset是指相对于该image起始位置的偏移):
PCIe Expansion Roms_第2张图片
Offset 02h~17h的位置存放的是处理器相关的数据,其格式如下表:
PCIe Expansion Roms_第3张图片

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格式如下表:
PCIe Expansion Roms_第4张图片

  • 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》

你可能感兴趣的:(PCIe,pci-e)