PCI ROM如何被遮蔽?

时间:2016-05-04 12:59:01

标签: hardware boot bios pci pci-bus

在几个资源中我发现:ROM映像必须通过000DFFFFh复制到RAM到000C0000h。如果类代码表明这是VGA设备ROM,则必须将其代码从位置000C0000h复制到存储器中。

1:如果我的PCI饥饿河马卡的ROM大于128KB会怎么样?

2:如果我的常规PCI设备有ROM 64KB,但我有4个,怎么办?它们是否按顺序加载到此内存范围内?如果是这样(虽然我怀疑)如何在init和boot阶段之间保留代码图像?

3:如果BIOS决定采用不符合规范并指定不同的内存位置会发生什么?为什么使用这个范围很重要?

4:与VGA接口有什么不同的常规情况?只是限制才能产生差异吗?

2 个答案:

答案 0 :(得分:2)

1)非UEFI BIOS Option ROM通常没有那么大且没有大小限制,但是UEFI驱动程序可以更大,并且可以放置在UEFI BIOS中的1MiB之上,在SEC阶段将退出实模式。您可以disable某些不想被掩盖的选项ROM下次启动时留在空白处。

3)之所以使用此较小范围,是因为非UEFI BIOS在实模式下运行(中断表(IVT而不是IDT)从0h开始,作为对可选ROM的保证),因此只能访问内存的前1MiB和需要内存来做其他事情(BIOS数据,BIOS,BIOS的堆栈/堆和选件ROM)。尽管大多数BIOS最终都使用虚幻模式或带虚拟8086的保护模式,因此它们可以同时使用IVT并寻址32位,所以没有什么能阻止BIOS遮盖RAM中其他位置的选项ROM以及BIOS扫描该区域(我已经读到,如果BIOS仅是64KiB,也可以使用E0000-EFFFF,但如果选件ROM本身寻找其他选件ROM(例如UNDI ROM在PxE NIC上寻找BC ROM)则变得很复杂。他们还使用PMM服务来分配16/32位堆地址。 UEFI不再使用BIOS中断服务;它使用EFI功能。

4)用于板载图形的选件ROM在BIOS本身中,并且其地址已知。传统上,它是硬编码的,可以移动到C0000h(实模式分段表示法中为C000:0000h),也可以移动到任何需要的地方。 BIOS至少确保它是第一个执行的ROM,但是例如,如果知道将其移动到D0000h,那么它将知道将控制权传递到哪里。如果允许它使用可变地址而不是固定地址,那么如果先屏蔽其他PCIe卡,则可能最终无法容纳该范围。另外,它必须先扫描VGA bios类代码,然后再次扫描范围,或保留内部选项ROM的内部表,这比在整个空间和视频BIOS上线性迭代的简单例程要复杂得多。碰巧先执行。因此,它需要一个固定的地址,如果它使固定地址为D0000h而不是C0000h,并在其周围放置其他选项ROM,则将发生空间的外部碎片。

PAM不再位于北桥中(现代Intel CPU中不再存在),它们被用作L3缓存片中SAD配置的一部分,该解码器解码地址并发送请求到内存控制器,DMI,PCIe链接或处理器图形。 BIOS可以设置PAM,以便将特定范围的读取发送到DMI,并将写入发送到内存控制器。这样一来,BIOS便可以隐藏在自身上,并且PCI(e)XROMBAR可以设置为将被隐藏到的相同地址。

在我的系统(Kaby lake + C230系列PCH + UEFI安全启动已禁用)上,C0000h–DFFFFh区域中有3个ROM。

VGA BIOS

Option ROM Header: 0x000C0000
55 AA 80 E9 91 F9 30 30 30 30 30 30 30 30 30 30 U.....0000000000
30 30 A8 2F E9 B1 2E AF 40 00 90 0B             00./....@...    
  Signature 0xAA55
  Length    0x80 (65536 bytes)
  Initialization entry  0x30F991E9 //software read this wrong it's actually 0xF991E9, which is a 16 bit relative jump 0xF991; -1647
  Reserved  0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 
  Reserved  0x30 0xA8 0x2F 0xE9 0xB1 0x2E 0xAF 
  PCI Data Offset   0x0040 //offset is from start of OpROM header
  Expansion Header Offset   0x0B90

PCI Data Structure: 0x000C0040
50 43 49 52 86 80 06 04 1C 00 1C 00 03 00 00 03 PCIR............
80 00 00 00 00 80 80 00                         ........        
  Signature PCIR
  Vendor ID 0x8086 - Intel Corporation
  Device ID 0x0406
  Product Data  0x001C
  Structure Length  0x001C
  Structure Revision    0x03
  Class Code    0x00 0x00 0x03
  Image Length  0x0080
  Revision Level    0x0000
  Code Type 0x00
  Indicator 0x80
  Reserved  0x0080

SATA控制器(每个磁盘的PnP扩展头)

