GA-Q35-S2主板BIOS中CPU远跳转指令的寻址疑问
CPU远跳转指令处理逻辑与BIOS早期执行阶段的地址路由问题
CPU远跳转指令的处理逻辑是怎样的?具体来说,远跳转后下一条指令的获取位置由什么决定?本文针对BIOS早期执行阶段的该问题展开探讨,以GA-Q35-S2主板的Award BIOS为例:
CPU执行的第一条指令来自复位向量,其相对跳转指令易于追踪:
1ffff0: e9 de fa jmpw 0x1ffad1
(注:1ffff0是BIOS转储文件中的偏移量,请勿与CPU物理地址混淆)
此处反汇编工具objdump可根据当前文件偏移量1ffff0及作为有符号16位整数的操作数0xfade,自动得到目标文件偏移量0x1ffad1,可通过指令objdump -D -b binary -m i386 -M i8086,suffix --start-address=0x1ffad1 bios_dump | head -n 20查看后续指令。
结合Intel Q35北桥芯片组 datasheet、Intel Q35南桥(ICH9)芯片组 datasheet,可分析后续执行的指令:
1ffad1: 8c d9 movw %ds,%cx # Save ds for restoring later 1ffad3: 8b fa movw.s %dx,%di # Save dx for restoring later 1ffad5: 66 b8 f0 f8 00 80 movl $0x8000f8f0,%eax 1ffadb: ba f8 0c movw $0xcf8,%dx 1ffade: 66 ef outl %eax,(%dx) # enables the configuration space for D31:F0 (function 0) using the north bridge. Precisely we are targeting the RCBA register of the north bridge 1ffae0: 83 c2 04 addw $0x4,%dx 1ffae3: 66 ed inl (%dx),%eax # obtain a configuration data window for the RCBA register 1ffae5: 66 8b d8 movl.s %eax,%ebx # save the CDW to enable restoring it later 1ffae8: 66 b8 01 00 0d 00 movl $0xd0001,%eax 1ffaee: 66 ef outl %eax,(%dx) # Enable RCBA base address = 0xd0000 1ffaf0: be 00 00 movw $0x0,%si 1ffaf3: b8 00 d0 movw $0xd000,%ax 1ffaf6: 8e d8 movw %ax,%ds 1ffaf8: 80 8c 10 34 04 orb $0x4,0x3410(%si) # Set Reserved Page Route (RPR) bit of the General Control and Status Register (GCS) - Configure the reservered page registers to have their writes forwarded to PCI, be shadowed within the ICH, and the reads will be returned from that internal shadow. (see ICH9 datasheet section 10.1.75) 1ffafd: 8a 84 11 34 movb 0x3411(%si),%al 1ffb01: 24 0c andb $0xc,%al 1ffb03: 3c 08 cmpb $0x8,%al # check if Boot BIOS Straps (BBS) bits of the GCS chipset configuration register are 10 - checks if the destination of accesses to the BIOS memory range is PCI (not SPI and not LPC). See ICH9 datasheet section 10.1.75 1ffb05: 75 12 jne 0x1ffb19 # If it's not PCI, we skip the below PCI-specific code that is for disabling legacy ranges decoding (as you can see below). 1ffb07: 66 b8 d8 f8 00 80 movl $0x8000f8d8,%eax 1ffb0d: ba f8 0c movw $0xcf8,%dx 1ffb10: 66 ef outl %eax,(%dx) # enable configuration space for D31:D8 function 0 using the north bridge. We are targetting the Firmware Hub Decode Enable Register (FWH_DEC_EN1) 1ffb12: 83 c2 04 addw $0x4,%dx 1ffb15: ec inb (%dx),%al 1ffb16: 24 3f andb $0x3f,%al 1ffb18: ee outb %al,(%dx) # Disable decoding legacy 64KB ranges at F0000h-FFFFFh and E0000h-EFFFFh by setting FWH_Legacy_F_EN = 0 and FWH_Legacy_E_EN = 0 1ffb19: 66 b8 f0 f8 00 80 movl $0x8000f8f0,%eax 1ffb1f: ba f8 0c movw $0xcf8,%dx 1ffb22: 66 ef outl %eax,(%dx) 1ffb24: 83 c2 04 addw $0x4,%dx 1ffb27: 66 8b c3 movl.s %ebx,%eax 1ffb2a: 66 ef outl %eax,(%dx) # Reset the Root Complex Base Address Register to the default value of 0x00000000 (disables back the chipset configuration registers memory mapping) 1ffb2c: 8b d7 movw.s %di,%dx # Restore back dx 1ffb2e: 8e d9 movw %cx,%ds # Restore back ds 1ffb30: ea 5b e0 00 f0 ljmpw $0xf000,$0xe05b # Long jump, who knows where?
但问题出现在此处:执行到ljmpw $0xf000,$0xe05b(目标物理地址FE05Bh)后,下一条指令从何处获取?通常会查看转储文件偏移量0x1e05b,但存在以下情况:
- BIOS转储文件为2MiB,前1MiB全为0xff;
- 代码已禁用F0000h-FFFFFh和E0000h-EFFFFh等传统内存范围解码。
Intel Q35 ICH9 datasheet的13.1.29节(FWH_*标志)给出了一些可能性,但仍不清楚芯片组如何路由该内存访问,以及RPR位设置是否提供线索,诚邀相关解答。
相关转储文件可在开源代码仓库获取。
内容的提问来源于stack exchange,提问作者Amad
相关产品推荐
相关产品推荐