Option ROM Header: 0x000D0000
55 AA 4D B8 00 01 CB 00 00 00 00 00 00 00 00 00 U.M.............
00 00 00 00 00 00 00 15 A0 00 9A 01             ............    
  Signature 0xAA55
  Length    0x4D (39424 bytes)
  Initialization entry  0xCB0100B8 //mov  ax, 0x100  retf 
  Reserved  0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
  Reserved  0x00 0x00 0x00 0x00 0x00 0x00 0x15 
  PCI Data Offset   0x00A0
  Expansion Header Offset   0x019A

PCI Data Structure: 0x000D00A0
50 43 49 52 86 80 2A 28 1C 00 1C 00 03 00 04 01 PCIR..*(........
4D 00 02 0F 00 80 4D 00                         M.....M.        
  Signature PCIR
  Vendor ID 0x8086 - Intel Corporation
  Device ID 0x282A
  Product Data  0x001C
  Structure Length  0x001C
  Structure Revision    0x03
  Class Code    0x00 0x04 0x01
  Image Length  0x004D
  Revision Level    0x0F02
  Code Type 0x00
  Indicator 0x80
  Reserved  0x004D

PnP Expansion Header: 0x000D019A
24 50 6E 50 01 02 BA 01 01 06 00 00 00 00 C2 00 $PnP............
D4 00 00 04 01 C4 90 1A 00 00 00 00 00 00 00 00 ................
  Signature $PnP
  Revision  0x01
  Length    0x02 (32 bytes)
  Next Header   0x01BA
  Reserved  0x01
  Checksum  0x06
  Device ID 0x00000000
  Manufacturer  0x00C2 - Intel Corporation  //location 0xD00C2
  Product Name  0x00D4 - SanDisk X400 M.2 2280 256GB //location 0xD00D4
  Device Type Code  0x00 0x04 0x01
  Device Indicators 0xC4
  Boot Connection Vector    0x1A90
  Disconnect Vector 0x0000
  Bootstrap Entry Vector    0x0000
  Reserved  0x0000
  Resource info. vector 0x0000

PnP Expansion Header: 0x000D01BA
24 50 6E 50 01 02 00 00 02 9B 00 00 00 00 C2 00 $PnP............
F5 00 00 04 01 C4 94 1A 00 00 00 00 00 00 00 00 ................
  Signature $PnP
  Revision  0x01
  Length    0x02 (32 bytes)
  Next Header   0x0000 //next PnP expansion header contains nothing useful
  Reserved  0x02
  Checksum  0x9B
  Device ID 0x00000000
  Manufacturer  0x00C2 - Intel Corporation
  Product Name  0x00F5 - ST1000LM035-1RK172
  Device Type Code  0x00 0x04 0x01
  Device Indicators 0xC4
  Boot Connection Vector    0x1A94
  Disconnect Vector 0x0000
  Bootstrap Entry Vector    0x0000
  Reserved  0x0000
  Resource info. vector 0x0000

以太网控制器

Option ROM Header: 0x000DA000
55 AA 08 E8 76 10 CB 55 BC 01 00 00 00 00 00 00 U...v..U........
00 00 00 00 00 00 20 00 40 00 60 00             ...... .@.`.    
  Signature 0xAA55
  Length    0x08 (4096 bytes)
  Initialization entry  0xCB1076E8 //call then far return 
  Reserved  0x55 0xBC 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
  Reserved  0x00 0x00 0x00 0x00 0x00 
  PXEROMID Offset  0x0020 //RWEverything didn't pick it up as a separate field and made it part of the reserved section so I separated it.
  PCI Data Offset   0x0040  
  Expansion Header Offset   0x0060

UNDI ROM ID Structure: 0x000DA020  //not recognised by RW Everything so I parsed it myself
55 4E 44 49 16 08 00 00 01 02 32 0D 00 08 B0 C4  UNDI......2...
80 46 50 43 49 52                                ¦-ÇFPCIR
  Signature  UNDI
  StructLength  0x16
  Checksum  0x08  
  StructRev  0x00
  UNDIRev 0x00 0x01 0x02
  UNDI Loader Offset 0x0D32
  StackSize 0x0800
  DataSize 0xC4B0
  CodeSize 0x4680
  BusType PCIR

PCI Data Structure: 0x000DA040
50 43 49 52 EC 10 68 81 00 00 1C 00 03 00 00 02 PCIR..h.........
08 00 01 02 00 80 08 00                         ........        
  Signature PCIR
  Vendor ID 0x10EC - Realtek Semiconductor
  Device ID 0x8168
  Product Data  0x0000
  Structure Length  0x001C
  Structure Revision    0x03
  Class Code    0x00 0x00 0x02
  Image Length  0x0008
  Revision Level    0x0201
  Code Type 0x00
  Indicator 0x80
  Reserved  0x0008

PnP Expansion Header: 0x000DA060
24 50 6E 50 01 02 00 00 00 D7 00 00 00 00 AF 00 $PnP............
92 01 02 00 00 E4 00 00 00 00 C1 0B 00 00 00 00 ................
  Signature $PnP
  Revision  0x01
  Length    0x02 (32 bytes)
  Next Header   0x0000
  Reserved  0x00
  Checksum  0xD7
  Device ID 0x00000000
  Manufacturer  0x00AF - Intel Corporation
  Product Name  0x0192 - Realtek PXE B02 D00
  Device Type Code  0x02 0x00 0x00
  Device Indicators 0xE4
  Boot Connection Vector    0x0000
  Disconnect Vector 0x0000
  Bootstrap Entry Vector    0x0BC1 // will be at 0xDABC1
  Reserved  0x0000
  Resource info. vector 0x0000

在具有旧版BIOS的另一台计算机上,只有VGA选项ROM出现在此区域的扫描中,并且位于0xC0000。没有EHCI和SATA。对我来说,这表明它已嵌入BIOS中,但它是BIOS代码的一部分,而不是作为可选的ROM(在BBS中被称为BAID)。用于初始化控制器和扫描引导设备并将其信息输入IPL表并挂钩int 13h的代码已在BIOS中进行了硬编码,以便MBR / VBR可以访问磁盘。另外,BCV挂接顺序优先级不再重要,因为它们如今都以BAID的形式全部输入到IPL表中,而不仅仅是可引导磁盘80h(通过读取BDA中当前磁盘枚举编号来填充,然后填充许多从int 13h调用中获取的条目及其各自的详细信息)。大概,IPL表包含要从中引导的磁盘号,并将其传递给条目中的向量,这将是所有BAID共享的代码,这些BAID使用int 13h到0x7c00从磁盘加载第一个扇区,以检查有效的MBR,然后通过控制。然后,MBR会将其自身从0x7c00移开,并将活动分区的VBR加载到0x7c00,并将控制权传递给JMP指令(如果其默认窗口为1。如果是GRUB,它将从扇区1–加载并将控制权传递给core.img。 65)。然后,VBR将使用VBR中BPB中的HiddenSectors值将IPL加载到其在磁盘上的扇区1-15中,并将控制权交给它。在Windows上,IPL解析紧随VBR之后的NTFS文件系统MFT,找到bootmgr.exe,将其解压缩并将控制权传递给DOS存根。

SATA控制器上初始化条目中的代码是远远返回0x100的代码。初始化完成后,BIOS或选件ROM本身似乎已对其进行了修改,或者可能只是因为它是在BIOS中其他位置初始化的嵌入式设备而被修改了。根据定义,初始化代码现在已无用,遵循DDIM的选件ROM可能会在初始化后将其从RAM中删除,并重新计算长度和校验和。视频履历甚至会产生一些负面的相对跳跃。这表明BIOS将其视频BIOS遮罩到了C0000h之前的位置,部分遮盖了VGA VRAM区域,从而使ROM标题出现在C0000h。

“长度”似乎是在描述选件ROM初始化后所占用的旧选件ROM影子RAM区域中的空间量。

这是分割的PXE选项ROM的示例内存映射:

enter image description here

BIOS可能不会一次设置所有XROMBAR使其包括预先初始化的长度,而是可能一次加载并初始化一个BIOS。它不能覆盖/删除选件ROM,因为选件ROM中与IPL代码分开的例程仍可能被BCV调用以与硬件交互。例如,在运行视频BIOS初始化代码之后,将扫描PCI配置空间,并且将第一个返回长度的XROMBAR设置为视频BIOS的末尾。然后,将读取定向到DMI,将写入定向到内存。然后将其映射到内存,将读取重定向到RAM,并对初始化条目执行远距离调用。然后,IPL代码通过删除初始化代码来收缩自身。 BIOS检查选件ROM的新大小以及PnP扩展标头并注册BEV / BCV。然后,它将加载重定向回DMI并加载下一个XROMBAR。 BIOS一次构建BCV表条目,然后按BCV优先级顺序执行BCV。

选项ROM可以将BEV / BCV移至扩展内存中的PMM分配,在BEV / BCV偏移处保留跳转指令,但是这会将BCV / BEV中跳转的相对寻址分解为其余功能。选件ROM。因此,它可以将整个自身重定位为PMM分配,并将大小减小为仅标头,但是显然,对于大多数选件ROM而言并非如此。 BEV确实会重新安置UNDI驾驶员。

答案 1 :(得分:1)

1:将这个大的ROM复制到选项ROM空间是不可能的。初始大小字段是1个字节,它被解释为512字节增量,即255 * 512 = 127KB

2:太糟糕了,其中一些还没有被初始化。

3:北桥(英特尔芯片组数据表)中有PAM。这些寄存器可以在可选的ROM空间中写入受保护的特定范围。

4:限制VGA的数量。它只需从c0000h开始,而某些NIC也可以从.. pfft d0000h开始。

谢谢Pyjong。 Pyjong欢迎你。