`
hulianwang2014
  • 浏览: 681062 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

Pinczakko的AwardBIOS逆向工程指导

 
阅读更多

Pinczakko的AwardBIOS逆向工程指导
作 者: beiyu
时 间: 2007-04-05,10:15
链 接: http://bbs.pediy.com/showthread.php?threadid=42166

Pinczakko的AwardBIOS逆向工程指导
作者:Pinczakko
翻译:beiyuhttp://beiyu.bokee.com
Email:beiyuly@gmail.com
时间:2006.6.6

ida的使用和最后展望没有翻译,希望有兴趣的朋友能够补上。

目录
Pinczakko的AwardBios逆向工程指导1
1.序言2
2.准备工作2
2.1.PCIBUS3
2.2.ISABUS4
3.一些硬件特性4
3.1.BIOS芯片地址5
3.2.晦涩的硬件接口(Port)6
3.3."可重定位"硬件Port8
3.4.ExpansionROMHandling9
4.一些软件特性10
4.1.call指令特性10
4.2.retnInstructionPeculiarity10
5.用到的工具13
5.1.我们的需求13
5.2.IDAPro技术介绍13
5.2.1.IDAPro介绍13
5.2.2.IDAProScriptingAndKeyBindings19
6.AwardBIOS文件结构26
6.1.压缩部分26
6.2.纯二进制部分27
6.3.真实系统(Mainboard)中的内存印象27
7.反汇编BIOS28
7.1.Bootblock29
7.1.1."VirtualShutdown"routine29
7.1.2.Chipset_Reg_Early_Initroutine29
7.1.3.Init_Interrupt_n_PwrMgmtroutine35
7.1.4.CallTo"EarlySiliconSupport"Routine36
7.1.5.BootblockIsCopiedAndExecutedInRAM37
7.1.6.Calltobiosdecompressionroutineandthejumpintodecompressedsystembios39
7.1.6.1.EnableFFF80000h-FFFDFFFFhdecoding40
7.1.6.2.Copylower128KBofBIOScodefromROMchipintoRAM40
7.1.6.3.DisableFFF8_0000h-FFFD_FFFFhdecoding40
7.1.6.4.VerifychecksumofthewholecompressedBIOSimage40
7.1.6.5.Lookforthedecompressionengine41
7.1.6.6.DecompressthecompressedBIOScomponents41
7.1.6.7.ShadowtheBIOScode60
7.1.6.8.EnablethemicroprocessorcachethenjumpintothedecompressedsystemBIOS60
7.2.SystemBIOSa.k.aOriginal.tmp61
7.2.1.Entrypointfrom"BootblockinRAM"61
7.2.2.Theawardext.romandExtensionBIOSComponents(lower128KBbios-code)RelocationRoutine62
7.2.3.CalltothePOSTroutinea.k.a"POSTjumptableexecution"64
7.2.4.The"segmentvector"Routines68
7.2.5."chksum_ROM"Procedure72
7.2.6.Original.tmpDecompressionRoutineforThe"Extension_BIOSComponents"72
7.2.7.MicrocodeUpdateRoutine90
8.激昂展望92
9.结束语92

1.序言
我非常欢迎你能够来实践复杂的AwardBios的代码研究工作。本文不是一篇官方的AwardBios逆向工程的文章,也不是由Award公司内部人员编辑的。我只是一个好奇的普通人,我真的很喜欢搞清楚我的电脑的Bios是怎样工作的。我写这篇文章的是为了公开我的发现和研究,从而回报那些我所犯的错误,都是我在逆向工程进程当中所犯的。你有几个可能性来读这篇文章,也许你是一个老资格的黑客,也许你是一个像我一样的系统程序设计爱好者,也许你只是一个好奇的外行。只有一点是肯定的,你肯定可以从这篇文章有所收获,可以提高你的技巧。无论如何,我已经写了一个准备章节,来保证你吸收这篇文章所具备的知识。
除非你自己反汇编了Bios的文件,你是不会理解搞清楚BIOS的工作的。
这篇文章的目的是消除疑惑,定位好你自己,在开始对BIOS的逆向工程工作中,为你提供一个参考。
2.准备工作
1.我必须承认,这个工作需要x86的知识。
2.保护模式下的编成开发知识。你必须学会怎样让x86机器从实模式转移到保护模式。也就是说,你必须学会初步的x86保护模式OS开发。www.osdever.net是一个很好的学习这方面知识的网站。最重要的事情是保护模式的数据结构是怎样工作的。我的意思是GDT、IDT、x86控制寄存器和段寄存器是怎样工作的,特别是awardbios用他们来实现他的奇妙的地方——稍后文章解释。
3.什么是x86的不真实模式。他是一个x86机器在真是模式和保护模式之间的的状态——稍后文章解释。
4.X86直接硬件编程开发。你需要知道怎样编程直接制硬件,特别是在你主板上面的。你可以联系这个,通过windows上的直接访问硬件程序开发练习。这个不是必需的,但是如果你懂的话,会给你带来很多方便。你也需要知道一些x86总线协议,比如PCI和ISA——稍后文章解释。
5.你必须理解大部分你的主板芯片的手册。比如北桥和南桥控制寄存器。
2.1.PCIBUS
官方的PCI总线标准系统是由PCISIG(PCISpecialInterestGroup)维持的。他可能是某种公司,他介于Intel和其他大公司,比如Microsoft。他将要被Arapahoe(PCI-Expressa.k.aPCI-e)andHypertransport代替。但是PCI曾经是在保持一种标准。Hypertransport向后兼容PCI。Arapahoe也是一样。只是这个PCI的标准是没有公开的。
首先,PCIBUS是一个32位宽度的总线。通讯需要32bit的地址模式。读写操作需要32位地址。64位PCIBus不是天生就是,他使用了双重地址回路实现。所以你可以说PCI就是一个32位总线的系统。
其次,这个总线系统定义位置是,控制端口PORTCF8h–CFBh,数据端口CFCh–CFFh。这些端口用来配置相应的PCI芯片,比如读写PCI芯片的配置寄存器值。
第三,这个总线系统强制我们和PCI通讯需要遵守下面的法则(从用户CPU观点):
1.写目标总线号,设备号,功能号和偏移/寄存器号到配置地质端口,然后使能bit置1。通俗讲就是,写寄存器的地址到你想要写入的PCI地址端口。
2.从一个配置数据端口执行一个one-byte,two-byte,orfour-byteI/O读操作或者写操作。通俗讲就是,读写数据从你想要读写的PCI端口。
作为一个提示,据我所知,每一个今天用到的BUS/通讯协议,使用简单的法则来使芯片互相通讯,而这些芯片有一个复杂的总线协议。
有了上面的定义,这里提供一个x86的汇编码片断,来说明怎样使用这些配置端口。
No.Mnemonic(masmsyntax)Comment
1Pushad保存所有通用寄存器的值
2moveax,80000064h把将要访问的PCI芯片寄存器的地址放入eax
(offset64hdevice00:00:00orhostbridge)
3movdx,0CF8h地址端口放入dx。因为是PCI,我们用CF8h作为端口,来打开访问这个设备。
4outdx,eax发送PCI地址端口到processor的I/O空间
5movdx,0CFCh数据端口放入dx。因为是PCI,我们用CFCh作为端口,来和这个设备数据通信。
6ineax,dx将从这个设备读出的数据放入eax
7oreax,00020202改变数据(thisisonlyexample,don'ttrythisinyourmachine,itmayhangorevendestroyyourmachine)
8outdx,eax将数据发送回设备
9............-
10Popad出栈所有寄存器值
11Ret返回

我想上面的代码已经非常清晰了。这里有一个PCI寄存器地址格式例子:
moveax,80000064h

the80000064histheaddress.Themeaningofthesebitsare:
bitposition313029282726252423222120191817161514131211109876543210
binaryvalue10000000000000000000000001100100
hexadecimalvalue80000064
Bit31是一个使能标志。如果这个位置设置了,我们就给与PCIbus读写通信的权利了,否则就是禁止。那就是为什么我们在最左边有一个8的原因。
Bits30-24保留bits。
Bits23-16是PCIBus号。
Bits15-11是PCI设备号。
Bits10-8是PCI功能号。
Bits7-0是偏移地址。
80000064h的意思就是我们通讯的设备是bus0,device0,function0,偏移地址是64h。实际上这个是我们主板上面的北桥芯片中的存储控制配置寄存器。大多数环境下,bus0,device0,function0是Hostbridge,你需要参考自己的芯片数据表来改变这个。大概来讲,他们要作如下工作:读取偏移地址,改写数据,写回设备。
2.2.ISABUS
AFAIK(恕我直言),ISAbus不是标准的总线。因此,实际上任何ISA设备可以存在于系统的16-bitI/O地址空间。我对ISAbus的经验很有限(CMOSchip,mainboard'shardwaremonitoringchip-WinbondW83781D)。这两个芯片用了上面提到的PCIbus通用算法:
1.先送出你想要读写的设备的地址。只有那样,你才可以通过这个设备的数据端口发送接收数据。
2.通过数据端口,发送接收将要通过设备读写的数据。
我的硬件监视芯片用端口295h作为地址端口,296h作为数据端口。CMOS用70h作为地址端口,71h作为数据端口。
3.一些硬件特性
X86平台存在很多hack,特别是他的bios。这个要归功于向下兼容。这章要讨论一对在我BIOS反汇编中遇到的问题。
3.1.BIOS芯片地址
最重要的负责bios代码处理的芯片是南桥和北桥芯片。由于这方面,北桥负责系统地址空间管理,比如biosshadowing,处理访问RAM和处理事务,用biosROM作为南桥的目标,南桥最后积存biosrom。南桥主要负责使能rom解码控制,这将要寄存要访问的biosrom的存储地址。下面展示的地址可以存在于系统DRAM和biosrom芯片中的任何一个,这取决于在bios代码执行时,南桥和北桥寄存器的设置。
PhysicalAddressAlsoKnownAsUsedbyAddressAliasingNote
000F_0000h-000F_FFFFhF_seg/F_segment1Mbit,2MBit,and4MBitBIOSaliastoFFFF_0000h-FFFF_FFFFhinallchipsetjustafterpower-up
000E_0000h-000E_FFFFhE_seg/E_segment1Mbit,2MBit,and4MBitBIOSaliastoFFFE_0000h-FFFE_FFFFhinsomechipsetjustafterpower-up
上面的地址范围包含了bios代码和很多的系统特性。所以你不得不参考你的芯片数据表来理解它。而且,在bios代码运行后的时间里,注意上面的地址要被bios代码占据的是F_segi.e.F_0000h-F_FFFFh。无论怎样,相当的操作系统可能会认为这段地址没有用,而且会把它用于自己的目的。上面提到的地址只是当bios代码访问或者其他代码直接访问biosrom的时候,反映了biosrom芯片到系统地址空间映射。就像我们要看到的一样,这个映射可以通过程序设计一些芯片寄存器来改变。
超过1m的Bios芯片,比如2m和4m的芯片有一个非常与众不同的低bios区域地址,i.e.C_seg,D_seg和其他低"segment(s)"。大多数情况,这个区域被映射到了靠近4GB地址范围。这个地址范围处理是从类似北桥到PCI地址范围来解决。这个配置下芯片行为如下:
•北桥作为一个地址传送装置:在不同方式和普通内存地址比较的状态下,它对这个特别的内存地址有反应,内存地址直接指向RAM。相反,这个特别的内存地址由北桥转到南桥,从而解码。
•南桥作为地址解码器:它解码这个特别的内存地址,这个地址指向正确的芯片,比如bios芯片。这方面,如果地址范围不被允许在南桥控制寄存器解码,南桥要返回“void”(bus地址周期结束)。
下面是一个例子:
PhysicalAddressAlsoKnownAsUsedbyAddressAliasingNote
000F_0000h-000F_FFFFhF_seg/F_segment1Mbit,2MBit,and4MbitBIOSaliastoFFFF_0000h-FFFF_FFFFhinallchipsetjustafterpower-up
000E_0000h-000E_FFFFhE_seg/E_segment1Mbit,2Mbit,and4MbitBIOSaliastoFFFE_0000h-FFFE_FFFFhinsomechipsetjustafterpower-up
FFFD_0000h-FFFD_FFFFhD_seg/D_segment2Mbit,and4MbitBIOS-
FFFC_0000h-FFFC_FFFFhC_seg/C_segment2Mbit,and4MbitBIOS-
FFF8_0000h-FFFB_FFFFh-4MbitBIOS-

结论是:现代芯片组表现为效法F_segandE_seg处理。这是一个证据,证明现代x86系统保持着向下兼容。无论如何,卖主已经远离x86,这些“杂牌电脑(cludge)”往往被认为是过去的东西。
下面是在刚刚系统加电启动后,VIA693A芯片组(北桥)系统内存映射,根据芯片数据表。
Table4.SystemMemoryMap
SpaceStartSizeAddressRangeComment
DOS0640K00000000-0009FFFFCacheable
VGA640K128K000A0000-000BFFFFUsedforSMM
BIOS768K16K000C0000-000C3FFFShadowCtrl1
BIOS784K16K000C4000-000C7FFFShadowCtrl1
BIOS800K16K000C8000-000CBFFFShadowCtrl1
BIOS816K16K000CC000-000CFFFFShadowCtrl1
BIOS832K16K000D0000-000D3FFFShadowCtrl2
BIOS848K16K000D4000-000D7FFFShadowCtrl2
BIOS864K16K000D8000-000DBFFFShadowCtrl2
BIOS880K16K000DC000-000DFFFFShadowCtrl2
BIOS896K64K000E0000-000EFFFFShadowCtrl3
BIOS960K64K000F0000-000FFFFFShadowCtrl3
Sys1MB?00100000-DRAMTopCanhavehole
BusDTopDRAMTop-FFFEFFFF
Init4G-64K64KFFFEFFFF-FFFFFFFF000Fxxxxalias
最重要的要考虑到的东西是地址别名,比如你看到的FFFE_FFFFh-FFFF_FFFFh范围就是000Fxxxxh别名,这个就是biosrom芯片地址映射的地方(我得主板)。但是,我们不得不认为,这个是在启动阶段最初的时候(reset后)。在芯片重新被bios改编程序后,这个地址范围就会映射到了RAM中。我们认为这个是作为加电启动默认值。作为一个标记,主要的x86芯片用这个地址作为别名,至少是F-segment地址范围。
另外一个事实就是我们不得不考虑:大部分芯片组在加电后,寄存器中,只提供默认F-segment地址配置,其他biosrom段保持不可访问。这些段的地址配置将要少后由bootblock代码在改变了相关芯片组寄存器后配置(大部分是南桥寄存器)。这里研究的芯片属于这个组。
现代系统连接biosrom芯片和南桥芯片是通过LPC(LowPinCount)接口。无论怎样,本文中的南桥没有这样的接口。它是一个老的芯片,使用ISAbus作为和biosrom的接口。
3.2.晦涩的硬件接口(Port)
下面提到的一些晦涩的硬件接口没有在芯片数据文档提到。注意,这些信息是从IntelICH5,VIA586B和VIA596B的数据表中得到。
I/OPortaddressPurpose
92hFastA20andInitRegister
4D0hMasterPICEdge/LevelTriggered(R/W)
4D1hSlavePICEdge/LevelTriggered(R/W)

Table146.RTCI/ORegisters(LPCI/F桪31:F0)
I/OPortLocationsIfU128Ebit=0Function
70hand74hAlsoaliasto72hand76hReal-TimeClock(StandardRAM)IndexRegister
71hand75hAlsoaliasto73hand77hReal-TimeClock(StandardRAM)TargetRegister
72hand76hExtendedRAMIndexRegister(ifenabled)
73hand77hExtendedRAMTargetRegister(ifenabled)

注意:
1.I/O位置的70h和71h是标准的服务于真实时间时钟的ISA接口。表格147所示。72h和73h作为访问扩展RAM。扩展RAM单元的访问依然通过索引配置。I/O地址72h作为地址指针,73h作为数据寄存器。索引地址127h以上不可用。如果不需要扩展RAM,它就变得不可用了。
2.软件比如保留地址70h的bit7。当顺序写入这个地址的时候,软件必须先读出这个位置的值,然后写入现同的值到bit7。注意70h不是可以直接读取的。唯一的方法是通过alt访问,读取相应寄存器的值。如果NMI#(不可屏蔽中断)使能没有在普通操作下改变,那么软件能够二者选一的读取这个bit一次,然后保留这个值,一边随后的所有写入端口70h操作。

RTC(通路控制)包含了两个索引寄存器配置,用于被两个分离索引和目标寄存器(70/71hor72/73h)访问,如147表格所示。

Table147.RTC(Standard)RAMBank(LPCI/F桪31:F0)
IndexName
00hSeconds
01hSecondsAlarm
02hMinutes
03hMinutesAlarm
04hHours
05hHoursAlarm
06hDayofWeek
07hDayofMonth
08hMonth
09hYear
0AhRegisterA
0BhRegisterB
0ChRegisterC
0DhRegisterD
0Eh?Fh114BytesofUserRAM

3.3."可重定位"硬件Port
系统I/O空间中,有一些硬件端口种类可以重定位。在这个bios,那些端口包括smbus-related端口和电源管理相关端口。这些端口当然是基本地址。这些所谓的基本地址是通过可以编程的基址寄存器控制的。Smbus由smbus基址寄存器,电源管理由电源管理I/O基址寄存器。所以这些端口是可编程的,bootblock历程在bios历程执行开始的时候初始化这些地址寄存器的值。由于这些端口的可编程特性,就必需要开始biosbootblock的逆向工程来查出哪个端口地址用来这些可编程硬件端口。否则,就会搞不清楚稍后逆向工程中怪异端口的事件。例如:
AddressHexMnemonic
F000:F604BEC4F6movsi,0F6C4h;addrofchipsetregmask
F000:F607next_PCI_reg:;CODEXREF:Chipset_Reg_Early_Init+29
F000:F6072E8B0Cmovcx,cs:[si]
F000:F60ABC10F6movsp,0F610h
F000:F60DE9F800jmpRead_PCI_Byte
F000:F60D;---------------------------------------------------------------------------
F000:F61012F6dw0F612h
F000:F612;---------------------------------------------------------------------------
F000:F6122E224402andal,cs:[si+2]
F000:F6162E0A4403oral,cs:[si+3]
F000:F61ABC20F6movsp,0F620h
F000:F61DE90201jmpWrite_PCI_Byte
F000:F61D;---------------------------------------------------------------------------
F000:F62022F6dw0F622h
F000:F622;---------------------------------------------------------------------------
F000:F62283C604addsi,4
F000:F62581FE04F7cmpsi,0F704h;arewedoneyet?
.........
F000:F6F4483Bdw3B48h;B#0D#7F#3:PwrMngmt&SMBus-PwrMngmtIOBaseAddrlo_byte
F000:F6F600db0;andmask
F000:F6F700db0;ormask
F000:F6F7;
F000:F6F8493Bdw3B49h;B#0D#7F#3:PwrMngmt&SMBus-PwrMngmtIOBaseAddrhi_byte
F000:F6FA40db40h;andmask
F000:F6FB40db40h;PwrMngmtIOBaseAddr=IOPort4000h
.........
F000:F643B9903Bmovcx,3B90h;B#0D#7F#3:PwrMngmt&SMBus-SMBusIOBaseAddrlo_byte
F000:F646B000moval,0;setSMBusIOBaselo_byteto00h
F000:F648BC4EF6movsp,0F64Eh
F000:F64BE9D400jmpWrite_PCI_Byte
F000:F64B;---------------------------------------------------------------------------
F000:F64E50F6dw0F650h
F000:F650;---------------------------------------------------------------------------
F000:F650B9913Bmovcx,3B91h;B#0D#7F#3:PwrMngmt&SMBus-SMBusIOBaseAddrhi_byte
F000:F653B050moval,50h;'P';setSMBusIOBasehi_byteto50h,
F000:F653;so,nowSMBusIOBaseisatport5000h!!!
F000:F655BC5BF6movsp,0F65Bh
F000:F658E9C700jmpWrite_PCI_Byte
F000:F658;---------------------------------------------------------------------------
F000:F65B5DF6dw0F65Dh
.........
F000:F66ABA0540movdx,4005h;accessACPIReg05h
F000:F66DB080moval,80h;'?;settingreservedbit?
.........
当然,还有更多的可重定向硬件端口,但是至少你已经看到了这些提示。所以,一旦逆发现bios中的代码有点象访问怪异的端口,你将会知道它去哪里。
3.4.ExpansionROMHandling
有一对问题需要考虑到,比如videobios和其他扩展rom处理。这里是基本bios中PCI扩展rom处理run-down:
1.系统bios检测所有的系统中的pci芯片,初始化他们的BARs(基址寄存器)。一旦初始化结束,系统就拥有了一个可用的广阔的系统地址配置。
2.通过广阔的系统地址配置,系统bios一个接一个的拷贝需要的PCI扩展rom到RAM,这些扩展在(C000:0000h-D000:FFFFh),并且执行每一个模块或者初始化每一个模块。
至于ISA扩展rom,以后版本文章会讨论。
4.一些软件特性
在bios代码中有一些棘手的区域和rom中一些可执行部分有关。下面介绍:
4.1.call指令特性
Call指令在rombios芯片内部的bios代码执行时不可用。这由于call指令使用桟,而我们不能在biosrom中写入来使用桟。这里使用桟是因为要压入call指令执行时写入保存的返回地址。我们很清楚的知道,这个时候地址指针ss:sp指向的时rom:我们不能写入。DRAM这个时候不能使用。它还没有被bios代码检测。我们根本就不知道有RAM存在!
4.2.retnInstructionPeculiarity
Retn指令特性,这里有ROM_call宏定义:
ROM_CALLMACRORTN_NAME
LOCALRTN_ADD
movsp,offsetDGROUP:RTN_ADD
jmpRTN_NAME
RTN_ADD:dwDGROUP:$+2
ENDM
例子:
AddressHexMnemonic
F000:6000F000_6000_read_pci_byteprocnear
F000:600066B800000080moveax,80000000h
F000:60068BC1movax,cx;copyoffsetaddrtoax
F000:600824FCandal,0FCh;maskit
F000:600ABAF80Cmovdx,0CF8h
F000:600D66EFoutdx,eax
F000:600FB2FCmovdl,0FCh
F000:60110AD1ordl,cl;getthebyteaddr
F000:6013ECinal,dx;readthebyte
F000:6014C3retn;ReturnNearfromProcedure
F000:6014F000_6000_read_pci_byteendp
......
F000:60431800GDTR_F000_6043dw18h;limitofGDTR(3validdescentry)
F000:604549600F00dd0F6049h;GDTphysicaladdr(below)
F000:60490000000000000000dq0;nulldescriptor
F000:6051FFFF00000F9F0000dq9F0F0000FFFFh;codedescriptor:
F000:6051;baseaddr=F0000h;limit=FFFFh;DPL=0;
F000:6051;exec/ReadOnly,conforming,accessed;
F000:6051;granularity=byte;Present;16-bitsegment
F000:6059FFFF000000938F00dq8F93000000FFFFh;datadescriptor:
F000:6059;baseaddr=00h;seg_limit=FFFFFh;DPL=0;
F000:6059;Present;read-write,accessed;
F000:6059;granularity=4KByte;16-bitsegment
......
F000:619B0F01164360lgdtqwordptrGDTR_F000_6043;LoadGlobalDescriptorTableRegister
F000:61A00F20C0moveax,cr0
F000:61A30C01oral,1;setPModeflag
F000:61A50F22C0movcr0,eax
F000:61A8EAAD610800jmpfarptr8:61ADh;jmpbelowin16-bitPMode(absaddrF61ADh)
F000:61A8;(codesegmentwithbaseaddr=F0000h)
F000:61AD;---------------------------------------------------------------------
F000:61ADB81000movax,10h;loaddswithvaliddatadescriptor
F000:61B08ED8movds,ax;ds=datadescriptor(GDT3rdentry)
......
F000:61BCB96B00movcx,6Bh;DRAMarbitrationcontrol
F000:61BFBCC561movsp,61C5h
F000:61C2E93BFEjmpF000_6000_read_pci_byte;Jump
F000:61C2;------------------------------------------------------------------
F000:61C5C761dw61C7h
F000:61C7;------------------------------------------------------------------
F000:61C70C02oral,2;enableVC-DRAM
你看到的,必需要考虑retn指令被当前ss:sp寄存器值影响,ss寄存器还没有加载到正确的16-bit保护模式使用!这些代码怎么会执行?答案有点复杂。让我们看看ss寄存器的值,它在上述调用之前就巧妙的处理了。
AddressHexMnemonic
F000:E0608CC8movax,cs
F000:E0628ED0movss,ax;ss=cs(ss=F000ha.k.aF_segment)
F000:E064assumess:F000
Note:thisroutineisexecutedinreal-mode
就如你看到的,ss寄存器装入了f000h(当前bios代码16-bit段在实模式)。这段代码说明隐藏的描述缓存寄存器(存在为每一个选择/段寄存器)被加载入ss*16orF_0000h的物理地址值。并且这个值会返回,尽管机器转变成了上述的16-bit保护模式,因为ss寄存器没有重载。IntelSoftwareDeveloperManualVol.3片断:

8.1.4.FirstInstructionExecuted
ThefirstinstructionthatisfetchedandexecutedfollowingahardwareresetislocatedatphysicaladdressFFFFFFF0H.Thisaddressis16bytesbelowtheprocessor抯uppermostphysicaladdress.TheEPROMcontainingthesoftware-initializationcodemustbelocatedatthisaddress.TheaddressFFFFFFF0Hisbeyondthe1-MByteaddressablerangeoftheprocessorwhileinreal-addressmode.Theprocessorisinitializedtothisstartingaddressasfollows.TheCSregisterhastwoparts:thevisiblesegmentselectorpartandthehiddenbaseaddresspart.Inrealaddressmode,thebaseaddressisnormallyformedbyshiftingthe16-bitsegmentselectorvalue4bitstothelefttoproducea20-bitbaseaddress.However,duringahardwarereset,thesegmentselectorintheCSregisterisloadedwithF000HandthebaseaddressisloadedwithFFFF0000H.ThestartingaddressisthusformedbyaddingthebaseaddresstothevalueintheEIPregister(thatis,FFFF0000+FFF0H=FFFFFFF0H).
ThefirsttimetheCSregisterisloadedwithanewvalueafterahardwarereset,theprocessorwillfollowthenormalruleforaddresstranslationinreal-addressmode(thatis,[CSbaseaddress=CSsegmentselector*16]).ToinsurethatthebaseaddressintheCSregisterremainsunchangeduntiltheEPROMbasedsoftware-initializationcodeiscompleted,thecodemustnotcontainafarjumporfarcallorallowaninterrupttooccur(whichwouldcausetheCSselectorvaluetobechanged).
Ddj(DoctorDobbsJournal)的一个小片断:

Atpower-up,thedescriptorcacheregistersareloadedwithfixed,defaultvalues,theCPUisinrealmode,andallsegmentsaremarkedasread/writedatasegments,includingthecodesegment(CS).AccordingtoIntel,eachtimetheCPUloadsasegmentregisterinrealmode,thebaseaddressis16timesthesegmentvalue,whiletheaccessrightsandsizelimitattributesaregivenfixed,"real-modecompatible"values.Thisisnottrue.Infact,onlytheCSdescriptorcacheaccessrightsgetloadedwithfixedvalueseachtimethesegmentregisterisloaded-andeventhenonlywhenafarjumpisencountered.Loadinganyothersegmentregisterinrealmodedoesnotchangetheaccessrightsorthesegmentsizelimitattributesstoredinthedescriptorcacheregisters.Forthesesegments,theaccessrightsandsegmentsizelimitattributesarehonoredfromanyprevioussetting(seeFigure3).Thusitispossibletohaveafourgiga-byte,read-onlydatasegmentinrealmodeonthe80386,butIntelwillnotacknowledge,orsupportthismodeofoperation.

现在,你知道重点在于描述缓存寄存器,特别是它的基地址部分。Ss可见部分只是一个“placeholder”和“register-in-charge”,对于真实地址计算/变换是一个隐藏的描述缓存。无论你对这个描述缓存做什么,当任何代码、栈或者数据值地址被转换计算的时候,它都要受到影响。在我们看来,我们不得不在16-bit保护模式使用基址是F_0000h的物理地址的“堆栈段”。这不是问题,因为ss描述缓存寄存器的基址已经在上面的代码中赋予了F_0000h值。这就解释了为什么上面的代码能够正确执行,下面是一个例子:
AddressHexMnemonic
F000:61BFBCC561movsp,61C5h
F000:61C2E93BFEjmpF000_6000_read_pci_byte;Jump
F000:61C2;------------------------------------------------------------------
F000:61C5C761dw61C7h
这段代码里面我们已经给ss:sp指向F_61C5h,为retn指令服务。实际上,我们已经做了,因为ss包含了F_0000h(它的描述缓存基址部分)和你看到(spcontains61C5h)的物理地址,ss:sp是F_0000h+61C5h,物理地址是F_61C5h。
5.用到的工具
本节介绍逆向工程分析所需的工具。将有一节单独解释IDAPro反汇编工具。
5.1.我们的需求
开始进行之前,我们需要以下工具:
1、IDAPro反汇编工具。我使用IDAProV4.3。你可以使用你喜欢的交互式反汇编工具。我觉得IDAPro最适合我。我们之所以需要交互式反汇编工具,因为我们要反汇编的BIOS代码并不是普通的代码。当驻留在ROM中执行的一些时候并没有栈可用,而是使用了一些栈的技巧来进行过程/例程调用。
2、一个好的二进制编辑器。我使用HexWorkshopver3.0b。该二进制编辑器最大的一个好处是它可以计算打开文件的所选范围内的校验和。
3、LHA2.55,用来修改BIOS二进制。如果你仅想解压缩并分析压缩的BIOS组件,也可使用winzip或其他可以处理LZH/LHA文件的压缩/解压缩工具。
4、BIOS修改工具,例如CBROM,我使用v2.08,v2.07和1.24。以及MODBIN,有两种:modbin6forawardbiosver.6和modbin4.50.xxforawardbiosver.4.5xPGNM。使用这些工具更容易查看BIOS组件。可从www.biosmods.com下载。
5、一些芯片集数据表,这取决于你要解剖的主板BIOS代码。www.com.by上有一部分pdf格式的数据表。我解剖的主板是VIA693A-596B,我当然有这个数据表。
6、IntelSoftwareDeveloperManualVolume1,2and3。BIOS有时使用一些外来指令集。另外有些很难记住的数据结构需要查询,如GDT、IDT等。
5.2.IDAPro技术介绍
本小节介绍使用IDAPro。如果抓住了这些概念,你可以方便地使用IDApro。
5.2.1.IDAPro介绍
逆向代码工程通过分析软件的可执行文件来实现对软件所使用算法的理解。在大多数情况下,软件仅发布它的可执行文件而没有源代码。BIOS也同样如此,我们可获得的仅仅是执行代码。逆向代码工程在以下工具的帮助下实现:调试器,反汇编工具,二进制文件编辑器即二进制编辑器,ICE()等。我们在本小节中仅讨论反汇编工具,例如IDAPro反汇编工具。
IDAPro是一款强大的反汇编工具。它支持插件和脚本组件支持50种以上的处理器结构。但功能强大的工具一般都有缺陷,就是难以掌握使用,IDAPro也不例外。
IDAPro有多个版本:免费版、标准版和高级版。最新的免费版为IDAProversion4.3(AFAIK),可在http://www.dirfile.com/ida_pro_freeware_version.htm下载。
ThereareseveraleditionsofIDAPro:freewareedition,standardeditionandadvancededition.ThelatestfreewareeditionisIDAProversion4.3(AFAIK)andit抯availablefordownloadathttp://www.dirfile.com/ida_pro_freeware_version.htm.It抯themostlimitedofallIDAProversion.Itonlysupportsx86processoranddoesn'tcomewithpluginfeature,butitcomesatnocost,that'swhyit'spresentedhere.Fortunately,itstillcomeswithscriptingfeature.ThestandardandadvancededitionsofIDAPro4.3ofcoursedifferfromthisfreewareedition,theycomewithsupportforpluginandsupportformuchmoreprocessorarchitecture.Wearegoingtolearnhowtousethescriptingfeatureinthenextsection.
Now,let抯starttouseIDAProfreewareversiontoopenaBIOSbinaryfile.First,IDAProfreewareversionhastobeinstalled.Aftertheinstallationfinished,onespecialstepmustbecarried-outtopreventunwantedbugwhenthisversionofIDAProopensupaBIOSfilewith*.romextension.Todoso,onemustedittheIDAProconfigurationfilethat抯locatedintherootdirectoryoftheIDAProinstallationdirectory.Thenameofthefileisida.cfg.Openthisfilebyusinganytexteditor(suchasnotepad)andlookforthefollowinglines:
DEFAULT_PROCESSOR={
/*ExtensionProcessor*/
"com":"8086"//IDAwilltrythespecified
"exe":""//extensionsifnoextensionis
"dll":""//given.
"drv":""
"sys":""
"bin":""//Emptyprocessormeansthedefaultprocessor
"ovl":""
"ovr":""
"ov?":""
"nlm":""
"lan":""
"dsk":""
"obj":""
"prc":"68000"//PalmPilotprograms
"axf":"arm710a"
"h68":"68000"//MC68000for*.H68files
"i51":"8051"//i8051for*.I51files
"sav":"pdp11"//PDP-11for*.SAVfiles
"rom":"z80"//Z80for*.ROMfiles
"cla*":"java"
"s19":"6811"
"o":""
"*":""//Defaultprocessor
}
Noticetheline:"rom":"z80"//Z80for*.ROMfiles
Thislinemustberemovedorjustreplacethe"z80"with""inthislinetodisabletheautomaticrequesttoloadz80processormoduleinIDAProuponopeninga*.romfile.Thebugoccurredifthe*.romfileisopenedwhilethislineisnotchangedincefreewareIDAProdoesn'tcomewithz80processormodule.Thus,opening*.romfilebydefaultwillterminateIDAPro.SomemotherboardBIOSfilescomeswith*.romextensionbydefault,eventhoughit'sveryclearthatitwon'tbeexecutedinz80processor.FixingthisbugwillensurethatwewillbeabletoopenmotherboardBIOSfilewith*.romextensionflawlessly.Notethatthestepsneededtoremoveotherfile-extensiontoprocessor-type"mapping"inthisversionofIDAProissimilartothez80processorthatisjustdescribed.
Nowlet'sproceedtoopenasampleBIOSfile.ThisBIOSfileisda8r9025.rom,BIOSfileforSupermicroH8DAR-8(OEMOnly)motherboard.ThismotherboardusedAMD-8131™HyperTransport™PCI-XTunnelchipandAMD-8111™HyperTransport™I/OHubchip.ThedialogboxbelowwillbedisplayedwhenyoustartIDAProfreewareversion4.3.

JustclickOKtoproceed.Thenthenextdialogboxshownbelowwillbedisplayed.

Inthisdialogbox,youcantryoneofthethreeoptions,butwewilljustclickontheGobutton.ThiswillstartIDAProwithemptyworkspaceasshownbelow

ThenlocateanddragthefiletobedisassembledtotheIDAProwindow(asshownabove).Inthiscase,IDAProwillshowthefollowingdialogbox.

Inthisdialogbox,wewillselectIntel80x86processors:athlonastheProcessortypeinthedropdownlistbox.ThenclickontheSetbuttontoactivatethenewprocessorselection.Lettheotheroptionasitis.CoderelocationwillbecarriedoutbyusingIDAProscriptsinlatersection,thenclickOK.IDAProthenshowsthefollowingdialogbox.

Thisdialogboxasksustochoosethedefaultoperating-modeofthex86compatibleprocessorduringthedisassemblingprocess.AMD64ArchitectureProgrammer抯ManualVolume2:SystemProgramming,February2005insection14.1.5page417statesthat:
"AfteraRESET#orINIT,theprocessorisoperatingin16-bitrealmode."
Inaddition,IA-32Intel®ArchitectureSoftwareDeveloper抯ManualVolume3:SystemProgrammingGuide2004section9.1.1statesthat:
"Table9-1showsthestateoftheflagsandotherregistersfollowingpower-upforthePentium4,IntelXeon,P6family,andPentiumprocessors.ThestateofcontrolregisterCR0is60000010H(seeFigure9-1),whichplacestheprocessorisinreal-addressmodewithpagingdisabled."
Thus,wecanconcludethatanyx86compatibleprocessorsstarttheirexecutionin16-bitrealmodejustafterpower-upandwehavetochoose16-bitmodeinthisdialogbox.It抯accomplishedbyclickingNointhedialogbox.Thenthefollowingdialogboxpopsup.

ThisdialogboxtoldusthatIDAProcan抰decidewheretheentry-pointlocated.Wehavetolocateitourselveslater.JustclickOKtocontinuetothemainwindowforthedisassemblyprocess.

UptothispointweareabletoopenthebinaryfilewithinIDAPro.ThisisnotatrivialtaskforpeoplenewtoIDAPro.That'swhyit'spresentedinastep-by-stepfashion.However,theoutputintheworkspaceisnotyetusable.ThenextstepislearningthescriptingfacilitythatIDAProprovidestomakesenseaboutthedisassemblydatabasethatIDAProgenerates.
5.2.2.IDAProScriptingAndKeyBindings
NowwewillproceedtotrytodecipherIDAProdisassemblydatabaseshownintheprevioussub-sectionwiththehelpofthescriptingfacility.Beforeweproceedtoanalyzethebinary,wehavetolearnsomebasicconceptsabouttheIDAProscriptingfacility.IDAProscriptssyntaxaresimilartoCprogramminglanguage.Thesyntaxasfollows:
1.IDAProscriptsonlyrecognizeonetypeofvariable,i.e.auto.Therearenoothervariabletypessuchasint,char,etc.ThedeclarationofvariableinanIDAProscriptasfollows:
autovariable_name;
2.EverystatementinanIDAProscriptendswithasemicolon(;),justlikeintheCprogramminglanguage.
3.Functioncanreturnavalueornot,butthere抯noreturntypedeclaration.Thesyntaxasfollows:
staticfunction_name(parameter1,parameter2,parameter_n,...)
4.CommentinanIDAProscriptstartswithdouble-slash(//).TheIDAProscriptingengineignoresanythingafterthecommentinthecorrespondingline.
5.//comment
6.statement;//comment
7.IDAPro"exports"itsinternalfunctionalitytothescriptthatwebuildbyusingheaderfiles.Theseheaderfilesmustbe"included"inourscriptsothatweareabletoaccessthatfunctionality.AtleastoneheaderfilemustbeincludedinanyIDAProscript,i.e.idc.idc.TheheaderfilesarelocatedinsideafoldernamedidcintheIDAProinstallationdirectory.Onemustreadthe*.idcfilesinsidethisdirectorytolearnaboutthefunctionsthatareexportedbyIDAPro.Themostimportantheaderfiletolearnisidc.idc.ThesyntaxusedtoincludeaheaderfileinanIDAProscriptis:
8.#include<header_file_name>
9.TheentrypointofanIDAProscriptisthemainfunction,justasintheCprogramminglanguage.
Nowisthetimetoputthetheoryintoasimpleworkingexample,anIDAProsamplescript.
#include<idc.idc>
//relocateonesegment
staticrelocate_seg(src,dest)
{
autoea_src,ea_dest,hi_limit;

hi_limit=src+0x10000;
ea_dest=dest;

for(ea_src=src;ea_src<hi_limit;ea_src=ea_src+4)
{
PatchDword(ea_dest,Dword(ea_src));
ea_dest=ea_dest+4;
}

Message("segmentrelocationfinished(insiderelocate_segfunction)../n");
}

staticmain()
{
Message("creatingtargetsegment(insideentrypointfunctionmain).../n");
SegCreate([0xF000,0],[0x10000,0],0xF000,0,0,0);
SegRename([0xF000,0],"_F000");

relocate_seg([0x7000,0],[0xF000,0]);
}
Thesquarebracket,i.e.[]inthescriptaboveisanoperatorusedtoformthelinearaddressfromitsparametersbyshiftingthefirstparametertoleftfourbitsandthenaddingthesecondparameterintotheresult,forexample:[0x7000,0]means(0x7000<<4)+0,i.e.0x7_0000linearaddress.ThisoperatorisjustthesameasMK_FP(,)operatorinpreviousversionsofIDAPro.Onemustreadidc.idcfiletoseethe"exported"functiondefinitiontounderstandthisscriptcompletely,suchastheMessage,SegCreateandSegRenamefunction.Another"exported"functionthatmaybeofinterestcanbefoundinnumerous*.idcfileintheidcdirectoryofIDAProinstallationfolder.Tobeabletousethefunction,itsdefinitionhavetobelookedupintheexportedfunctiondefinitioninthecorresponding*.idcheaderfile.Forexample,SegCreatefunctionisdefinedinidc.idcasfollows:
//Createanewsegment
//startea-linearaddressofthestartofthesegment
//endea-linearaddressoftheendofthesegment
//thisaddresswillnotbelongtothesegment
//'endea'shouldbehigherthan'startea'
//base-baseparagraphorselectorofthesegment.
//aparagraphis16bytememorychunk.
//Ifaselectorvalueisspecified,theselectorshouldbe
//alreadydefined.
//use32-0:16bitsegment,1:32bitsegment
//align-segmentalignment.seebelowforalignmentvalues
//comb-segmentcombination.seebelowforcombinationvalues.
//returns:0-failed,1-ok

successSegCreate(longstartea,longendea,longbase,longuse32,
longalign,longcomb);
A512KBBIOSbinaryfilemustbeopenedinIDAProwiththeloadingaddresssetto0000htobeabletoexecutethesamplescriptabove.Thisloadingschemeisthesameasexplainedintheprevioussub-section.Inthiscase,wewilljustopenthebinaryfileofSupermicroH8DAR-8motherboardasintheprevioussub-sectionandthenexecutethescript.First,wemusttypethescriptaboveinaplaintextfile.WecanusenotepadoranotherASCIIfileeditorforthispurpose.Wewillnamethefileasfunction.idc.ThescriptthenexecutedbyclickingontheFile|IDCfile...menuorbypressingF2,thenthedialogboxbelowwillbeshown.

Justselectthefileandclickopentoexecutethescript.Ifthere抯anymistakeinthescript,IDAProwillwarnyouwithawarningdialogbox.ExecutingthescriptwilldisplaythecorrespondingmessageinthemessagepaneofIDAProasshownbelow.

Thescriptaboverelocatesthelastsegment(64KB)oftheSupermicroH8DAR-8BIOScodetotherightplace.OnemustbeawarethatIDAProisonlyanadvancedtooltohelpthereversecodeengineeringtask,it抯notamagicaltoolthat抯goingtorevealtheoverallstructureoftheBIOSbinarywithoutusbeingsignificantlyinvolveintheprocess.Thescriptrelocates/copiesBIOScodefromphysical/linearaddress0x7_0000-0x7_FFFFto0xF_0000-0xF_FFFF.Thelogicalreasonbehindthisalgorithmisexplainedbelow.
AMD-8111HyperTransportIOHubDatasheetchapter4page153saysthat:
Note:ThefollowingrangesarealwaysspecifiedasBIOSaddressranges.SeeDevB:0x80formoreinformationabouthowaccesstoBIOSspacesmaybecontrolled.
SizeHostAddressRange[31:0]AddresstranslationforLPCbus
64KbytesFFFF_0000h?FFFF_FFFFhFFFF_0000h?FFFF_FFFFh
64Kbytes000F_0000h?000F_FFFFhFFFF_0000h?FFFF_FFFFh
Inaddition,AMD64ArchitectureProgrammer抯ManualVolume2:SystemProgramming,February2005insection14.1.5page417saysthat:
"Normallywithinrealmode,thecode-segmentbaseaddressisformedbyshiftingtheCS-selectorvalueleftfourbits.ThebaseaddressisthenaddedtothevalueinEIPtoformthephysicaladdressintomemory.Asaresult,theprocessorcanonlyaddressthefirst1Mbyteofmemorywheninrealmode.However,immediatelyfollowingRESET#orINIT,theCSselectorregisterisloadedwithF000h,buttheCSbase-addressisnotformedbyleft-shiftingtheselector.Instead,theCSbaseaddressisinitializedtoFFFF_0000h.EIPisinitializedtoFFF0h.Therefore,thefirstinstructionfetchedfrommemoryislocatedatphysical-addressFFFF_FFF0h(FFFF_0000h+0000_FFF0h).TheCSbase-addressremainsatthisinitialvalueuntiltheCSselectorregisterisloadedbysoftware.Thiscanoccurasaresultofexecutingafarjumpinstructionorcallinstruction,forexample.WhenCSisloadedbysoftware,thenewbase-addressvalueisestablishedasdefinedforrealmode(byleftshiftingtheselectorvaluefourbits)."
Fromthereferencesabove,weconcludethataddress000F_0000h?000F_FFFFhisanaliastoaddressFFFF_0000h?FFFF_FFFFh,i.e.theybothpointstothesamephysicaladdressrange.Wheneverthehost(CPU)accessessomevaluein000F_0000h?000F_FFFFhaddressrange,it'sactuallyaccessingthevalueatFFFF_0000h?FFFF_FFFFhrangeandthereverseisalsotrue.Fromthisfact,weknowthatwehavetorelocate64KBoftheuppermostBIOScodetoaddress000F_0000h?000F_FFFFhforfurtherinvestigation.ThisdecisionismadebasedonmypreviousexperiencewithvariousBIOSbinaryfiles,theygenerallyreferencesaddresswithF000husedasthesegmentvaluewithintheBIOScode.Also,notethatthelast64KBoftheBIOSbinaryfileismappedtolast64KBofthe4GBaddressspace,i.e.4GB-64KBto4GB,that'swhywehavetorelocatethelast64KB.
SimplescriptthatisonlyseverallinescanbetypedandexecuteddirectlywithinIDAProwithoutopeningatexteditor.IDAProprovidesaspecificdialogboxforthispurposeanditcanbeaccessedbypressingShift+F2.Thisismorepracticalforsimpletask,butasthenumberoftheroutinegrows,onemightconsidercodingthescriptasdescribedinthepreviousexplanationduetolimitationofthenumberofinstructionthatcanbeenteredinthedialogbox.Inthisdialogbox,enterthescripttobeexecutedandclickOKtoexecutethescript.Belowisanexamplescript.

Notethatthereisnoneedfor#includestatementinthebeginningofthescript,sincebydefaultallofthefunctionsthatareexportedbyIDAProinitsscriptsheaderfiles(*.idc)isaccessiblewithinthescriptingdialogboxshownabove.Themainfunctionisalsodoesn抰needtobedefined.Infact,anythingyouwritewithinthedialogboxentrywillbehaveasifit'swritteninsidethemainfunctioninanIDAProscriptfile.
Anyway,youmightwanttogototheIDAPalaceformoreIDAProscriptsamples.Itwilltakeawhiletograspthem,butIDAPalaceisdefinitelytheplacetogoifyou'recuriousaboutIDAProscripting.
Atpresent,weareabletorelocatethebinarywithinIDAPro;thenextstepistodisassemblethebinarywithinIDAPro.Beforethat,weneedtoknowhowthedefaultkeybindingworksinIDAPro.Keybindingisthe"mapping"betweenthekeyboardbuttonandthecommandcarried-outwhenthecorrespondingkeyispressed.Thecursormustbeplacedintheworkspacebeforeanycommandiscarried-outinIDAPro.Thekeybindingisdefinedinidagui.cfgfilethat'slocatedinIDAProinstallationdirectory.Anexcerptofthekeybinding(hotkey)isprovidedbelow.
"MakeCode"='C'
"MakeData"='D'
"MakeAscii"='A'
"MakeUnicode"=0//createunicodestring
"MakeArray"="Numpad*"
"MakeUnknown"='U'

"MakeName"='N'
//"MakeAnyName"="Ctrl-N"
"ManualOperand"="Alt-F1"

"MakeFunction"='P'
"EditFunction"="Alt-P"
"DelFunction"=0
"FunctionEnd"='E'
Onecanalteridagui.cfgtochangethedefaultkeybinding,butwewillonlyconsiderthedefaultkeybinding.Nowwehavegraspedthekeybindingconcept,let'sseehowtouseitinourbinary.Inthepreviousexample,wearecreatinganewsegment,i.e.0xF000.Now,wewillgotothefirstinstructionthat'sexecutedintheBIOSwithinthatsegment,i.e.address0xF000:0xFFF0.PressG,thedialogboxbelowwillbeshown.

Inthisdialogbox,enterthedestinationaddress.Youmustentertheaddressincompleteform(segment:offset)asshownabove,i.e.F000:FFF0.Then,clickOKtogototheintendedaddress.Notethatyoudon'thavetotypetheleading0xcharacter,sincebydefault,thevaluewithintheinputboxisinhexadecimal.Theresultwillbeasshownbelow(insideIDAProworkspace).

Thenextsteptodoistoconvertthevalueinthisaddressintoameaningfulmachineinstruction.Todoso,pressC.Theresultisasshownbelow.

Then,wecanfollowthejumpbypressingEnter.Theresultisasshownbelow.

Wecanreturnfromthejumpthatwe'vejustmadebypressingEsc.
Uptothispoint,you'vegainedsignificantintuitiontouseIDAPro.Youjustneedtoconsultthekeybindingsinidagui.cfgincasewanttodosomethinganddon'tknowwhatkeytopress.
________________________________________
Nowwe'rearmed.Whatweneedtodonextistounderstandthebasicstuffbyusingthehexeditorbeforeproceedingthroughthedisassemblingsession.
6.AwardBIOS文件结构
6.1.压缩部分
内存映射16进制表:
1.0000h-3AACh:XGROUPROM(awardext.rom),Award扩展rom.包含由systembios调用的例程,比如original.tmp。
2.3AADh-97AFh:CPUCODE.BIN,bios的微代码。
3.97B0h-A5CFh:ACPITBL.BIN,acpi表。
4.A5D0h-A952h:Iwill.bmp,BMPlogo。
5.A953h-B3B1h:nnoprom.bin,Ihaven'tknowyetwhatthiscomponent'srole。
6.B3B2h-C86Ch:Antivir.bin,bootsector防病毒。
7.C86Dh-1BEDCh:ROSUPD.BIN,我得bios中的自定义部分,用于显示自定义的启动logo和提示符。
8.2_0000h-3_5531h:original.tmp,我得特殊的bios中的systemBIOS部分。大多数的2m的bios在2_0000h-3_xxxxh(ifyoulookfromwithinhexeditor)都有original.tmp。有一些4M的bios有original.tmp在bios二进制文件的最开始的部分,比如0000h。
注意:
a.在压缩的ROSUPD.BIN和original.tmp之间有填充FFhbytes.这些填充bytes在压缩original.tmp和纯二进制BIOS部分之后都有发现。一个例子:
AddressHexASCII

00037D002A424253532A006000700060006000A0*BBSS*.`.p.`.`..
00037D10337746708977ACCFC4CF010000FFFFFF3wFp.w..........
00037D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF................
00037D30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF................
b.这些压缩了的部分可以很容易的,通过拷贝和粘贴到新的二进制文件,通过Hexworkshop。然后,解压这个新的文件,用LHA2.55或者winzip。如果我们使用winzip,那么改编扩展名为.lzh,这样winzip就可以自动识别了。识别我们剪切的部分非常简单,只要看到“-lh5-”字符串就可以了。2bytes的“-lh5-”在文件的最前面,文件最后面总是00h,正好在下一个压缩了的文件前面,正好在填充bytes或者某些checksum前面。我要给你两个例子下面。高亮的bytes是要所的文件的最初和最后的标志。
我得bios中的压缩的CPUCODE.BIN:
AddressHexASCII
00003AA04E6119E697752B46BA5585F00024382DNa...u+F.U...$8-
00003AB06C68352DDC5C000000A0000000000140lh5-./.........@
00003AC020010B435055434F44452E42494EBCAA..CPUCODE.BIN..
00003AD0200000383894970052C4A2CFF0400000..88...R....@..
00003AE040000000000000000000000000000000@...............
........
000097A00E3C8FA7FFF4FFFE9FFFD3FFFFFBFF00.<..............
000097B024D92D6C68352DFA0D0000A621000000$.-lh5-.....!...

我得bios中的压缩的ORIGINAL.TMP:
AddressHexASCII
0001FFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF................
00020000251A2D6C68352D095501000000020000%.-lh5-.U.......
0002001000005020010C6F726967696E616C2E74..P..original.t
000200206D700CD92000002D7888F0FDD624A5BAmp....-x....$..
........
00035510019E6E67BF11858288D94E7CBEC8C34C..ng......N|...L
00035520401D189FBDD0A17617F043831D73BF99@......v..C..s..
0003553000C9FFFFFFFFFFFFFFFFFFFFFFFFFFFF................
00035540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF................

6.2.纯二进制部分
内存印象:
1.3_6000h-3_6C4Ah:这个例程初始化DRAM控制器(在hostbtidge中的),和我的bios中的DRAM时钟。
2.3_7000h-3_7D1Ch:解压缩例程部分。这个例程包含了LZH解压引擎,可以解压缩上面的bios压缩部分。
3.3_C000h-3_CFE4h:这个区域包含了不同的例程,低128KB是bios地址解码启动,默认的VGA初始化(如果系统bios错误执行),剩下的是Hostbridge初始化例程。
4.3_E000h-3_FFFFh:包含BootBlock代码。
注意:一些部分之间是填充.一些是FFhbytes一些是00hbytes.
6.3.真实系统(Mainboard)中的内存印象
我们已经注意到了内存映象,前面提到了bios二进制代码的。在主板bios芯片中,有一点不太一样,并且更加复杂。我得主板的映象如下(和你的可能不一样,参考芯片组文档):

1.Bios二进制文件中的0_0000h-3_FFFFh映射到了系统内存中的FFFC_0000h-FFFF_FFFFh。由于我得系统中的北桥,地址FFFF_0000h-FFFF_FFFFh只是F_0000h-F_FFFFh的别名或者也可以说是在“实模式行话”F000:0000h-F000:FFFFh。注意这个映射适合在加电后,因为它是芯片组加电默认的值。在芯片组被bios重新编程后,不保证是否有效。有一些“kludge(杂牌电脑)”,它们是由系统决定的。你不得不参考IntelSoftwareDeveloperManualVolume3(systemprogramming)和你的芯片数据表。
2.归功于第一点的解释,bios中的纯二进制部分映射如下(加电后):
1)BootBlock:F000:E000h-F000:FFFFh
2)DecompressionBlock:F000:7000h-F000:7D1Ch
3)早期DRAM控制器和DRAM初始化:F000:6000h-F000:6C4Ah
3.压缩的bios部分在他们通过不同方式被释放后映射到系统内存空间。他们依靠这个解压模块例程,但是不同的bios文件中,他们的映射很少有看起来相同的。这些映射(我得如下,你的可能不一样,但是段地址很可能相同):
1)original.tmpa.k.aSystemBIOS:E000:0000h-F000:FFFFh
2)awardext.roma.k.aAward扩展ROM:4100:0000h-4100:xxxxh。稍后被original.tmp重新部署到6000:0000h-6000:xxxxh,比如在它执行之前。

在我们进行我们的旅途中,我们必需要注意这样的映射。

注意:
由于完全复杂的映射到真实系统bios二进制地址,我们很容易迷路。但是,有一个技巧可以方便我们的工作,在我们反汇编进程中,通过使用IDAPro:
从纯二进制部分开始反汇编进程。在地址F000:FFF0h(3_FFF0h从hexeditor看二进制)开始反汇编。为了做到这个,用IDAPro打开二进制文件(VD30728.BIN,i.e.IwillVD133BIOSbinary),然后反汇编这个文件,通过设置它的地址映射到C000:0000h,记住让段名无效,那样我们就可以在系统中,执行的时候看到实模式地址。通过IDAPro的Scripts调整另外的段地址,记住调整地址配置来符合芯片数据表。
7.反汇编BIOS
由于IntelsystemprogrammingGuide,我们就要开始在f000:fff0h地址反汇编了(看看上面的内存映射,调整IDAPro来适应它)。你可能会问:这怎么可能?IntelSoftwareDeveloperManualVol.3(PROCESSORMANAGEMENTANDINITIALIZATION-FirstInstructionExecuted)介绍:
在硬件reset后得到并执行的第一条指令所在的物理地址是FFFFFFF0H。
答案是:北桥芯片组使用000F_xxxxh作为FFFE_FFFFh-FFFF_FFFFh的别名。而且,注意在这个地址的转移之后南桥没有意义。它只是直接将地址传到BiosRom芯片。因此,在加电reset后,地址FFFF_FFF0h和F_FFF0h(orF000:FFF0in"real-modelingo")没有什么困难。它是那么简单。这个是BootBlock区域。它总是有一个farjump跳入bootblock区域,主要的在F000:E05Bh。从这点看,我们能够继续主要的纯二进制部分的反汇编。实际上,很多纯二进制部分代码没有执行,因为你的系统bios很少错误,并且BootblockPOST进程发生了,除非你把它搞糟了。

7.1.Bootblock
从这点看,我们可以返汇编bootblock例程了。现在,我要给你一些不明显的和重要的在已经反汇编了的bios代码区域。这个是关于我的bios,你的可能不同,但是恕我直言很相近。
7.1.1."VirtualShutdown"routine
AddressHexMnemonic
F000:E07FBC0BF8movsp,0F80Bh;retfromthisjmpredirectedto0E103h(F000:E103h)
F000:E082E97B15jmpChipset_Reg_Early_Init
7.1.2.Chipset_Reg_Early_Initroutine
AddressHexMnemonic
F000:F600Chipset_Reg_Early_Initprocnear;CODEXREF:F000:E082j
F000:F60066C1E410shlesp,10h
F000:F604BEC4F6movsi,0F6C4h;addrofchipsetregmask
F000:F607next_PCI_reg:;CODEXREF:Chipset_Reg_Early_Init+29j
F000:F6072E8B0Cmovcx,cs:[si]
F000:F60ABC10F6movsp,0F610h
F000:F60DE9F800jmpRead_PCI_Byte
F000:F60D;---------------------------------------------------------------------------
F000:F61012F6dw0F612h
F000:F612;---------------------------------------------------------------------------
F000:F6122E224402andal,cs:[si+2]
F000:F6162E0A4403oral,cs:[si+3]
F000:F61ABC20F6movsp,0F620h
F000:F61DE90201jmpWrite_PCI_Byte
F000:F61D;---------------------------------------------------------------------------
F000:F62022F6dw0F622h
F000:F622;---------------------------------------------------------------------------
F000:F62283C604addsi,4
F000:F62581FE04F7cmpsi,0F704h;arewedoneyet?
F000:F62975DCjnznext_PCI_reg
F000:F62BBAD004movdx,4D0h;MasterPICEdge/LevelTriggered
F000:F62E32C0xoral,al
F000:F630EEoutdx,al
F000:F631FEC2incdl;SlavePICEdge/LevelTriggered
F000:F633EEoutdx,al
F000:F634B90838movcx,3808h;Bus#0Dev#7Func#0(PCI2ISABridge)reg8h(revisionid)
F000:F637BC3DF6movsp,0F63Dh
F000:F63AE9CB00jmpRead_PCI_Byte
F000:F63A;---------------------------------------------------------------------------
F000:F63D3FF6dw0F63Fh
F000:F63F;---------------------------------------------------------------------------
F000:F63F3C10cmpal,10h;issiliconrevision>10h
F000:F6417253jbsilicon_rev_lt_10h;incurrentmobothisjmpNOTtaken(revid=12h)
F000:F643B9903Bmovcx,3B90h;B#0D#7F#3:PwrMngmt&SMBus-SMBusIOBaseAddrlo_byte
F000:F646B000moval,0;setSMBusIOBaselo_byteto00h
F000:F648BC4EF6movsp,0F64Eh
F000:F64BE9D400jmpWrite_PCI_Byte
F000:F64B;---------------------------------------------------------------------------
F000:F64E50F6dw0F650h
F000:F650;---------------------------------------------------------------------------
F000:F650B9913Bmovcx,3B91h;B#0D#7F#3:PwrMngmt&SMBus-SMBusIOBaseAddrhi_byte
F000:F653B050moval,50h;'P';setSMBusIOBasehi_byteto50h,
F000:F653;so,nowSMBusIOBaseisatport5000h!!!
F000:F655BC5BF6movsp,0F65Bh
F000:F658E9C700jmpWrite_PCI_Byte
F000:F658;---------------------------------------------------------------------------
F000:F65B5DF6dw0F65Dh
F000:F65D;---------------------------------------------------------------------------
F000:F65DB9D23Bmovcx,3BD2h;B#0D#7F#3:PwrMngmt&SMBus-SMBusCtrl
F000:F660B001moval,1;SMBusControllerEnable
F000:F662BC68F6movsp,0F668h
F000:F665E9BA00jmpWrite_PCI_Byte
F000:F665;---------------------------------------------------------------------------
F000:F6686AF6dw0F66Ah
F000:F66A;---------------------------------------------------------------------------
F000:F66ABA0540movdx,4005h;accessACPIReg05h
F000:F66A;(seechipsetinitaboveforinitofport4000hasACPIIO)
F000:F66DB080moval,80h;'?;settingreservedbit?
F000:F66FEEoutdx,al
F000:F670B9413Bmovcx,3B41h;generalconfig
F000:F673BC79F6movsp,0F679h
F000:F676E98F00jmpRead_PCI_Byte
F000:F676;---------------------------------------------------------------------------
F000:F6797BF6dw0F67Bh
F000:F67B;---------------------------------------------------------------------------
F000:F67B0C04oral,4;RTCEnableSignalGatedwithPSON(SUSC#)in
F000:F67B;Soft-OffMode
F000:F67DBC83F6movsp,0F683h
F000:F680E99F00jmpWrite_PCI_Byte
F000:F680;---------------------------------------------------------------------------
F000:F68385F6dw0F685h
F000:F685;---------------------------------------------------------------------------
F000:F685reinit_SCI_interrupt:;CODEXREF:Chipset_Reg_Early_Init+92j
F000:F685B9423Bmovcx,3B42h;B#0D#7F#3:SCIInterruptConfiguration
F000:F688BC8EF6movsp,0F68Eh
F000:F68BEB7BjmpshortRead_PCI_Byte
F000:F68B;---------------------------------------------------------------------------
F000:F68D90db90h;?
F000:F68E90F6dw0F690h
F000:F690;---------------------------------------------------------------------------
F000:F690A840testal,40h;checkSUSCState
F000:F69274F1jzreinit_SCI_interrupt
F000:F694EB27jmpshortexit
F000:F696;---------------------------------------------------------------------------
F000:F696silicon_rev_lt_10h:;CODEXREF:Chipset_Reg_Early_Init+41j
F000:F696B9803Bmovcx,3B80h
F000:F699B000moval,0
F000:F69BBCA1F6movsp,0F6A1h
F000:F69EE98100jmpWrite_PCI_Byte
F000:F69E;---------------------------------------------------------------------------
F000:F6A1A3F6dw0F6A3h
F000:F6A3;---------------------------------------------------------------------------
F000:F6A3B9813Bmovcx,3B81h
F000:F6A6B050moval,50h;'P'
F000:F6A8BCAEF6movsp,0F6AEh
F000:F6ABEB75jmpshortWrite_PCI_Byte
F000:F6AB;---------------------------------------------------------------------------
F000:F6AD90db90h;?
F000:F6AEB0F6dw0F6B0h
F000:F6B0;---------------------------------------------------------------------------
F000:F6B0B9843Bmovcx,3B84h
F000:F6B3B007moval,7
F000:F6B5BCBBF6movsp,0F6BBh
F000:F6B8EB68jmpshortWrite_PCI_Byte
F000:F6B8;---------------------------------------------------------------------------
F000:F6BA90db90h;?
F000:F6BBBDF6dw0F6BDh
F000:F6BD;---------------------------------------------------------------------------
F000:F6BDexit:;CODEXREF:Chipset_Reg_Early_Init+94j
F000:F6BD66C1EC10shresp,10h
F000:F6C1C3retn
F000:F6C1Chipset_Reg_Early_Initendp
.........
F000:F6C4Begin_Chipset_Reg_Val
F000:F6C44738dw3847h;bus#0dev#7func#0:PCI2ISABridgereg47h
F000:F6C6BFdb0BFh;disablePCIdelaytransaction
F000:F6C7A0db0A0h;-UseINITasCPUReset
F000:F6C7;-Enable(ports4D0-1perEISAspecification)
F000:F6C7;
F000:F6C85000dw50h;HostBridgereg50hRequestPhaseControl
F000:F6CAFFdb0FFh;andmask
F000:F6CB10db10h;enableDeferRetryWhenHLOCKActive
F000:F6CB;
F000:F6CC5100dw51h;HostBridgereg51hResponsePhaseControl
F000:F6CEDDdb0DDh;resetreservedbits
F000:F6CF0Ddb0Dh;enable:
F000:F6CF;-Non-PostedIOW
F000:F6CF;-ConcurrentPCIMaster/HostOperation
F000:F6CF;
F000:F6D05200dw52h;HostBridgereg52hDynamicDeferTimer
F000:F6D2E0db0E0h;disabledynamicdefer
F000:F6D308db8;snoopstallcount=8
F000:F6D3;
F000:F6D46B00dw6Bh;HostBridgereg6BhDRAMArbitrationControl
F000:F6D600db0;-Parkatlastbusowner
F000:F6D6;-DisableFastReadtoWriteturn-around
F000:F6D6;-MemoryModuleConfiguration-NormalOperation
F000:F6D6;-MDBus2ndLevelStrengthControl=NormalSlewrate
F000:F6D6;-CASBus2ndLevelStrengthControl=NormalSlewrate
F000:F6D6;-VC-DRAMdisable
F000:F6D6;-Multi-PageOpendisable
F000:F6D701db1;EnableMulti-PageOpen
F000:F6D7;
F000:F6D87100dw71h;HostBridgereg71hCPUtoPCIFlowControl1
F000:F6DA00db0;Disable:
F000:F6DA;-DynamicBurst
F000:F6DA;-ByteMerge
F000:F6DA;-PCII/OCyclePostWrite
F000:F6DA;-PCIBurst
F000:F6DA;-PCIFastBack-to-BackWrite
F000:F6DA;-QuickFrameGeneration
F000:F6DA;-1WaitStatePCICycles
F000:F6DB08db8;EnablePCIBurst
F000:F6DB;
F000:F6DC7500dw75h;HostBridgereg75hPCIArbitration1
F000:F6DE00db0;-PCIhaspriority
F000:F6DE;-REQ-based(arbitrateatendofREQ#)
F000:F6DE;-DisablePCIMasterBusTime-Out
F000:F6DF80db80h;FairarbitrationbetweenPCIandCPU
F000:F6DF;
F000:F6E07600dw76h;HostBridgereg76hPCIArbitration2
F000:F6E2CFdb0CFh;andmask
F000:F6E380db80h;ormask
F000:F6E3;
F000:F6E44138dw3841h;bus#0dev#7func#0:PCI2ISABridgereg41h-ISABuscontrol
F000:F6E6FFdb0FFh;andmask
F000:F6E701db1;ROMWriteEnable
F000:F6E7;
F000:F6E84338dw3843h;bus#0dev#7func#0:PCI2ISABridgereg43h-ROMDecodeControl
F000:F6EA00db0;DisableROMCS#decodeforallranges
F000:F6EB30db30h;EnableROMCS#decodeforthefollowingranges:
F000:F6EB;1.FFF00000h-FFF7FFFFh
F000:F6EB;2.000E0000h-000EFFFFh
F000:F6EB;
F000:F6EC4A38dw384Ah;bus#0dev#7func#0:PCI2ISABridgereg4Ah-IDEInterruptRouting
F000:F6EEFFdb0FFh;andmask
F000:F6EF40db40h;Accessports00-FFhviaSDbus(appliesto
F000:F6EF;externaldevicesonly;internaldevicessuchas
F000:F6EF;themousecontrollerarenoteffected)
F000:F6EF;
F000:F6F05A38dw385Ah;bus#0dev#7func#0:PCI2ISABridgereg5Ah-KBC/RTCControl
F000:F6F2F8db0F8h;Disable:
F000:F6F2;-InternalRTC
F000:F6F2;-InternalPS2Mouse
F000:F6F2;-InternalKBC
F000:F6F304db4;InternalRTCEnable
F000:F6F3;
F000:F6F4483Bdw3B48h;B#0D#7F#3:PwrMngmt&SMBus-PwrMngmtIOBaseAddrlo_byte
F000:F6F600db0;andmask
F000:F6F700db0;ormask
F000:F6F7;
F000:F6F8493Bdw3B49h;B#0D#7F#3:PwrMngmt&SMBus-PwrMngmtIOBaseAddrhi_byte
F000:F6FA40db40h;andmask
F000:F6FB40db40h;PwrMngmtIOBaseAddr=IOPort4000h
F000:F6FB;
F000:F6FC413Bdw3B41h;bus#0dev#7func#3:PwrMngmt&SMBus-GeneralConfig
F000:F6FEFFdb0FFh;andmask
F000:F6FF80db80h;enable:I/OforACPII/OBase
F000:F6FF;
F000:F7007638dw3876h;bus#0dev#7func#0:PCI2ISABridgereg76h-GPIO/ChipSelectControl
F000:F70200db0;DisableGPO24-26
F000:F70302db2;EnableGPO25
F000:F703End_Chipset_Reg_Val

7.1.3.Init_Interrupt_n_PwrMgmtroutine
AddressHexMnemonic
F000:E1A0BFA6E1movdi,0E1A6h;retaddrbelow
F000:E1A3E94299jmpInit_Interrupt_n_PwrMgmt
F000:E1A6;---------------------------------------------------------------------------
F000:E1A6B0C1moval,0C1h;'+'
....
F000:7CDDdelay:;CODEXREF:Init_Interrupt_n_PwrMgmt:delay
F000:7CDDE2FEloopdelay
F000:7CDFFFE7jmpdi;jmptoF000:E1A6h
F000:7CDFInit_Interrupt_n_PwrMgmtendp

7.1.4.CallTo"EarlySiliconSupport"Routine
AddressHexMnemonic
F000:E1ADE94702jmpSearch_BBSS_Signature
F000:E1AD;---------------------------------------------------------------------------
F000:E1B0B2E1dw0E1B2h
F000:E1B2;---------------------------------------------------------------------------
F000:E1B20BF6orsi,si
F000:E1B47438jzshort_BBSS_not_found
F000:E1B68BDEmovbx,si;checksumstarthere
F000:E1B82E8B04movax,cs:[si]
F000:E1BB2500F0andax,0F000h
F000:E1BEC1E804shrax,4
F000:E1C10500F0addax,0F000h
F000:E1C48ED8movds,ax;ds=baseaddrforcalculationofBBSSchecksum
F000:E1C6assumeds:nothing
F000:E1C632E4xorah,ah
F000:E1C833F6xorsi,si
F000:E1CAB9FF0Fmovcx,0FFFh;lengthofBBSS
F000:E1CDnext_byte:;CODEXREF:000FE1D0j
F000:E1CDAClodsb
F000:E1CE02E0addah,al;calc8-bitchksumforBBSS
F000:E1D0E2FBloopnext_byte
F000:E1D23A24cmpah,[si]
F000:E1D47518jnzshort_BBSS_not_found
F000:E1D62E8B07movax,cs:[bx];chsumok,jumpto(exec)theBBSSengine
F000:E1D92500F0andax,0F000h
F000:E1DC8BF0movsi,ax
F000:E1DE81C6FC0Faddsi,0FFCh
F000:E1E22E8B34movsi,cs:[si]
F000:E1E5BCECE1movsp,0E1ECh
F000:E1E8FFE6jmpsi;jmptoF000:60B4h(BBSSEngine),returnsatF000:E1F8h
F000:E1E8;theBBSSengineissiliconsupportroutine,usedto
F000:E1E8;initializePwrMgmtGPIOCtlr,HostCtlrandDRAMCtlr
F000:E1E8;---------------------------------------------------------------------------
F000:E1EA87db87h;?
F000:E1EBDBdb0DBh;-
F000:E1ECF8E1dw0E1F8h
.........
F000:E1F8BBSS_exec_done:
F000:E1F8B80000movax,0
.........
这段代码在bootblock拷贝到RAM之前执行。万一RAM有错误,系统就要halt并且从扬声器输出错误代码。
7.1.5.BootblockIsCopiedAndExecutedInRAM
AddressHexMnemonic
F000:E2AA;-----------Enter16-bitProtectedMode(Flat)------------
F000:E2AAassumeds:_F000h
F000:E2AA0F0116F6E4lgdtqwordptrword_F000_E4F6
F000:E2AF0F20C0moveax,cr0
F000:E2B20C01oral,1
F000:E2B40F22C0movcr0,eax
F000:E2B7EB00jmpshort$+2;clearprefetch,enter16-bitPMode.We're
F000:E2B7;usingthe"unchanged"hiddenvalueofCS
F000:E2B7;register(descriptorcache)fromprevious
F000:E2B7;"PModesession"inmemory_check_routine
F000:E2B7;forcodesegmentdesc
F000:E2B9B80800movax,8
F000:E2BC8ED8movds,ax;initdsto4GB-widesegment
F000:E2BEassumeds:nothing
F000:E2BE8EC0moves,ax;initesto4GB-widesegment
F000:E2C0
F000:E2C0TherearetwolocationstoaccessE0000HROMspace,oneis0E0000H
F000:E2C0andanotheris0FFFE0000H.SomechipsetscannotaccessonboardROM
F000:E2C0spaceat0E0000HifanydevicealsousethespaceonISAbus.
F000:E2C0Tosolvethisproblem,weneedtochangeaddressto0FFFE0000H
F000:E2C0toreadBIOScontentsat0E0000Hspace.
F000:E2C0assumees:nothing
F000:E2C066BE00000E00movesi,0E0000h
F000:E2C66766817E022D6C68+cmpdwordptr[esi+2],'5hl-'
F000:E2CF7407jzshortLHA_sign_OK
F000:E2D16681CE0000F0FForesi,0FFF00000h
F000:E2D8
F000:E2D8moveentireBIOS(i.e.original.tmpandbootblock)
F000:E2D8fromROMatE0000h-FFFFFhtoRAMat10000h-2FFFFh
F000:E2D8LHA_sign_OK:;CODEXREF:000FE2CF
F000:E2D866BF00000100movedi,10000h;destinationaddr=1000:0
F000:E2DE66B900800000movecx,8000h;copy128KBytetobuffer(original.tmpnBootblock)
F000:E2E467F366A5repmovsdwordptres:[edi],dwordptr[esi]
F000:E2E80F20C0moveax,cr0
F000:E2EB24FEandal,0FEh
F000:E2ED0F22C0movcr0,eax
F000:E2F0EB00jmpshort$+2;leave16-bitprotectedmode(voodoomode)
F000:E2F2EAF7E20020jmpfarptr_bootblock_in_RAM
.........
2000:E2F7;---------------------------------------------------------------------------
2000:E2F7Setuptemporarystackat0:1000H,atthispoint
2000:E2F7Bioscode(last128Kbyte)isstillcompressed
2000:E2F7exceptthebootblockanddecompressioncode
2000:E2F7
2000:E2F7_bootblock_in_RAM:
2000:E2F733C0xorax,ax
2000:E2F98ED0movss,ax
2000:E2FBassumess:nothing
2000:E2FBBC0010movsp,1000h
最后128KB的bios代码(E000:0000h-F000:FFFFh)拷贝到RAM如下:
1.北桥加电的时候默认把F_0000h-F_FFFFh放入空间FFFE_FFFFh-FFFF_FFFFh这里也是biosrom芯片的地址空间映射。那也是下马面的代码能够安全运行的原因:
AddressHexMnemonic
F000:FFF0EA5BE000F0jmpfarptrentry_point;Northbridgeisresponsiblefordecoding
F000:FFF0;thetargetaddressofthisjumpintoBIOS
F000:FFF0;chipthroughaddressaliasing.So,evenif
F000:FFF0;thisisafarjump(readIntelSoftware
F000:FFF0;DeveloperGuideVol.3forinfo)
F000:FFF0;wearestillinBIOSchipd00d;)
F000:FFF0;vi693A:FFFE_FFFF-FFFF_FFFFis000F_xxxxalias.
并且,北桥加电默认禁止这段空间的DRAMshadowing。所以读写这段区域空间就不会送到DRAM。同时,在南桥没有控制寄存器控制这个地址空间的映射。所以,对这个地址空间的读操作就会直接指向了biosrom芯片,而没有被南桥转换地址。当然,这个读操作首先通过北桥,那样应用地址重名配置。
2.非常靠近bootblock执行的开始,例程Chipset_Reg_Early_Init开始执行。这个例程重新编程PCI-to-ISA桥(在南桥中),能够编码E_0000h-E_FFFFh地址,比如促进这个地址的读操作到biosrom芯片。北桥加电默认禁止对这个地址空间的DRAMshadowing。所以,读写这个空间就不会写入DRAM。
3.然后上面的例程,拷贝biosrom芯片最后128KB(E_0000h-F_FFFFh)内容到DRAM(1000:0000h-2000:FFFFh)中去。这个可以实现,因为这个地址空间已经用芯片映射到了DRAM中,没有特别的地址翻译。
7.1.6.Calltobiosdecompressionroutineandthejumpintodecompressedsystembios
AddressHexMnemonic
2000:E3DCE83301callDecompress_System_BIOS
2000:E3DFEB03jmpshort_sysbios_chksum_ok
2000:E3E1;---------------------------------------------------------------------------
2000:E3E1_sysbios_chksum_error:;CODEXREF:0002E347
2000:E3E1;0002E350...
2000:E3E1B80010movax,1000h
2000:E3E4
2000:E3E4_sysbios_chksum_ok:;CODEXREF:0002E3DF
2000:E3E48ED8movds,ax;ax=5000hifdecompressionsuccessful,otherwiseax=1000h
2000:E3E6assumeds:_1000h
2000:E3E6B0C5moval,0C5h;'+'
2000:E3E8E680out80h,al;manufacture'sdiagnosticcheckpoint
2000:E3EA
2000:E3EAThesourcedatasegmentis5000Hifchecksumisgood.
2000:E3EAthecontentsinthisareaisdecompressedbyroutine"Decompress_System_BIOS".
2000:E3EAAndsegment1000HisforshadowingoriginalBIOSimageifchecksum
2000:E3EAisbad.BIOSwillshadowbootblockandbootfromit.
2000:E3EAE887EBcallCopy_Decomprssd_E_n_F_Seg;relocatedcomprssedfromdecompressionsegto
2000:E3EA;E_n_F_seginRAM(ShadowthesystemBIOS)
2000:E3EDB000moval,0
2000:E3EFE8C710callSetup_Cpu_Cache
2000:E3F2
2000:E3F2BIOSdecidewheretogofromhere.
2000:E3F2IfBIOSchecksumisgood,thisaddressF80DHisshadowedby
2000:E3F2decompressedcode(i.e.original.binandothers),
2000:E3F2And"BootBlock_POST"willbeexecutedifchecksumisbad.
2000:E3F2EA0DF800F0jmpfarptrloc_F000_F80D;jumptodecompressedsystemBIOS(F_seg)inRAMifdecompression
2000:E3F2;successful,otherwisejumptobootblockatthesameaddressif
2000:E3F2;decompressionfailed.

在执行例程Decompress_System_BIOS时,在RAM地址1000:0000h-2000:FFFFh中的bioscode(original.tmp)解压到了RAM中的5000:0000h-6000:FFFFh。这个解压了的systembios然后重新定位到了RAM中的E000:0000h-F000:FFFFh。尽管如此,如果这个解压进程失败了,当前压缩的E_seg和F_seg定位到了RAM中的1000:0000h-2000:FFFFh(包括在RAM中的bootblock)将要重新定位到RAM中的E000:0000h-F000:0000h,然后bootblock错误处理代码就要运行了。注意那个问题是由于地址混淆,并且在重新定位时DRAMshadowing被通过设置一个适当的芯片寄存器而处理。下面是这个例程基本run-down:
7.1.6.1.EnableFFF80000h-FFFDFFFFhdecoding
1.使能FFF80000h-FFFDFFFFh解码。对这个地址的访问就会通过PCI-to-ISA桥直接到biosrom芯片。PCI-to-ISA桥rom解码控制寄存器在这里管理。这是必要的,所以我的256KB的bios芯片只有128KB是拷贝到RAM中的,比如original.tmp和bootblock目前正在地址1000:0000h-2000:FFFFh上。
7.1.6.2.Copylower128KBofBIOScodefromROMchipintoRAM
2.拷贝低128KB的bios代码,从ROM芯片中的FFFC_0000h-FFFD_FFFFh到RAM中8000:0000h-9000:FFFFh。
7.1.6.3.DisableFFF8_0000h-FFFD_FFFFhdecoding
3.禁止FFF8_0000h-FFFD_FFFFh解码。这个地址的访问将不会通过PCI-to-ISA桥到biosrom芯片中去。
7.1.6.4.VerifychecksumofthewholecompressedBIOSimage
4.改变整个bios映像的checksum。计算在内存RAM中的压缩的8bit的checksum(比如8000:0000h-9000:FFFFh+1000:0000h-2000:7FFDh),并且和储存在2000:7FFEh的值比较结果。如果8bit不匹配,那么goto_sysbios_chksum_err,否则继续解压缩例程。
7.1.6.5.Lookforthedecompressionengine
5.在段2000h通过搜索*BBSS*来查找解压引擎。
7.1.6.6.DecompressthecompressedBIOScomponents
6.通过调用上面的解压引擎,解压缩压缩了的bios部分。注意这一步中,只有original.tmp和它的扩展(awardext.rom)被解压(其他的版本的awardext.rom也可能适用,我没有验证)。另外的部分通过其他方式处理。这个解压例程至处理他们自己的解压和压缩区域,并把他们放入RAM中的某些地方。我们需要一些预备信息,在深入研究这一步之前:
7.1.6.6.a.TheformatoftheLZHlevel-1compressedbioscomponents
A.LAHlevel-1压缩bios部分格式。这些bios部分在解压缩之后的地址范围也是这样的结构。结构如下(适用于所有的压缩部分):
Offsetfrom1stbyteOffsetinRealHeaderContents
00hN/ATheheaderlengthofthecomponent.Itdependsonthefile/componentname.
01hN/ATheheader8-bitchecksum,notincludingthefirst2bytes(headerlengthandheaderchecksumbyte).
02h-06h00h-04hLZHMethodID(ASCIIstringsignature).InmyBIOSit's"-lh5-"whichmeans:8kslidingdictionary(max256bytes)+staticHuffman+improvedencodingofpositionandtrees.
07h-0Ah05h-08hcompressedfile/componentsizeinlittleendiandwordvalue,i.e.MSBat0Ahandsoforth
0Bh-0Eh09h-0ChUncompressedfile/componentsizeinlittleendiandwordvalue,i.e.MSBat0Ehandsoforth
0Fh-10h0Dh-0EhDecompressionoffsetaddressinlittleendianwordvalue,i.e.MSBat10handsoforth.Thecomponentwillbedecompressedintothisoffsetaddress(realmodeaddressingisineffecthere).
11h-12h0Fh-10hDecompressionsegmentaddressinlittleendianwordvalue,i.e.MSBat12handsoforth.Thecomponentwillbedecompressedintothissegmentaddress(realmodeaddressingisineffecthere).
13h11hFileattribute.MyBIOScomponentscontain20hhere,whichisnormallyfoundinLZHlevel-1compressedfile.
14h12hLevel.MyBIOScomponentscontain01hhere,whichmeansit'saLZHlevel-1compressedfile.
15h13hcomponentfilenamenamelengthinbyte.
16h-[15h+filename_len]14h-[13h+filename_len]componentfilename(ASCIIstring)
[16h+filename_len]-[17h+filename_len][14h+filename_len]-[15h+filename_len]file/componentCRC-16inlittleendianwordvalue,i.e.MSBat[HeaderSize-2h]andsoforth.
[18h+filename_len][16h+filename_len]OperatingSystemID.InmyBIOSit'salways20h(ASCIIspacecharacter)whichdon'tresembleanyLZHOSIDknowntome.
[19h+filename_len]-[1Ah+filename_len][17h+filename_len]-[18h+filename_len]Nextheadersize.InmyBIOSit'salways0000hwhichmeansnoextensionheader.
注意:
1.上面最左边的和在列中用到的地址是从部分的第一个字节计算的。这个“真正头部偏移”就像上面解释得的“便签RAM”使用。
2.每一个部分结束是EOFbyte,比如00hbyte。
3.在我的bios中,有read_header例程,包含读写这个头部内容的例程。访问Calc_LZH_hdr_CRC16有一个关键“procedurecall”,它读出这个bios部分头部到“便签本”RAM中,从3000:0000h(ds:0000h)开始。这个便签本区域由"real-LZH-headervalue"填充,没有包含最前面的2bytes(头大小,头8bit校验和),但是包含了第三byte(offset02h)直到HeaderSize+02h。
7.1.6.6.b.Thelocationofvariouschecksums
B.解压前和解压时的不同的checksum位置:
LocationCalculationMethod
Rightaftercompressedoriginal.tmporiginal.tmp8-bitchecksum.Thisvalueiscalculatedafterit'scopiedtoRAMatsegment1000hand2000h.Thecodeasfollows:
AddressAssemblyCode
2000:E307;verifySystem_BIOSchecksum
2000:E307movax,1000h
2000:E30Amovds,ax;ds=E_seg_in_RAM
2000:E30Cassumeds:_1000h
2000:E30Cmovbx,cmprssd_size_hi_word
2000:E310movcx,cmprssd_size_lo_word
2000:E314addcl,hdr_len;cl=LZHhdrlen
2000:E318adcch,0
2000:E31Badcbx,0
2000:E31Eaddcx,3
2000:E321adcbx,0
2000:E324jzshorthi_word_zero
2000:E326movbx,cx
2000:E328xorcx,cx
2000:E32Ahi_word_zero:;CODEXREF:0002E324
2000:E32Axorsi,si
2000:E32Cxorah,ah
2000:E32E_next_byte:;CODEXREF:0002E3310002E343
2000:E32Elodsb
2000:E32Faddah,al
2000:E331loop_next_byte
2000:E333orbx,bx;compressedBIOSbiggerthan64kb?
2000:E335jzshortcmp_chksum
2000:E337movcx,bx
2000:E339movbx,ds
2000:E33Baddbx,1000h;proceedtoF_seginRAM
2000:E33Fmovds,bx
2000:E341assumeds:_2000h
2000:E341xorbx,bx
2000:E343jmpshort_next_byte
2000:E345;---------------------------------------------------------------------------
2000:E345cmp_chksum:;CODEXREF:0002E335
2000:E345cmpah,[si];cmpcalc-edoriginal.tmpchksumwith
2000:E345;chksuminBIOSimage
2000:E347jnz_sysbios_chksum_error
RightafterthedecompressionengineThisisthe8-bitchecksumofthedecompressionenginewhichstartsatF000:7000h(2000:7000haftercopiedtoRAM)inmyBIOS.IguessthisisthethingthatsomepeoplecallDecompressionBlock.Thecodeasfollows:
AddressAssemblyCode
2000:E35E;Verifychecksumofdecompressengine
2000:E35Emovds,ax;ds=2700h(2000:7000h)
2000:E360assumeds:nothing
2000:E360xorah,ah
2000:E362xorsi,si
2000:E364movcx,0FFFh;cx=sizeofBBSS_engine(4KB-1)
2000:E367__next_byte:;CODEXREF:0002E36A
2000:E367lodsb
2000:E368addah,al
2000:E36Aloop__next_byte
2000:E36Ccmpah,[si];decompressionenginechksumOK?
2000:E36Ejnzshort_sysbios_chksum_error
1bytebeforedecompressionenginechecksum(that'sexplainedabove)Thisisthe8-bitchecksumofallcompressedBIOSplusthe8-bitchecksumofthedecompressionengine(notincludingitspreviouslycalculatedchecksumabove).Thecode:
AddressAssemblyCode
2000:E512callCopy_C_seg_n_D_seg;copylower128KBytebioscodefromROM(atFFFC_0000h-
2000:E512;FFFD_0000h)toRAM(at8000:0000h-9000:FFFFh)
2000:E515xorah,ah
2000:E517xorcx,cx
2000:E519movbx,8000h
2000:E51Cmovds,bx;ds=8000h,containscompressed
2000:E51C;lower128KBbioscomponents(awdext,etc.)
2000:E51Eassumeds:nothing
2000:E51Exorsi,si
2000:E520next_Cseg_Dseg_byte:;CODEXREF:Decompress_System_BIOS+11
2000:E520;Decompress_System_BIOS+1F
2000:E520lodsb
2000:E521addah,al;calc8-bitchksumofC_segnD_seg
2000:E523loopnext_Cseg_Dseg_byte
2000:E525movbx,ds
2000:E527cmpbh,90h;'?;areweinseg9000h?
2000:E52Ajnbshortdone
2000:E52Caddbh,10h;movetonexthighersegment
2000:E52Fmovds,bx
2000:E531assumeds:nothing
2000:E531jmpshortnext_Cseg_Dseg_byte
2000:E533;---------------------------------------------------------------------------
2000:E533done:;CODEXREF:Decompress_System_BIOS+18
2000:E533movbx,1000h
2000:E536movds,bx;ds=start_addr_ofE_segnF_seginRAM
2000:E536;(compressedoriginal.tmp+bootblock)
2000:E538assumeds:_1000h
2000:E538xorsi,si
2000:E53Acld
2000:E53Bnext_Eseg_Fseg_byte:;CODEXREF:Decompress_System_BIOS+2C
2000:E53B;Decompress_System_BIOS+3B
2000:E53Blodsb
2000:E53Caddah,al;calc8bitchksum,contdfromchksumabove
2000:E53Eloopnext_Eseg_Fseg_byte
2000:E540cmpbh,20h;'';areweinseg2000h?
2000:E543jnbshortchksum_done
2000:E545addbh,10h;movetonexthighersegment
2000:E548movds,bx
2000:E54Aassumeds:_2000h
2000:E54Amovcx,7FFEh;amountofbyteinlastseg(F_seginRAM)tocalc
2000:E54Djmpshortnext_Eseg_Fseg_byte
2000:E54F;---------------------------------------------------------------------------
2000:E54Fchksum_done:;CODEXREF:Decompress_System_BIOS+31
2000:E54Fcmpah,[si];cmpcalc-edchksumandchksumpointedtoby[si].
2000:E54F;thisisthechksumforthebiosbinary
2000:E54F;from00000hto37FFDh(C000:0h-F000:7FFDh)
2000:E551jnz_sysbios_chksum_error;jmpbackandcontinuetobootblockerrorhandlingroutine

7.1.6.6.c.Thekeypartsofthedecompressionroutine
C.解压例程的关键部分
AddressAssemblyCode
2000:E512Decompress_System_BIOSprocnear;CODEXREF:0002E3DC
.........
2000:E555movbx,0
2000:E558moves,bx
2000:E55Aassumees:nothing
2000:E55Amovwordptres:7004h,0FFFFh
2000:E561xoral,al
2000:E563
2000:E563;System_BIOSDecompressionstartedhere
2000:E563movbx,1000h
2000:E566moves,bx;es=src_seg
2000:E568assumees:_1000h
2000:E568xorbx,bx;bx=src_offset
2000:E56AcallDecompress;onret,CF=1iferroroccured
2000:E56Djbshortsysbios_decomp_error
2000:E56Ftestecx,0FFFF0000h;compressedcomponentsizemorethan64KB?
2000:E576jzshortsysbios_decomp_error;jmpifcompressedcomponentsize<=64KB
2000:E578movbx,2000h
2000:E57Bmoves,bx;proceed2nextcmprssdcomponnt(innextsegment)
2000:E57Dassumees:_2000h
2000:E57Dmovbx,1;bx=indextobeaddedtoprevioussrc_offsetincx
2000:E580jmpshortrepeat_decompress;decompressremainingcomponent(1stpassjmptaken)
2000:E582;---------------------------------------------------------------------------
2000:E582sysbios_decomp_error:;CODEXREF:Decompress_System_BIOS+5B
2000:E582;Decompress_System_BIOS+64
2000:E582rclal,1
2000:E584movbx,2000h
2000:E587moves,bx
2000:E589xorbx,bx
2000:E58BcallDecompress
2000:E58Erclal,1
2000:E590cmpal,3
2000:E592jnzshortdecompress_successfull
2000:E594movax,1000h
2000:E597stc
2000:E598retn
2000:E599;---------------------------------------------------------------------------
2000:E599decompress_successfull:;CODEXREF:Decompress_System_BIOS+80
2000:E599oral,al
2000:E59Bjnzshortsys_bios_dcomprss_done
2000:E59Drepeat_decompress:;CODEXREF:Decompress_System_BIOS+6E
2000:E59D;Decompress_System_BIOS+99
2000:E59Daddbx,cx;bx=pointtonextcompressedcomponent
2000:E59FcallDecompress
2000:E5A2jbshortsys_bios_dcomprss_done;1stpassjmptaken(original.tmp)
2000:E5A4testecx,0FFFF0000h
2000:E5ABjzshortrepeat_decompress
2000:E5ADsys_bios_dcomprss_done:;CODEXREF:Decompress_System_BIOS+89
2000:E5AD;Decompress_System_BIOS+90
2000:E5ADcallDecmprss_Sysbios_Extension
2000:E5B0jz_sysbios_chksum_error
2000:E5B4movax,5000h
2000:E5B7clc
2000:E5B8retn
2000:E5B8Decompress_System_BIOSendp
________________________________________
2000:E5B9---Decompress---
2000:E5B9in:es=component_seg
2000:E5B9bx=component_offset
2000:E5B9out:ecx=overall_compressed_component_length
2000:E5B9edx=original_component_size
2000:E5B9CF,setiffailed,clearedifsuccess
2000:E5B9;---------------SUBROUTINE---------------------------------------
2000:E5B9Decompressprocnear;CODEXREF:Decmprss_Sysbios_Extension:not_awdext
2000:E5B9;Decmprss_Sysbios_Extension:not_awdext2...
2000:E5B9cmpdwordptres:[bx+0Fh],40000000h;isextensioncomponent?
2000:E5C2jnzshortnot_xtension_component;1stpassjmptaken
2000:E5C4movsi,0
2000:E5C7movds,si
2000:E5C9assumeds:nothing
2000:E5C9movds:7000h,bx
2000:E5CDmovsi,es
2000:E5CFmovds:7002h,si
2000:E5D3leasi,ds:7789h
2000:E5D7movds:7004h,si
2000:E5DBmovzxecx,byteptres:[bx]
2000:E5E0addecx,es:[bx+7]
2000:E5E5addecx,3
2000:E5E9retn
2000:E5EA;---------------------------------------------------------------------------
2000:E5EAnot_xtension_component:;CODEXREF:Decompress+9
2000:E5EAmovdx,3000h;dx=scratchpad_segfordecompression
2000:E5EDpushax
2000:E5EEpushes
2000:E5EFcallFind_BBSS;onret,sicontainsoffsetrightafterBBSSsign
2000:E5F2popes
2000:E5F3assumees:nothing
2000:E5F3pushes
2000:E5F4movax,es
2000:E5F6shrax,0Ch
2000:E5F9moves,ax
2000:E5FBassumees:nothing
2000:E5FBmovax,cs:[si+0Eh]
2000:E5FFcallax;calldecompressionengineat2000:7789h
2000:E601popes
2000:E602assumees:nothing
2000:E602popax
2000:E603retn
2000:E603Decompressendp
________________________________________
2000:7789---Decomprssion_Ngine---
2000:7789in:dx=scratch-pad_segment_for_decompression
2000:7789es=(compressed_segment_addr>>0xC)[hi_wordofsrcphyaddr]
2000:7789bx=compressed_offset_addr
2000:7789
2000:7789out:ecx=overall_compressed_component_length
2000:7789edx=original_file_size
2000:7789;---------------SUBROUTINE---------------------------------------
2000:7789Decompression_Ngineprocnear
2000:7789pusheax
2000:778Bpushbx
2000:778Cpushes
2000:778Dmovds,dx
2000:778Fpushds
2000:7790popes
2000:7791xordi,di
2000:7793movcx,4000h
2000:7796xorax,ax
2000:7798repstosw;zero-init32KBstartingatScratchpad_Seg:0000h
2000:779Apopes
2000:779Bpushes
2000:779C
2000:779C;SetupGDTtobeusedtogetsrcbytes(Fetch_Byte)later
2000:779Cmovwordptrds:100h,es;ds:100h=compressed_seg_addr>>0xC
2000:779C;1stpassds:100h=1
2000:77A0movds:102h,bx;ds:102h=compressed_offset_addr
2000:77A0;1stpassbx=0
2000:77A4xorecx,ecx
2000:77A7movds:57A8h,ecx
2000:77ACmovds:57ACh,ecx
2000:77B1leacx,ds:57A8h
2000:77B5rorecx,4
2000:77B9movax,ds
2000:77BBaddcx,ax
2000:77BDrolecx,4
2000:77C1movwordptrds:57A2h,18h
2000:77C7movds:57A4h,ecx
2000:77CCmovdwordptrds:57B0h,0FFFFh
2000:77D5movax,es
2000:77D7movzxecx,ah;es=hi_wordaddrofdesc_base
2000:77DBrorecx,8;ecx=base_24_31<<24
2000:77DFmovcl,al
2000:77E1orecx,8F9300h
2000:77E8movds:57B4h,ecx
2000:77EDmovdwordptrds:57B8h,0FFFFh
2000:77F6movdwordptrds:57BCh,8F9300h
2000:77FFpushgs
2000:7801movdi,0
2000:7804movgs,di
2000:7806assumegs:nothing
2000:7806movdi,6000h
2000:7809movwordptrgs:[di],7789h
2000:780E
2000:780E;checkLZHheader
2000:780Eaddbx,12h;LZH-headerdecomp_seg_addr_hi_byteindex
2000:7811callFetch_Byte
2000:7814subbx,12h;restorebxtopointtofirstbyte
2000:7817cmpal,40h;'@';isextensioncomponent?
2000:7817;at1st:alequ50h(original.tmp)
2000:7817;at2nd:alequ41h(awardext.rom)
2000:7819jnzshortnot_extension_component;1st-passjmptaken
2000:781Baddbx,11h
2000:781EcallFetch_Byte;fetch"dest_seg_addr"lo_byte
2000:7821subbx,11h;restorebxtopointtofirstbyte
2000:7824oral,al;ifextensioncomponent,jmptaken
2000:7826jnzshortextension_component
2000:7828cmpdwordptrgs:[di+4],0
2000:782Ejnzshortnot_extension_component
2000:7830extension_component:;CODEXREF:Decompression_Ngine+9D
2000:7830movzxdx,al;dl="dest_seg_addr"lo_byte
2000:7833incbx;bx=LZH_hdr_chksumbyteindex
2000:7834callFetch_Byte
2000:7837subal,dl;LZH_hdr_chksum=LZH_hdr_chksum-"dest_seg_addr"_lo_byte
2000:7839callPatch_Byte;storenewchecksum
2000:783Cdecbx;restorebx
2000:783Dxoral,al;al=00h
2000:783Faddbx,11h;bx="dest_seg_addr"_lo_byteindex
2000:7842callPatch_Byte;patch"dest_seg_addr"_lo_byteto00h
2000:7845subbx,11h
2000:7848incdx;dx="dest_seg_addr"_lo_byte+1
2000:7849shldx,2;dx=4*("dest_seg_addr"_lo_byte+1)
2000:784Cadddi,dx;di=6000h+dx--lookabove!
2000:784Emovgs:[di],bx;0000:[di]=compressed_offset_addr
2000:7851movcx,es
2000:7853movgs:[di+2],cx;0000:[di+2]=compressed_seg_addr>>0xC(hi_wordofsrcphyaddr)
2000:7857callFetch_Byte;al=LZH_hdr_len
2000:785Amovzxecx,al;ecx=LZH_hdr_len
2000:785Eaddbx,7
2000:7861callFetch_Dword;eax=compressed_file_size
2000:7864subbx,7
2000:7867addecx,eax;ecx=LZH_header_len+compressed_file_size
2000:786Aaddecx,3;ecx=total_compressed_component_size
2000:786Epopgs
2000:7870assumegs:nothing
2000:7870jmpexit
2000:7873;---------------------------------------------------------------------------
2000:7873not_extension_component:;CODEXREF:Decompression_Ngine+90
2000:7873;Decompression_Ngine+A5
2000:7873popgs
2000:7875callMake_CRC16_Table
2000:7878callRead_Header;fetchheadercomponenttoscratchpad_seg,onerrorCF=1
2000:787Bjbexit;retwitherrorcodeset
2000:787Fmovax,ds:108h;movax,decomprss_seg_addr
2000:7882movds:104h,ax;movnu_decomprss_seg_addr,ax
2000:7885movax,ds:10Ah;movax,decomprss_offst_addr
2000:7888movds:106h,ax;movnu_decomprss_offst_addr,ax
2000:788Bmovecx,ds:310h;ecx=compressed_component_size
2000:7890xoreax,eax
2000:7893moval,ds:571Ch;al=LZH_hdr_len
2000:7896addecx,eax;ecx=compressed_cmpnnt_size+LZH_hdr_len
2000:7899addecx,3;ecx=compressed_cmpnnt_size+LZH_hdr_len+
2000:7899;sizeof(EOF_byte)+sizeof(LZH_hdr_len_byte)+
2000:7899;sizeof(LZH_hdr_8bit_chk_sum)
2000:7899;i.e.ecx=overall_component_len
2000:789Dmovedx,ds:314h;movedx,original_file_size
2000:78A2pushedx
2000:78A4pushecx
2000:78A6pushbx
2000:78A7addbx,5;pointtoLZHIDbyte
2000:78AAcallFetch_Byte
2000:78ADpopbx
2000:78AEcmpal,'0';is'-lh0-'?
2000:78B0jnzshortdecompress_part
2000:78B2pushds
2000:78B3pushsi
2000:78B4pushbx
2000:78B5movdi,ds:10Ah
2000:78B9movzxax,byteptrds:571Ch
2000:78BEaddax,2
2000:78C1addbx,ax
2000:78C3movcx,ds:310h
2000:78C7movax,ds:108h
2000:78CAmoves,ax
2000:78CCaddcx,3
2000:78CFshrcx,2
2000:78D2next_dword:;CODEXREF:Decompression_Ngine+151
2000:78D2callFetch_Dword
2000:78D5addbx,4
2000:78D8stosd
2000:78DAloopnext_dword
2000:78DCpopbx
2000:78DDpopsi
2000:78DEpopds
2000:78DFjmpshortLZH_hdr_OK
2000:78E1;---------------------------------------------------------------------------
2000:78E1decompress_part:;CODEXREF:Decompression_Ngine+127
2000:78E1pushwordptrds:104h;savedestinationsegaddr
2000:78E5pushwordptrds:106h;savedestinationoffsetaddr
2000:78E9pushlarge[dwordptrds:314h]
2000:78EEcallLzh_Expand;Lzh_Expandcapableofhandlingcompressed
2000:78EE;componentbiggerthan64KB(1segment)
2000:78F1popdwordptrds:314h
2000:78F6popwordptrds:106h
2000:78FApopwordptrds:104h
2000:78FELZH_hdr_OK:;CODEXREF:Decompression_Ngine+156
2000:78FEcallZero_Init;zeroinit32KBofscratchpad_seg
2000:7901popecx
2000:7903popedx
2000:7905clc
2000:7906exit:;CODEXREF:Decompression_Ngine+E7
2000:7906;Decompression_Ngine+F2
2000:7906popes
2000:7907popbx
2000:7908popeax
2000:790Aretn
2000:790ADecompression_Ngineendp
________________________________________

2000:790B---Make_CRC16_Table---
2000:790B1stpass,thebaseaddressforDSis3_0000h
2000:790Bin:ds=scratch_pad_segmentforCRCtable
2000:790Bout:ds:10Ch-ds:11Bh=CRC-16table
2000:790B;---------------SUBROUTINE---------------------------------------
2000:790BMake_CRC16_Tableprocnear;CODEXREF:Decompression_Ngine+EC
2000:790B51pushcx
2000:790C53pushbx
2000:790D50pushax
2000:790E56pushsi
2000:790FBE0C01movsi,10Ch
2000:7912B90001movcx,100h
2000:7915next_byte:;CODEXREF:Make_CRC16_Table+2B
2000:7915B80001movax,100h
2000:79182BC1subax,cx
2000:791A50pushax
2000:791BBB0000movbx,0
2000:791Eis_bit:;CODEXREF:Make_CRC16_Table+25
2000:791EA90100testax,1
2000:79217407jzshortnot_bit
2000:7923D1E8shrax,1
2000:79253501A0xorax,0A001h;CRCpoly
2000:7928EB02jmpshortpoint_to_next_byte
2000:792A;---------------------------------------------------------------------------
2000:792Anot_bit:;CODEXREF:Make_CRC16_Table+16
2000:792AD1E8shrax,1
2000:792Cpoint_to_next_byte:;CODEXREF:Make_CRC16_Table+1D
2000:792C43incbx
2000:792D83FB08cmpbx,8
2000:793072ECjbshortis_bit
2000:79325Bpopbx
2000:79338900mov[bx+si],ax
2000:793546incsi
2000:7936E2DDloopnext_byte
2000:79385Epopsi
2000:793958popax
2000:793A5Bpopbx
2000:793B59popcx
2000:793CC3retn
2000:793CMake_CRC16_Tableendp
________________________________________

2000:79E8---Read_Header---
2000:79E8in:ds=scratchpad_segment
2000:79E8ds:102h=LZH_hdr_byte_index
2000:79E8
2000:79E8out:ds:102h=LZH_hdr_byte_index
2000:79E8ds:108h=componnt_decomprrsion_seg_addr
2000:79E8ds:10Ah=componnt_decomprrsion_offset_addr
2000:79E8ds:310h=uncompressed_componnt_size
2000:79E8ds:314h=component_seg:offset_decompression_addr
2000:79E8ds:571Ch=LZH_hdr_len
2000:79E8ds:571Dh=LZH_hdr_chksum
2000:79E8ds:571Eh=LZHcrc16val
2000:79E8ds:0-ds:LZH_hdr_len=copyofcurrentcomponentLZHhdr
2000:79E8;---------------SUBROUTINE---------------------------------------
2000:79E8Read_Headerprocnear;CODEXREF:Decompression_Ngine+EF
2000:79E860pusha
2000:79E906pushes
2000:79EA8B1E0201movbx,ds:102h
2000:79EEE8DA00callFetch_Byte
2000:79F1FF060201incwordptrds:102h
2000:79F5A21C57movds:571Ch,al
2000:79F807popes
2000:79F9803E1C5700cmpbyteptrds:571Ch,0
2000:79FE7504jnzshortread_LZH_hdr_ok
2000:7A00error:;CODEXREF:Read_Header+38
2000:7A00;Read_Header+71...
2000:7A00F9stc
2000:7A01E98600jmpexit
2000:7A04;---------------------------------------------------------------------------
2000:7A04read_LZH_hdr_ok:;CODEXREF:Read_Header+16
2000:7A0406pushes
2000:7A058B1E0201movbx,ds:102h
2000:7A09E8BF00callFetch_Byte;readLZH_hdr_chksumbyte
2000:7A0CFF060201incwordptrds:102h
2000:7A10A21D57movds:571Dh,al;1stpass:3000:571D=LZH_hdr_chksum
2000:7A1307popes
2000:7A14E826FFcallCalc_LZH_hdr_CRC16;fetchcompressedcomponentvaluetoRAM,
2000:7A14;thencalcitsCRC16checksum
2000:7A17E888FFcallCalcHdrSum
2000:7A1A3A061D57cmpal,ds:571Dh;isthestoredLZH_hdr8-bitchksummatchtheonethatread?
2000:7A1E7402jzshortLZH_hdr_8bit_chksum_ok
2000:7A20EBDEjmpshorterror
2000:7A22;---------------------------------------------------------------------------
2000:7A22LZH_hdr_8bit_chksum_ok:;CODEXREF:Read_Header+36
2000:7A22BB0500movbx,5
2000:7A25B90400movcx,4;bx+cx=compressed_component_size_index(Dword)
2000:7A28E899FFcallGetFromHeader
2000:7A2B66A31003movds:310h,eax
2000:7A2FBB0900movbx,9
2000:7A32B90400movcx,4;bx+cx=originalfilesize(Dword)
2000:7A35E88CFFcallGetFromHeader
2000:7A3866A31403movds:314h,eax
2000:7A3CBB0D00movbx,0Dh
2000:7A3FB90200movcx,2;bx+cx=decompression_component_offsetaddr(Word)
2000:7A42E87FFFcallGetFromHeader
2000:7A45A30A01movds:10Ah,ax
2000:7A48BB0F00movbx,0Fh
2000:7A4BB90200movcx,2;bx+cx=decompression_component_segmentaddr(Word)
2000:7A4EE873FFcallGetFromHeader
2000:7A51A30801movds:108h,ax
2000:7A54803E110020cmpbyteptrds:11h,20h;'';isLZHlevel1fileattribute?
2000:7A5975A5jnzshorterror
2000:7A5B803E120001cmpbyteptrds:12h,1;isLZHlevel1?
2000:7A60759Ejnzshorterror
2000:7A620FB61E1C57movzxbx,byteptrds:571Ch;bx=lzh_hdr_len
2000:7A6783EB05subbx,5;bx=CRC16_byte_index
2000:7A6AB90200movcx,2
2000:7A6DE854FFcallGetFromHeader;readCRC16value
2000:7A70A31E57movds:571Eh,ax;ds:571Eh=CRC16_val
2000:7A73BB1300movbx,13h;bx=filename_lenbyteindex
2000:7A768A9F0000movbl,[bx+0];bl=filename_len
2000:7A7AB81400movax,14h
2000:7A7D03D8addbx,ax;bx=CRC16_byte_index
2000:7A7FC687000024movbyteptr[bx+0],24h;'$'
2000:7A84C687010000movbyteptr[bx+1],0
2000:7A89F8clc
2000:7A8Aexit:;CODEXREF:Read_Header+19
2000:7A8A61popa
2000:7A8BC3retn
2000:7A8BRead_Headerendp
________________________________________

2000:793DCalc_LZH_hdr_CRC16procnear;CODEXREF:Read_Header+2C
2000:793D50pushax
2000:793E53pushbx
2000:793F51pushcx
2000:794052pushdx
2000:79410FB60E1C57movzxcx,byteptrds:571Ch
2000:794606pushes
2000:794756pushsi
2000:79488B1E0201movbx,ds:102h
2000:794CBE0000movsi,0
2000:794Fnext_byte:;CODEXREF:Calc_LZH_hdr_CRC16+19
2000:794FE87901callFetch_Byte
2000:79528804mov[si],al
2000:795443incbx
2000:795546incsi
2000:7956E2F7loopnext_byte
2000:79588BC3movax,bx
2000:795A2B060201subax,ds:102h
2000:795E891E0201movds:102h,bx
2000:79625Epopsi
2000:796307popes
2000:7964A21C57movds:571Ch,al
2000:79678BC8movcx,ax
2000:796901061403addds:314h,ax
2000:796D41inccx
2000:796EBB0000movbx,0
2000:7971next_CRC_byte:;CODEXREF:Calc_LZH_hdr_CRC16+5E
2000:79710FB607movzxax,byteptr[bx]
2000:797449deccx
2000:7975E326jcxzshortexit
2000:797750pushax
2000:797853pushbx
2000:797956pushsi
2000:797A8BF0movsi,ax
2000:797CA10C03movax,ds:30Ch
2000:797F33C6xorax,si
2000:798125FF00andax,0FFh
2000:79848BF0movsi,ax
2000:7986D1E6shlsi,1
2000:79888B9C0C01movbx,[si+10Ch]
2000:798CA10C03movax,ds:30Ch
2000:798FC1E808shrax,8
2000:799233C3xorax,bx
2000:7994A30C03movds:30Ch,ax
2000:79975Epopsi
2000:79985Bpopbx
2000:799958popax
2000:799A43incbx
2000:799BEBD4jmpshortnext_CRC_byte
2000:799D;---------------------------------------------------------------------------
2000:799Dexit:;CODEXREF:Calc_LZH_hdr_CRC16+38
2000:799D5Apopdx
2000:799E59popcx
2000:799F5Bpopbx
2000:79A058popax
2000:79A1C3retn
2000:79A1Calc_LZH_hdr_CRC16endp
________________________________________

2000:79A2CalcHdrSumprocnear;CODEXREF:Read_Header+2F
2000:79A253pushbx
2000:79A351pushcx
2000:79A452pushdx
2000:79A5B80000movax,0
2000:79A80FB60E1C57movzxcx,byteptrds:571Ch
2000:79ADloc_2000_79AD:;CODEXREF:CalcHdrSum+19j
2000:79AD0FB61E1C57movzxbx,byteptrds:571Ch
2000:79B22BD9subbx,cx
2000:79B40FB6970000movzxdx,byteptr[bx+0]
2000:79B903C2addax,dx
2000:79BBE2F0looploc_2000_79AD
2000:79BD5Apopdx
2000:79BE59popcx
2000:79BF5Bpopbx
2000:79C025FF00andax,0FFh
2000:79C3C3retn
2000:79C3CalcHdrSumendp
________________________________________

2000:79C4---GetFromHeader---
2000:79C4in:bx=byte_indexofthe"component"toread
2000:79C4cx=lengthof"component"toread
2000:79C4
2000:79C4out:eax=dword_read
2000:79C4;---------------SUBROUTINE---------------------------------------
2000:79C4GetFromHeaderprocnear;XREF:Read_Header+40
2000:79C4;Read_Header+4D...
2000:79C453pushbx
2000:79C56652pushedx
2000:79C756pushsi
2000:79C86633C0xoreax,eax
2000:79CB4Bdecbx
2000:79CC41inccx
2000:79CDnext_byte:;CODEXREF:GetFromHeader+1D
2000:79CD49deccx
2000:79CEE313jcxzshortexit
2000:79D066C1E008shleax,8
2000:79D48BF3movsi,bx
2000:79D603F1addsi,cx
2000:79D8660FB6940000movzxedx,byteptr[si+0]
2000:79DE6603C2addeax,edx
2000:79E1EBEAjmpshortnext_byte
2000:79E3;---------------------------------------------------------------------------
2000:79E3exit:;CODEXREF:GetFromHeader+A
2000:79E35Epopsi
2000:79E4665Apopedx
2000:79E65Bpopbx
2000:79E7C3retn
2000:79E7GetFromHeaderendp
看完这些彻底的线索,我们成功的构建映射了bios解压部分:
StartingaddressofdecompressedBIOScomponentinRAMCompressedSizeDecompressedSizeDecompressionState(byBootblockcode)Componentdescription
4100:0000h3A85h57C0hDecompressedtoRAMbeginningataddressincolumnone.awardext.rom,thisisa"helpermodule"fororiginal.tmp
4001:0000h5CDChA000hNotdecompressedyetcpucode.bin,thisistheCPUmicrocode
4003:0000hDFAh21A6hNotdecompressedyetacpitbl.bin,thisistheACPItable
4002:0000h35Ah2D3ChNotdecompressedyetiwillbmp.bmp,thisistheEPAlogo
4027:0000hA38hFEChNotdecompressedyetnnoprom.bin,explanationN/A
4007:0000h1493h2280hNotdecompressedyetantivir.bin,thisisBIOSantiviruscode
4028:0000hF63Ah14380hNotdecompressedyetROSUPD.bin,seemstobecustomLogodisplayprocedure
5000:0000h15509h20000hDecompressedtoRAMbeginningataddressincolumnone.original.tmp,thesystemBIOS
注意:绿色覆盖的解压地址被另外的方法处理:
A.上面解释的部分不是真正的被解压区域。只是某种真正解压区域的占有区域,稍后由original.tmp处理。结论是:在bootblock中只有original.tmp和awardext.rom被Decompress_System_Bios解压缩。如果你想改变这个,那么试着计算被解压代码的大小总和,他不会合适的!
B.所有的这些被解压段地址部分被Decompression_Ngineprocedure变换到4000h,就像你看到的在例程里面地址2000:7842h。
C.“(被解压)开始地址。。。”中的40xxh实际上是一个ID,工作如下:40(高字节)是ID,标示它是一个扩展bios,将要在稍后的original.tmp执行时被解压缩。Xx是一个id,在original.tmp用到,标示要被解压缩的部分。这些在下面的original.tmp中会详细解释。
D.所有的这些部分都要在original.tmp执行时被解压缩。解压结果被放在地址4000:0000h,但是不会在同一时刻。有一些(也许所有的)部分也要从那个地址重新定向,在另外的部分在那个地址被解压缩后保留他们的内容。这些在下面的original.tmp中会详细解释。
7.1.6.7.ShadowtheBIOScode
7.Shadowbios代码。假设解压例程成功的完成了,上面的例程接着拷贝被解压得systembios(original.tmp),从RAM中的5000:0000h-6000:FFFFh到E_0000h-F_FFFFh。完成如下:
1)重新编程北桥shadowRAM控制寄存器,使能只写到地址E_0000h-F_FFFFh,促进写操作这个地址范围到DRAM(没有到biosrom芯片)。
2)进行一个字符串拷贝操作,拷贝被解压了的systembios(original.tmp),从5000:0000h-6000:FFFFh到E_0000h-F_FFFFh。
3)重新编程北桥shadowRAM控制寄存器,使能只读到地址E_0000h-F_FFFFh,促进读操作这个地址范围到DRAM(没有到biosrom芯片)。这个也是对systembios代码写保护
7.1.6.8.EnablethemicroprocessorcachethenjumpintothedecompressedsystemBIOS
8.使能微处理高速缓存,然后跳转到压缩的systembios。这一步是普通bootblock代码执行路径的最后一步。使能处理器高速缓存后,代就会跳转到RAM地址F000:F80Dh中的写保护的systembios(original.tmp),如上面看到的代码。这个跳转的目的地址好像在不同的awardbios中都一样。
现在我要呈现在跳转到解压缩的original.tmp之前,压缩的和解压的bios部分的内存地图。这个很重要,因为这会在等会的分析解压缩了的original.tmp方便我们。现在我们不得不注意,所有的代码都在RAM中之行,在没有代码在biosrom芯片中执行了。
AddressRangeinRAMDecompressionState(byBootblockcode)Description
0000:6000h-0000:6xxxhN/AThisareacontainstheheaderoftheextensioncomponent(componentotherthanoriginal.tmpandawardext.rom)fetchedfromthecompressedBIOSat8000:0000h-9000:FFFFh(previouslyBIOScomponentatFFFC_0000h-FFFD_FFFFhintheBIOSchip).Notethatthisisfetchedherebypartofthebootblockinsegment2000h.
1000:0000h-2000:5531hCompressedThisareacontainsthecompressedoriginal.tmp.It'spartofthecopyofthelast128KBoftheBIOS(previouslyBIOScomponentatE000:0000h-F000:FFFFhintheBIOSchip).ThiscodeisshadowedherebythebootblockinBIOSROMchip.
2000:5532h-2000:5FFFhPureBinary(non-executable)Thisareacontainsonlypaddingbytes.
2000:6000h-2000:FFFFhPurebinary(executable)Thisareacontainsthebootblockcode.It'spartofthecopyofthelast128KBoftheBIOS(previouslyBIOScomponentatE000:0000h-F000:FFFFhintheBIOSROMchip).ThiscodeisshadowedherebythebootblockinBIOSROMchip.Thisiswhereourcodecurrentlyexecuting(the"copy"ofbootblockinsegment2000h).
4100:0000h-4100:57C0hDecompressedThisareacontainsthedecompressedawardext.rom.Notethatthedecompressionprocessisaccomplishedbypartofthebootblockcodeinsegment2000h.
5000:0000h-6000:FFFFhDecompressedThisareacontainsthedecompressedoriginal.tmp.Notethatthedecompressionprocessisaccomplishedbypartofthebootblockcodeinsegment2000h.
8000:0000h-9000:FFFFhCompressedThisareacontainsthecopyofthefirst/lower128KBoftheBIOS(previouslyBIOScomponentatFFFC_0000h-FFFD_0000hintheBIOSchip).Thiscodeiscopiedherebythebootblockcodeinsegment2000h.
E000:0000h-F000:FFFFhDecompressedThisareacontainscopyofthedecompressedoriginal.tmp,whichiscopiedherebythebootblockcodeinsegment2000h.

最后要注意:这里解释的booblock只涉及到了normalBootblockcodeexecutionpath,意思是没有解释一旦original.tmp崩溃时的bootblockPOST。有时间的话,我将要涉及到。所有的bootblock如上,我们将要开始研究original.tmp。
7.2.SystemBIOSa.k.aOriginal.tmp
我们刚进行了上面的bootblock,我要高亮晦涩的代码执行路径。所以,现在,你正在看我的bios的解压了的original.tmp的反汇编代码。
7.2.1.Entrypointfrom"BootblockinRAM"
AddressHexMnemonic
F000:F80DThiscodeisjumpedintobythebootblockcode
F000:F80DifeverythingwentOK
F000:F80DE902F6jmpsysbios_entry_point;
这里是在重新定位和写保护systembios后,bootblock跳转的地方。
7.2.2.Theawardext.romandExtensionBIOSComponents(lower128KBbios-code)RelocationRoutine
AddressAssemblyCode
F000:EE12sysbios_entry_point:;CODEXREF:F000:F80D
F000:EE12movax,0
F000:EE15movss,ax;ss=0000h
F000:EE17movsp,1000h;setupstackat0:1000h
F000:EE1Acallsetup_stack;CallProcedure
F000:EE1Dcallinit_DRAM_shadowRW;CallProcedure
F000:EE20movsi,5000h;ds=5000h(lookatcopy_mem_word)
F000:EE23movdi,0E000h;es=E000h(lookatcopy_mem_word)
F000:EE26movcx,8000h;copy64KByte
F000:EE29callcopy_mem_word;copyE000hsegmentroutine,i.e.
F000:EE29;copy64Kbytefrom5000:0htoE000:0h
F000:EE2Ccallj_init_DRAM_shadowR;CallProcedure
F000:EE2Fmovsi,4100h;ds=XGroupsegmentdecompressed,i.e.
F000:EE2F;atthispoint4100h
F000:EE32movdi,6000h;es=newXGroupsegment
F000:EE35movcx,8000h;copy64KByte
F000:EE38callcopy_mem_word;copyXGroupsegment,i.e.
F000:EE38;64Kbytefrom4100:0hto6000:0h
F000:EE3BcallEnter_UnrealMode;jumpbelowinUnrealMode
F000:EE3EBegin_in_UnrealMode
F000:EE3Emovax,ds
F000:EE40moves,ax;es=ds(3rdentryinGDT)
F000:EE40;base_addr=00000000h;limit4GB
F000:EE42assumees:nothing
F000:EE42movesi,80000h;movesi,(POST_Cmprssed_Temp_Segshl4)
F000:EE42;relocatelower128KBbioscode
F000:EE48movedi,160000h
F000:EE4Emovecx,8000h
F000:EE54cld;ClearDirectionFlag
F000:EE55repmovsdwordptres:[edi],dwordptr[esi];move
F000:EE55;128kdatato160000h(phyaddr)
F000:EE59callLeave_UnrealMode;CallProcedure
F000:EE59End_in_UnrealMode
F000:EE5Cmovbyteptr[bp+214h],0;movbyteptr
F000:EE5C;POST_SPEED[bp],Normal_Boot
F000:EE61movsi,626Bh;offset626Bh(E000hPOSTtests)
F000:EE64push0E000h;segmentE000h
F000:EE67pushsi;nextinstructionoffset(626Bh)
F000:EE68retf;jmptoE000:626Bh
________________________________________

F000:7440Enter_UnrealModeprocnear;CODEXREF:F000:EE3B
F000:7440movax,cs
F000:7442movds,ax;ds=cs
F000:7444assumeds:F000
F000:7444lgdtqwordptrGDTR_F000_5504;LoadGlobalDescriptorTableRegister
F000:7449moveax,cr0
F000:744Coral,1;LogicalInclusiveOR
F000:744Emovcr0,eax
F000:7451movax,10h
F000:7454movds,ax;ds=10h(3rdentryinGDT)
F000:7456assumeds:nothing
F000:7456movss,ax;ss=10h(3rdentryinGDT)
F000:7458assumess:nothing
F000:7458retn;ReturnNearfromProcedure
F000:7458Enter_UnrealModeendp
________________________________________

F000:5504GDTR_F000_5504dw30h;DATAXREF:Enter_PMode+4
F000:5504;GDTlimit(6validdesc)
F000:5506dd0F550Ah;GDTphyaddr(below)
F000:550Adq0;nulldesc
F000:5512dq9F0F0000FFFFh;codedesc(08h)
F000:5512;base_addr=F0000h;seg_limit=64KB;code,execute/ReadOnly
F000:5512;conforming,accessed;granularity=1Byte;16-bitsegment;
F000:5512;segmentpresent,code,DPL=0
F000:551Adq8F93000000FFFFh;datadesc(10h)
F000:551A;base_addr=00000000h;seg_limit=4GB;data,R/W,accessed;
F000:551A;granularity=4KB;16-bitsegment;segmentpresent,
F000:551A;data,DPL=0
F000:5522dq0FF0093FF0000FFFFh;datadesc18h
F000:5522;base_addr=FFFF0000h;seg_limit=64KB;data,R/W,accessed;
F000:5522;16-bitsegment,granularity=1byte;
F000:5522;segmentpresent,data,DPL=0.
F000:552Adq0FF0093FF8000FFFFh;datadesc20h
F000:552A;base_addr=FFFF8000h;seg_limit=64KB;data,R/W,accessed;
F000:552A;16-bitsegment,granularity=1byte;
F000:552A;segmentpresent,data,DPL=0.
F000:5532dq930F0000FFFFh;datadesc28h
F000:5532;base_addr=F0000h;seg_limit=64KB;data,R/W,accessed;
F000:5532;16-bitsegment,granularity=1byte;
F000:5532;segmentpresent,data,DPL=0.
________________________________________
注意:上面的代码执行以后,这个内存地图就再改变了一次。但是这个时候,只对于压缩BIOS扩展,比如低128KB的bios代码和解压缩了的awardext.rom,在上面bootblock解释到的内存地图部分的被覆盖了。
NewAddressRangeinRAMDecompressionStateDescription
6000:0000h-6000:57C0hDecompressedThisistherelocatedawardext.rom
160000h-17FFFFhCompressedThisistherelocatedcompressed"BIOSextension",includingthecompressedawardext.rom.(i.e.thisisthecopyofFFFC0000h-FFFDFFFFintheBIOSromchip.

7.2.3.CalltothePOSTroutinea.k.a"POSTjumptableexecution"
AddressAssemblyCode
E000:626BThelastofthethesePOSTroutinesstartstheEISA/ISA
E000:626BsectionofPOSTandthusthiscallshouldneverreturn.
E000:626BIfitdoes,weissueaPOSTcodeandhalt.
E000:626B
E000:626BThisroutinecalledfromF000:EE68h
E000:626B
E000:626Bsysbios_entry_point_contda.k.aNORMAL_POST_TESTS
E000:626Bmovcx,3;movcx,STD_POST_CODE
E000:626Emovdi,61C2h;movdi,offsetSTD_POST_TESTS
E000:6271callRAM_POST_tests;thiswon'treturninnormalcondition
E000:6274jmpshortHalt_System;Jump
________________________________________

E000:6276;---------------SUBROUTINE---------------------------------------
E000:6276
E000:6276RAM_POST_testsprocnear;CODEXREF:last_E000_POST+D
E000:6276;last_E000_POST+18...
E000:6276moval,cl;cl=3
E000:6278out80h,al;manufacture'sdiagnosticcheckpoint
E000:627Apush0F000h
E000:627Dpopfs;fs=F000h
E000:627F
E000:627F;ThisisthebeginningofthecallintoE000segment
E000:627F;POSTfunctiontable
E000:627Fassumefs:F000
E000:627Fmovax,cs:[di];inthebeginning:
E000:627F;di=61C2h;ax=cs:[di]=154Eh
E000:627F;calledfromE000:2489w/di=61FCh(dummy)
E000:6282incdi;Incrementby1
E000:6283incdi;di=di+2
E000:6284orax,ax;LogicalInclusiveOR
E000:6286jzRAM_post_return;RAMPostError
E000:6288pushdi;savedi
E000:6289pushcx;savecx
E000:628Acallax;call154Eh(relativecalladdr)
E000:628A;,oneofthiscall
E000:628A;won'treturninnormalcondition
E000:628Cpopcx;restoreall
E000:628Dpopdi
E000:628EjbRAM_post_return;JumpifBelow(CF=1)
E000:6290inccx;Incrementby1
E000:6291jmpshortRAM_POST_tests;Jump
E000:6293;---------------------------------------------------------------------------
E000:6293
E000:6293RAM_post_return:;CODEXREF:RAM_POST_tests+10
E000:6293;RAM_POST_tests+18
E000:6293retn;ReturnNearfromProcedure
E000:6293RAM_POST_testsendp
________________________________________

E000:61C2E0_POST_TESTS_TABLE:
E000:61C2dw154Eh;Restorebootflag
E000:61C4dw156Fh;Chk_Mem_Refrsh_Toggle
E000:61C6dw1571h;keyboard(anditscontroller)POST
E000:61C8dw16D2h;chksumROM,checkEEPROM
E000:61C8;onerrorgeneratespkrtone
E000:61CAdw1745h;CheckCMOScircuitry
E000:61CCdw178Ah;"chipsetdefaults"initialization
E000:61CEdw1798h;initCPUcache(bothCyrixandIntel)
E000:61D0dw17B8h;initinterruptvector,alsoinitialize
E000:61D0;"signatures"usedforExt_BIOScomponents
E000:61D0;decompression
E000:61D2dw194Bh;Init_mainboard_equipment&CPUmicrocode
E000:61D2;chkISACMOSchksum?
E000:61D4dw1ABCh;Checkchecksum.Initializekeyboardcontroller
E000:61D4;andsetupallofthe40:areadata.
E000:61D6dw1B08h;RelocateextendedBIOScode
E000:61D6;initCPUMTRR,PCIREGs(VideoBIOS?)
E000:61D8dw1DC8h;Video_Init(includingEPAproc)
E000:61DAdw2342h
E000:61DCdw234Eh
E000:61DEdw2353h;dummy
E000:61E0dw2355h;dummy
E000:61E2dw2357h;dummy
E000:61E4dw2359h;initProgrammableTimer(PIT)
E000:61E6dw23A5h;initPIC_1(programmableInterruptCtlr)
E000:61E8dw23B6h;sameasabove?
E000:61EAdw23F9h;dummy
E000:61ECdw23FBh;initPIC_2
E000:61EEdw2478h;dummy
E000:61F0dw247Ah;dummy
E000:61F2dw247Ah
E000:61F4dw247Ah
E000:61F6dw247Ah
E000:61F8dw247Ch;thiswillcallRAM_POST_testsagain
E000:61F8;forvaluesbelow(a.k.aISAPOST)
E000:61FAdw0
E000:61FAEND_E0_POST_TESTS_TABLE
________________________________________

E000:247Clast_E000_POSTprocnear
E000:247Ccli;ClearInterruptFlag
E000:247Dmovwordptr[bp+156h],0
E000:2483movcx,30h;'0'
E000:2486movdi,61FCh;thisaddrcontains0000h
E000:2489
E000:2489repeat_RAM_POST_tests:;CODEXREF:last_E000_POST+10
E000:2489callRAM_POST_tests;thiscallimmediatelyreturn
E000:2489;sincecs:[di]=0000h
E000:248Cjbrepeat_RAM_POST_tests;jmpifCF=1;nottaken
E000:248Emovcx,30h;'0'
E000:2491movdi,61FEh;cs:[di]contains249Ch
E000:2494
E000:2494repeat_RAM_POST_tests_2:;CODEXREF:last_E000_POST+1B
E000:2494callRAM_POST_tests;thiscallshouldnvrreturnif
E000:2494;everythingisok
E000:2497jbrepeat_RAM_POST_tests_2;JumpifBelow(CF=1)
E000:2499jmpHalt_System;
E000:2499last_E000_POSTendp
________________________________________

E000:61FCISA_POST_TESTS
E000:61FCdw0
E000:61FEdw249Ch
E000:6200dw26AFh
E000:6202dw29DAh
E000:6204dw2A54h;dummy
E000:6206dw2A54h
E000:6208dw2A54h
E000:620Adw2A54h
E000:620Cdw2A54h
E000:620Edw2A54h
E000:6210dw2A56h;dummy
E000:6212dw2A56h
E000:6214dw2A56h
E000:6216dw2A58h
E000:6218dw2A64h
E000:621Adw2B38h
E000:621Cdw2B5Eh;dummy
E000:621Edw2B60h;dummy
E000:6220dw2B62h
E000:6222dw2BC8h;HDinit?
E000:6224dw2BF0h;gameioportinit?
E000:6226dw2BF5h;dummy
E000:6228dw2BF7h;FPUerrorinterruptrelated
E000:622Adw2C53h;dummy
E000:622Cdw2C55h
E000:622Edw2C61h;dummy
E000:6230dw2C61h
E000:6232dw2C61h
E000:6234dw2C61h
E000:6236dw2C61h
E000:6238dw2C61h
E000:623Adw2CA6h
E000:623Cdw6294h;setcursorcharcteristic
E000:623Edw62EAh
E000:6240dw6329h
E000:6242dw6384h
E000:6244dw64D6h;dummy
E000:6246dw64D6h
E000:6248dw64D6h
E000:624Adw64D6h
E000:624Cdw64D6h
E000:624Edw64D6h
E000:6250dw64D6h
E000:6252dw64D6h
E000:6254dw64D6h
E000:6256dw64D6h
E000:6258dw64D6h
E000:625Adw64D6h
E000:625Cdw64D6h
E000:625Edw64D8h;bootstrap
E000:6260dw66A1h
E000:6262dw673Ch
E000:6264dw6841h;issuesint19h(bootstrap)
E000:6266dw0
E000:6266END_ISA_POST_TESTS

注意:
这个“POSTjumptable”例程在他们遇到一些执行错误的时候会设置CarryFlay(CF=1)。在POST例程返回,这个CarryFlag就要被测试,如果它被设置,然后这个“RAM_POST_TESTS”就会立刻返回,这样就会使系统崩溃,系统扬声器就会发出声音。
7.2.4.The"segmentvector"Routines
下面只是一个它的用法例子。它有很多地方用得到。有一对这样的“段向量”。一些就要从段E000h跳转到F000h,一些从段F000h跳到E000h,一些从E000h到6000h(重新定位的解压了的awardext.rom),一些从F000h到6000h(重新定位的解压了的awardext.rom)。
a.Firstvariant:jumpfromsegmentE000htoF000h
b.AddressAssemblyCode
________________________________________

E000:1553Restore_Warm_Boot_Flagprocnear;CODEXREF:POST_1S
.........
E000:155AcallF_Vect_Read_CMOS_Byte
.........
E000:156ERestore_Warm_Boot_Flagendp
________________________________________

AddressMachineCodeAssemblyCode
E000:6CA2F_Vect_Read_CMOS_Byteprocnear;CODEXREF:Restore_Warm_Boot_Flag+7p
E000:6CA2;000E1747p...
E000:6CA2push0E000h
E000:6CA5push6CB3h
E000:6CA8push0EC31h
E000:6CABpush0E4FDh;Read_CMOS_Byte
E000:6CAEjmpfarptrF000_Vector
E000:6CB3;---------------------------------------------------------------------------
E000:6CB3retn
E000:6CB3F_Vect_Read_CMOS_Byteendp
________________________________________

F000:EC30F000_Vector:;CODEXREF:000E1781J000E17AAJ...
F000:EC30retn
F000:EC31;---------------------------------------------------------------------------
F000:EC31retf
________________________________________

F000:E4FDRead_CMOS_Byteprocnear
F000:E4FDxchgbx,bx
F000:E4FFnop
F000:E500out70h,al;CMOSMemory:
F000:E500;usedbyreal-timeclock
F000:E502jcxzshort$+2
F000:E504jcxzshort$+2
F000:E506xchgbx,bx
F000:E508inal,71h;CMOSMemory
F000:E50Ajcxzshort$+2
F000:E50Cjcxzshort$+2
F000:E50Eretn
F000:E50ERead_CMOS_Byteendp
________________________________________

c.Secondvariant:jumpfromsegmentE000hto6000h
d.AddressMachineCodeAssemblyCode
________________________________________

.........
E000:1737pushcs
E000:1738push1743h;retaddrbelow
E000:173Bpush1829h;funcaddrinXGROUPROM
E000:173Ejmpfarptrloc_6000_2
E000:1743;---------------------------------------------------------------------------
E000:1743clc
E000:1744retn
.........
________________________________________

6000:0000locret_6000_0:;CODEXREF:00060017j
6000:0000retn;jumptotargetprocedure
6000:0001;---------------------------------------------------------------------------
6000:0001retf;backtocaller
________________________________________

6000:0002loc_6000_2:;pushreturnaddrforretn
6000:0002push1;(addr_ofretfabove)
6000:0005pushax
6000:0006pushf
6000:0007cli
6000:0008xchgbp,sp
6000:000Amovax,[bp+4];movax,1;lookat1stinstabove
6000:000Dxchgax,[bp+6];xchgax,word_pushed_by_org_tmp
6000:0010mov[bp+4],ax;[sp+4]=word_pushed_by_org_tmp
6000:0013xchgbp,sp;modifysp
6000:0015popf
6000:0016popax
6000:0017jmpshortlocret_6000_0;jumpintoword_pushed_by_original.tmp
________________________________________

6000:1829cli;ClearInterruptFlag
.........
6000:18B3retn;ReturnNearfromProcedure
________________________________________

e.Thirdvariant:jumpfromsegment6000htoF000h
f.AddressAssemblyCode
________________________________________

6000:4F60reinit_chipsetprocfar
6000:4F60pushds
6000:4F61movax,0F000h
6000:4F64movds,ax;ds=F000h
6000:4F66assumeds:nothing
6000:4F66movbx,0E38h;ptrtoPCIregvals(ds:bx=F000:E38h)
6000:4F69
6000:4F69next_PCI_reg:;CODEXREF:reinit_chipset+3D
6000:4F69cmpbx,0EF5h;arewefinished?
6000:4F6Djzexit_PCI_init;ifyes,thenexit
6000:4F6Fmovcx,[bx+1];cx=PCIaddrtoread
6000:4F72callsetup_read_write_PCI;onret,ax=F70Bh,di=F725h
6000:4F75pushcs
6000:4F76push4F7Fh
6000:4F79pushax;gotoF000:F70B(Read_PCI_Byte)
6000:4F7Ajmpfarptr0E000h:6188h;goto_seg_F000
6000:4F7F;---------------------------------------------------------------------------
6000:4F7Fmovdx,[bx+3];reverse-andmask
.........
________________________________________

E000:6188goto_F000_seg:;CODEXREF:HD_init_?+3BD
E000:6188;HD_init_?+578...
E000:61886831ECpush0EC31h
E000:618B50pushax
E000:618C9Cpushf;PushFlagsRegisterontotheStack
E000:618DFAcli;ClearInterruptFlag
E000:618E87ECxchgbp,sp;ExchangeRegister/MemorywithRegister
E000:61908B4604movax,[bp+4];movax,EC31h
E000:6193874606xchgax,[bp+6];xchgretaddrandEC31h
E000:6196894604mov[bp+4],ax;mov[sp+4],[sp+6]
E000:619987ECxchgbp,sp;ExchangeRegister/MemorywithRegister
E000:619B9Dpopf;PopStackintoFlagsRegister
E000:619C58popax
E000:619DEA30EC00F0jmpfarptrF000_func_vector;Jump
________________________________________

F000:EC30F000_func_vector:;CODEXREF:chk_cmos_circuit+3C
F000:EC30C3retn;jumptotargetfunction
F000:EC31;-------------------------------------------------------------------
F000:EC31CBretf;returntocallingsegment:offset(6000:4F7F)
________________________________________

F000:F70Bread_PCI_byteprocnear;CODEXREF:enable_ROM_write?+4
.........
F000:F724retn;ReturnNeartoF000:EC31h
F000:F724read_PCI_byteendp

7.2.5."chksum_ROM"Procedure
这个例程是“E0_POST_TESTS”的一部分,“E0_POST_TESTS”是由POST例程通过使用“POSTjumptable”来调用的。这个例程没有立刻的返回。但是,一个调用到“Check_F_Next”的调用将会完成这个“nearreturn”,这个近返回需要继续进行下一个“POST进程”的执行。
________________________________________
E000:16D2chksum_ROMprocnear
.........
E000:16FF741EjzCheck_F_Next;yes.Thisjumpwillreturnthisroutine
E000:16FF;towhereit'scalled
.........
E000:171DEBE6jmpshortspkr_endless_loop;Jump
E000:171Dchksum_ROMendp
________________________________________
E000:171FCheck_F_Nextprocnear;CODEXREF:chksum_ROM+2D
.........
E000:1743F8clc;signalsuccessfulexecution
E000:1744C3retn;retntoRAM_POST_TESTS,proceedtonextPOSTproc
E000:1744Check_F_Nextendp;sp=-6
________________________________________
7.2.6.Original.tmpDecompressionRoutineforThe"Extension_BIOSComponents"
这是一个在最开始的时候最会混淆的地方。但是,通过理解它,我们实际上的没有更多的需要对“bios代码执行路径”担心的。我怀疑我们这里要解释的相同的技术适用于绝大部分的awardbios。这个例程基本的run-down解释如下:
a.Decompress_System_BIOS历程被“主bootblock执行路径”(在bootblock代码在地址段2000h执行期间)调用,保存了必需的对在RAM预先确定区域有用的标志,下面展示:
________________________________________
2000:E512Decompress_System_BIOSprocnear;CODEXREF:0002E3DC
2000:E512E8EBDAcallCopy_C_seg_n_D_seg;copylower128KBytebioscodefromROM(atFFFC_0000h-
2000:E512;FFFD_0000h)toRAM(at8000:0000h-9000:FFFFh)
2000:E51532E4xorah,ah
2000:E51733C9xorcx,cx
2000:E519BB0080movbx,8000h
2000:E51C8EDBmovds,bx;ds=8000h,containscompressed
2000:E51C;lower128KBbioscomponents(awdext,etc.)
2000:E51Eassumees:nothing,ds:nothing
2000:E51E33F6xorsi,si
2000:E520next_Cseg_Dseg_byte:;CODEXREF:Decompress_System_BIOS+11
2000:E520;Decompress_System_BIOS+1F
2000:E520AClodsb
2000:E52102E0addah,al;calc8-bitchksumofC_segnD_seg
2000:E523E2FBloopnext_Cseg_Dseg_byte
2000:E5258CDBmovbx,ds
2000:E52780FF90cmpbh,90h;'?';areweinseg9000h?
2000:E52A7307jnbshortdone
2000:E52C80C710addbh,10h;movetonexthighersegment
2000:E52F8EDBmovds,bx
2000:E531assumeds:nothing
2000:E531EBEDjmpshortnext_Cseg_Dseg_byte
2000:E533;---------------------------------------------------------------------------
2000:E533done:;CODEXREF:Decompress_System_BIOS+18
2000:E533BB0010movbx,1000h
2000:E5368EDBmovds,bx;ds=start_addr_ofE_segnF_seginRAM
2000:E536;(compressedoriginal.tmp+bootblock)
2000:E538assumeds:_1000h
2000:E53833F6xorsi,si
2000:E53AFCcld
2000:E53Bnext_Eseg_Fseg_byte:;CODEXREF:Decompress_System_BIOS+2C
2000:E53B;Decompress_System_BIOS+3B
2000:E53BAClodsb
2000:E53C02E0addah,al;calc8bitchksum,cont'dfromchksumabove
2000:E53EE2FBloopnext_Eseg_Fseg_byte
2000:E54080FF20cmpbh,20h;'';areweinseg2000h?
2000:E543730Ajnbshortchksum_done
2000:E54580C710addbh,10h;movetonexthighersegment
2000:E5488EDBmovds,bx
2000:E54Aassumeds:_2000h
2000:E54AB9FE7Fmovcx,7FFEh;amountofbyteinlastseg(F_seginRAM)tocalc
2000:E54DEBECjmpshortnext_Eseg_Fseg_byte
2000:E54F;---------------------------------------------------------------------------
2000:E54Fchksum_done:;CODEXREF:Decompress_System_BIOS+31j
2000:E54F3A24cmpah,[si];cmpcalc-edchksumandchksumpointedtoby[si].
2000:E54F;thisisthechksumforthebiosbinary
2000:E54F;from00000hto37FFDh(C000:0h-F000:7FFDh)
2000:E5510F858CFEjnz_sysbios_chksum_error;jmpbackandcontinuetobootblockerrorhandlingroutine
2000:E555movbx,0
2000:E558moves,bx
2000:E55Aassumees:nothing
2000:E55Amoves:word_0_7004,0FFFFh;savesignaturetobeusedbyoriginal.tmp
2000:E55A;(POST_8S)fordecompression
2000:E561xoral,al
2000:E563
2000:E563;System_BIOSDecompressionstartedhere
2000:E563movbx,1000h
2000:E566moves,bx;es=src_seg
2000:E568assumees:_1000h
2000:E568xorbx,bx;bx=src_offset
2000:E56AcallDecompress;onret,CF=1iferroroccured
2000:E56D7213jbshortsysbios_decomp_error
2000:E56F66F7C10000FFFFtestecx,0FFFF0000h;compressedcomponentsizemorethan64KB?
2000:E576740Ajzshortsysbios_decomp_error;jmpifcompressedcomponentsize<=64KB
2000:E578BB0020movbx,2000h
2000:E57B8EC3moves,bx;proceed2nextcmprssdcomponnt(innextsegment)
2000:E57Dassumees:_2000h
2000:E57DBB0100movbx,1;bx=indextobeaddedtoprevioussrc_offsetincx
2000:E580EB1Bjmpshortrepeat_decompress;decompressremainingcomponent(1stpassjmptaken)
2000:E582;---------------------------------------------------------------------------
2000:E582sysbios_decomp_error:;CODEXREF:Decompress_System_BIOS+5B
2000:E582;Decompress_System_BIOS+64
2000:E582D0D0rclal,1
2000:E584BB0020movbx,2000h
2000:E5878EC3moves,bx
2000:E58933DBxorbx,bx
2000:E58BE82B00callDecompress
2000:E58ED0D0rclal,1
2000:E5903C03cmpal,3
2000:E5927505jnzshortdecompress_successfull
2000:E594B80010movax,1000h
2000:E597F9stc
2000:E598C3retn
2000:E599;---------------------------------------------------------------------------
2000:E599decompress_successfull:;CODEXREF:Decompress_System_BIOS+80
2000:E5990AC0oral,al
2000:E59B7510jnzshortsys_bios_dcomprss_done
2000:E59Drepeat_decompress:;CODEXREF:Decompress_System_BIOS+6E
2000:E59D;Decompress_System_BIOS+99
2000:E59D03D9addbx,cx;bx=pointtonextcompressedcomponent
2000:E59FE81700callDecompress
2000:E5A27209jbshortsys_bios_dcomprss_done;1stpassjmptaken
2000:E5A466F7C10000FFFFtestecx,0FFFF0000h
2000:E5AB74F0jzshortrepeat_decompress
2000:E5ADsys_bios_dcomprss_done:;CODEXREF:Decompress_System_BIOS+89
2000:E5AD;Decompress_System_BIOS+90
2000:E5ADE8ABDAcallDecmprss_Sysbios_Extension
2000:E5B00F842DFEjz_sysbios_chksum_error
2000:E5B4B80050movax,5000h;setsuccessflag
2000:E5B7F8clc
2000:E5B8C3retn
2000:E5B8Decompress_System_BIOSendp
________________________________________
b.Decmprss_Sysbios_Extension要保存段8000h或者9000h作为解压了的bios部分扩展的源段。这个是在RAM(seg2000h)中的bootblock执行期间完成的,如下展示:
________________________________________
2000:C05B--Decmprss_Sysbios_Extension--
2000:C05Bin:es=src_seg
2000:C05Bbx=src_offset
2000:C05B
2000:C05Bout:ZF=1-->erroroccured
2000:C05BZF=0-->executionsucceeded
2000:C05B;---------------SUBROUTINE---------------------------------------
2000:C05BDecmprss_Sysbios_Extensionprocnear
2000:C05B;CODEXREF:Decompress_System_BIOS:sys_bios_dcomprss_donep
2000:C05BBB0080movbx,8000h;es=seg_addrofC_segnD_segcopyinRAM
2000:C05B;thisseg_addrwillbesavedtoRAM(0000:60XXh)
2000:C05B;forextensioncomponentotherthanawdext.rom/awdeyt.rom
2000:C05E8EC3moves,bx
2000:C060assumees:nothing
2000:C06033DBxorbx,bx;resetsrc_offset_addr
2000:C0626633C9xorecx,ecx;resetcompressedsrcsize
2000:C06551pushcx
2000:C066repeat_decomprss:;CODEXREF:Decmprss_Sysbios_Extension+30j
2000:C06603D9addbx,cx
2000:C0687209jbshortmove_to_next_seg
2000:C06A66F7C10000FFFFtestecx,0FFFF0000h;issizemorethan64KB?
2000:C071740Ajzshortsize_less_than_64KB
2000:C073move_to_next_seg:;CODEXREF:Decmprss_Sysbios_Extension+Dj
2000:C0738CC1movcx,es
2000:C07581C10010addcx,1000h
2000:C0798EC1moves,cx
2000:C07Bassumees:nothing
2000:C07BEB1Ajmpshortreset_byte_counter
2000:C07D;---------------------------------------------------------------------------
2000:C07Dsize_less_than_64KB:;CODEXREF:Decmprss_Sysbios_Extension+16j
2000:C07D26807F1241cmpbyteptres:[bx+12h],41h;'A';isawardext.rom?
2000:C0827504jnzshortnot_awdext
2000:C08458popax
2000:C0850C01oral,1
2000:C08750pushax
2000:C088not_awdext:;CODEXREF:Decmprss_Sysbios_Extension+27j
2000:C088E82E25callDecompress
2000:C08B73D9jnbshortrepeat_decomprss
2000:C08D8CC3movbx,es
2000:C08F81C30010addbx,1000h
2000:C0938EC3moves,bx
2000:C095assumees:nothing
2000:C09533DBxorbx,bx
2000:C097reset_byte_counter:;CODEXREF:Decmprss_Sysbios_Extension+20j
2000:C09733C9xorcx,cx
2000:C099repeat_dcomprss2:;CODEXREF:Decmprss_Sysbios_Extension+4Ej
2000:C09903D9addbx,cx
2000:C09B26807F1241cmpbyteptres:[bx+12h],41h;'A'
2000:C0A07504jnzshortnot_awdext2
2000:C0A258popax
2000:C0A30C01oral,1;setsuccessfulflag
2000:C0A550pushax
2000:C0A6not_awdext2:;CODEXREF:Decmprss_Sysbios_Extension+45j
2000:C0A6E81025callDecompress
2000:C0A973EEjnbshortrepeat_dcomprss2
2000:C0AB58popax
2000:C0AC0AC0oral,al;al=0indicateanerroroccured
2000:C0AC;(awdext_romdoesn'texist)
2000:C0AEC3retn
2000:C0AEDecmprss_Sysbios_Extensionendp
________________________________________
c.Decompression_Ngine例程被解压缩例程在RAM(在seg2000h)中的bootblock改变头部时调用,它按需要改变头部,保存结果到RAM中重新定义区域,如下:
________________________________________
2000:7789---Decomprssion_Ngine---
2000:7789in:dx=scratch-pad_segment_for_decompression
2000:7789es=(compressed_segment_addr>>0xC)[hi_wordofsrcphyaddr]
2000:7789bx=compressed_offset_addr
2000:7789
2000:7789out:ecx=overall_compressed_component_length
2000:7789edx=original_file_size
2000:7789;---------------SUBROUTINE---------------------------------------
2000:7789Decompression_Ngineprocnear
.........
2000:77FFpushgs
2000:7801movdi,0
2000:7804movgs,di
2000:7806assumegs:nothing
2000:7806movdi,6000h
2000:7809movwordptrgs:[di],7789h;saveDecompression_Ngineoffset
2000:780E
2000:780E;checkLZHheader
2000:780Eaddbx,12h;LZH-headerdecomp_seg_addr_hi_byteindex
2000:7811callFetch_Byte
2000:7814subbx,12h;restorebxtopointtofirstbyte
2000:7817cmpal,40h;'@';isextensioncomponent?
2000:7817;at1st:alequ50h(original.tmp)
2000:7817;at2nd:alequ41h(awardext.rom)
2000:7819jnzshortnot_extension_component;1st-passjmptaken
2000:781Baddbx,11h
2000:781EcallFetch_Byte;fetch"dest_seg_addr"lo_byte
2000:7821subbx,11h;restorebxtopointtofirstbyte
2000:7824oral,al;ifextensioncomponent,jmptaken
2000:7826jnzshortextension_component
2000:7828cmpdwordptrgs:[di+4],0;cmpdword[0000:6004]:0
2000:7828;1stpassfromoriginal.tmp,[0000:6004]=FFFFh
2000:7828;(programmedbyPOST_8Sinoriginal.tmppriortocallingthisengine)
2000:782Ejnzshortnot_extension_component
2000:7830extension_component:;CODEXREF:Decompression_Ngine+9D
2000:7830movzxdx,al;dl="dest_seg_addr"lo_byte
2000:7833incbx;bx=LZH_hdr_chksumbyteindex
2000:7834callFetch_Byte
2000:7837subal,dl;LZH_hdr_chksum=LZH_hdr_chksum-"dest_seg_addr"_lo_byte
2000:7839callPatch_Byte;storenewchecksum
2000:783Cdecbx;restorebx
2000:783Dxoral,al;al=00h
2000:783Faddbx,11h;bx="dest_seg_addr"_lo_byteindex
2000:7842callPatch_Byte;patch"dest_seg_addr"_lo_byteto00h
2000:7845subbx,11h
2000:7848incdx;dx="dest_seg_addr"_lo_byte+1
2000:7849shldx,2;dx=4*("dest_seg_addr"_lo_byte+1)
2000:784Cadddi,dx;di=6000h+dx--lookabove!
2000:784Emovgs:[di],bx;0000:[di]=compressed_offset_addr
2000:7851movcx,es
2000:7853movgs:[di+2],cx;0000:[di+2]=compressed_seg_addr>>0xC(hi_wordofsrcphyaddr)
2000:7857callFetch_Byte;al=LZH_hdr_len
2000:785Amovzxecx,al;ecx=LZH_hdr_len
2000:785Eaddbx,7
2000:7861callFetch_Dword;eax=compressed_file_size
2000:7864subbx,7
2000:7867addecx,eax;ecx=LZH_header_len+compressed_file_size
2000:786Aaddecx,3;ecx=total_compressed_component_size
2000:786Epopgs
2000:7870assumegs:nothing
2000:7870jmpexit
2000:7873;---------------------------------------------------------------------------
2000:7873not_extension_component:;CODEXREF:Decompression_Ngine+90
2000:7873;Decompression_Ngine+A5
2000:7873popgs
2000:7875callMake_CRC16_Table
2000:7878callRead_Header;fetchheadercomponenttoscratchpad_seg,onerrorCF=1
2000:787Bjbexit;retwitherrorcodeset
2000:787Fmovax,ds:108h;movax,decomprss_seg_addr
2000:7882movds:104h,ax;movnu_decomprss_seg_addr,ax
2000:7885movax,ds:10Ah;movax,decomprss_offst_addr
2000:7888movds:106h,ax;movnu_decomprss_offst_addr,ax
2000:788Bmovecx,ds:310h;ecx=compressed_component_size
2000:7890xoreax,eax
2000:7893moval,ds:571Ch;al=LZH_hdr_len
2000:7896addecx,eax;ecx=compressed_cmpnnt_size+LZH_hdr_len
2000:7899addecx,3;ecx=compressed_cmpnnt_size+LZH_hdr_len+
2000:7899;sizeof(EOF_byte)+sizeof(LZH_hdr_len_byte)+
2000:7899;sizeof(LZH_hdr_8bit_chk_sum)
2000:7899;i.e.ecx=overall_component_len
2000:789Dmovedx,ds:314h;movedx,original_file_size
2000:78A2pushedx
2000:78A4pushecx
2000:78A6pushbx
2000:78A7addbx,5;pointtoLZHIDbyte
2000:78AAcallFetch_Byte
2000:78ADpopbx
2000:78AEcmpal,'0';is'-lh0-'?
2000:78B0jnzshortdecompress_part
2000:78B2pushds
2000:78B3pushsi
2000:78B4pushbx
2000:78B5movdi,ds:10Ah
2000:78B9movzxax,byteptrds:571Ch
2000:78BEaddax,2
2000:78C1addbx,ax
2000:78C3movcx,ds:310h
2000:78C7movax,ds:108h
2000:78CAmoves,ax
2000:78CCaddcx,3
2000:78CFshrcx,2
2000:78D2next_dword:;CODEXREF:Decompression_Ngine+151j
2000:78D2callFetch_Dword
2000:78D5addbx,4
2000:78D8stosd
2000:78DAloopnext_dword
2000:78DCpopbx
2000:78DDpopsi
2000:78DEpopds
2000:78DFjmpshortLZH_hdr_OK
2000:78E1;---------------------------------------------------------------------------
2000:78E1decompress_part:;CODEXREF:Decompression_Ngine+127
2000:78E1pushwordptrds:104h;savedestinationsegaddr
2000:78E5pushwordptrds:106h;savedestinationoffsetaddr
2000:78E9pushlarge[dwordptrds:314h]
2000:78EEcallLzh_Expand;Lzh_Expandcapableofhandlingcompressed
2000:78EE;componentbiggerthan64KB(1segment)
2000:78F1popdwordptrds:314h
2000:78F6popwordptrds:106h
2000:78FApopwordptrds:104h
2000:78FELZH_hdr_OK:;CODEXREF:Decompression_Ngine+156
2000:78FEcallZero_Init;zeroinit32KBofscratchpad_seg
2000:7901popecx
2000:7903popedx
2000:7905clc
2000:7906exit:;CODEXREF:Decompression_Ngine+E7
2000:7906;Decompression_Ngine+F2
2000:7906popes
2000:7907popbx
2000:7908popeax
2000:790Aretn
2000:790ADecompression_Ngineendp
________________________________________
这个用红线标记的一行写入“signatures”到内存。比如,nnoprom.bin部分用id:4027h定义。这个例程中,nnoprom.bin的索引就要被保存。这个索引的计算方法如下(也是上面代码所看到的算法):
index=4*(lo_byte(ID)+1)
这个所引用来计算地址来保存信息或者签名。再nnoprom.bin里,索引是A0h(从[4*(27h+1)])。所以,保存了信息的这个地址开始与60A0h。就像你上面看到的,第一个保存的信息是有压缩的“Extension_BIOScomponents”这个部分的偏移地址。它被保存在地址60A0h(fornnoprom.bin)。然后,临时“压缩/解压段地址”保存在60A2h(fornnoprom.bin)。对所有的“扩展bios部分”,这个临时的“压缩/解压段地址”经常是4000h,就像你上面看到的代码那样(这个临时的被解压段的值修改成了4000h,在被保存到RAM之前)。这个相同的进程就为其他的所有“扩展bios部分”执行完成了。
d.下一步,original.tmp(post执行期间)中的POST_8S负责准备为解压缩必须的签名,如下面你所看到的:
________________________________________
E000:17B8POST_8Sprocnear
.........
E000:183FBE0000movsi,0
E000:18428EDEmovds,si
E000:1844assumeds:nothing
E000:1844BE0070movsi,7000h
E000:18478B4404movax,[si+4];ax=FFFFh(0000:7004hfilledbeforebyDecompress_System_BIOS
E000:1847;duringbootblock_in_RAMexecution)
E000:184ABF0000movdi,0
E000:184D8EC7moves,di
E000:184Fassumees:nothing
E000:184FBF0060movdi,6000h
E000:185226894504moves:[di+4],ax;[0000:6004]=FFFFh-->signaturetodoLZHdecompression
E000:1852;forextensioncomponents
E000:18563DFFFFcmpax,0FFFFh
E000:18597410jzshortsignature_ok
E000:185B8B04movax,[si]
E000:185D26894504moves:[di+4],ax
E000:18618B4402movax,[si+2]
E000:1864C1E80Cshrax,0Ch
E000:186726894506moves:[di+6],ax
E000:186Bsignature_ok:;CODEXREF:POST_8S+A1
E000:186BE8A26Ccall_init_Pwr_Mgmt_ctlr
E000:186EF8clc
E000:186FC3retn
E000:186FPOST_8Sendp
________________________________________
e.下一步,例程init_nnoprom_rosupd(这只是一个例子,其他部分可能会不同)解压缩nnoprom.bin和rosupd.bin,如下面代码:
________________________________________
E000:71C1init_nnoprom_rosupdprocnear;CODEXREF:POST_11S
.........
E000:71CFBFA000movdi,0A0h;'a';nnoprom.binindex
E000:71CF;nnoprom.bin-->4027h;A0h=4h*(lo_byte(4027h)+1h)
E000:71D2E874FCcallnearptrdecompress_BIOS_component;decompressNNOPROM.BIN
E000:71D50F82ED00jbdecompression_error
E000:71D9680040push4000h
E000:71DC1Fpopds;ds=4000h;decompressionresultseg
E000:71DDassumeds:nothing
E000:71DD33F6xorsi,si
E000:71DF680070push7000h
E000:71E207popes;es=7000h
E000:71E3assumees:nothing
E000:71E333FFxordi,di
E000:71E5B90040movcx,4000h
E000:71E8FCcld
E000:71E9F366A5repmovsd;copynnopromdecompressionresultfrom
E000:71E9;seg4000htoseg7000h
E000:71ECBF0300movdi,3
E000:71EF6626813D244E4E4Fcmpdwordptres:[di],'ONN$';match(decompressed)nnoprom.binsignature
E000:71F70F85CB00jnzdecompression_error
E000:71FB68F89Fpush9FF8h
E000:71FE07popes;es=9FF8h
E000:71FFassumees:nothing
E000:71FF33FFxordi,di
E000:7201B96800movcx,68h;'h'
E000:720432C0xoral,al
E000:7206F3AArepstosb
E000:7208BFA400movdi,0A4h;'a';ROSUPD.binindex
E000:720BE83BFCcallnearptrdecompress_BIOS_component;decompressROSUPD.bin
E000:720E0F82B400jbdecompression_error
E000:72121Epushds
E000:721306pushes
E000:72140FA0pushfs
E000:72160FA8pushgs
E000:72189ADD5F00F0callds_es_fs_gs_flat_4GB
E000:721D6633F6xoresi,esi
E000:72208EDEmovds,si
E000:7222assumeds:nothing
E000:72228EC6moves,si
E000:7224assumees:nothing
E000:7224680040push4000h
E000:72275Epopsi
E000:722866C1E604shlesi,4;esi=4_0000h(decompressedROSUPD.bin)
E000:722C66BF00001000movedi,100000h
E000:7232668BCBmovecx,ebx
E000:723566C1E902shrecx,2
E000:7239FCcld
E000:723AF3676626A5repmovsdwordptres:[edi],dwordptres:[esi];copydecmprssdROSUPD.BINto1MB
E000:723F0FA9popgs
E000:72410FA1popfs
E000:724307popes
E000:7244assumees:nothing
E000:72441Fpopds
E000:7245assumeds:nothing
E000:724568F89Fpush9FF8h
E000:724807popes
E000:7249assumees:nothing
E000:72496626C70600000000+movdwordptres:0,100000h
E000:72536626C70604000000+movdwordptres:4,40000h
E000:725D6633C0xoreax,eax
E000:7260B800E0movax,0E000h
E000:726366C1E004shleax,4
E000:7267660556710000addeax,7156h
E000:726D6626A30800moves:8,eax
E000:7272B80700movax,7
E000:727526A30C00moves:0Ch,ax
E000:7279B80070movax,7000h
E000:727C26A30E00moves:0Eh,ax
E000:72806633C0xoreax,eax
E000:7283B800E0movax,0E000h
E000:728666C1E004shleax,4
E000:728A6605AA710000addeax,71AAh
E000:72906626A31000moves:10h,eax
E000:729566BE80FF0900movesi,9FF80h
E000:729B6681C600000000addesi,0
E000:72A2B036moval,36h;'6'
E000:72A40Epushcs
E000:72A568B072push72B0h
E000:72A868FDE4push0E4FDh;readCMOSbyte
E000:72ABEA886100E0jmpfarptrFseg_vector
E000:72B0;---------------------------------------------------------------------------
E000:72B08AD8movbl,al
E000:72B2B80000movax,0
E000:72B5E841FEcallnearptrcall_nnoprom_at_7000h;executedecompressednnoprom.bin
E000:72B89Cpushf
E000:72B99Dpopf
E000:72BA720Ajbshortdecompression_error
E000:72BCB80000movax,0
E000:72BF8ED8movds,ax
E000:72C1assumeds:nothing
E000:72C1800EB70403ords:byte_0_4B7,3
E000:72C6decompression_error:;CODEXREF:init_nnoprom_rosupd+14
E000:72C6;init_nnoprom_rosupd+36...
E000:72C66661popad
E000:72C807popes
E000:72C9assumees:nothing
E000:72C91Fpopds
E000:72CAassumeds:nothing
E000:72CAC3retn
E000:72CAinit_nnoprom_rosupdendp;sp=2
________________________________________
E000:6E49--decompress_BIOS_component--
E000:6E49in:di=indextocompressedcomponent(aswrittenat0000:6XXXh)
E000:6E49;---------------SUBROUTINE---------------------------------------
E000:6E49decompress_BIOS_componentprocfar
E000:6E49;CODEXREF:EPA_Procedure+43
E000:6E49;EPA_Procedure+5E...
E000:6E491Epushds
E000:6E4A06pushes
E000:6E4B55pushbp
E000:6E4C57pushdi
E000:6E4D56pushsi
E000:6E4E81E7FF3Fanddi,3FFFh;cleardi'sMSB
E000:6E52FAcli
E000:6E53B0FFmoval,0FFh;enablecache
E000:6E55E814FEcallF0_init_cpu_cache
E000:6E586800E0push0E000h
E000:6E5B68696Epush6E69h
E000:6E5E6831ECpush0EC31h
E000:6E6168D4E3push0E3D4h;mod_A20_access_mode
E000:6E64EA30EC00F0jmpfarptrF000_Vector
E000:6E69;---------------------------------------------------------------------------
E000:6E69E82F7Dcallds_ss_Enter_Voodoo_Mode
E000:6E6C8CD8movax,ds
E000:6E6E8EC0moves,ax;es=voodoomode,baseat0000_0000h
E000:6E70assumees:nothing
E000:6E70E8457Dcallss_Leave_Voodoo_mode
E000:6E735Apopdx;dx=si
E000:6E7458popax;ax=di-->compressedcomponentindex
E000:6E7526668B9D0060movebx,es:[di+6000h];ebx=compressedcomponentphysicaladdr((seg>>0xC)+offset)
E000:6E7B660BDBorebx,ebx;iscompressdcomponentexist?
E000:6E7E0F842E01jzno_cmprssd_component
E000:6E8283FBFFcmpbx,0FFFFh
E000:6E850F842701jzno_cmprssd_component
E000:6E89F6C440testah,40h
E000:6E8C7404jzshortexec_decompress;fornnoprom.bin,jmptaken
E000:6E8EF8clc
E000:6E8FE91F01jmpdecomprss_BIOS_componnt_ret
E000:6E92;---------------------------------------------------------------------------
E000:6E92exec_decompress:;CODEXREF:decompress_BIOS_component+43
E000:6E92268B3E0060movdi,es:6000h;di=Decompression_Ngineoffsetaddr
E000:6E9767668B3500001600movesi,ds:160000h;movesi,[awardext.rom4Bytehdr]
E000:6E9F66F7D6notesi
E000:6EA26766893500000800movds:80000h,esi;modifyds:80000hvalue;restoredbelow
E000:6EAA6681FB00001000cmpebx,100000h;compressed_component_phy_addr>1MB?
E000:6EB17257jbshortabove_1MB;fornnoprom.bin,jmp_not_taken
E000:6EB357pushdi;saveDecompression_Ngineoffset
E000:6EB466BE00000900movesi,90000h
E000:6EBA66BF00001400movedi,140000h
E000:6EC066B900400000movecx,4000h;copyonesegment
E000:6EC6FCcld
E000:6EC767F366A5repmovsdwordptres:[edi],dwordptr[esi]
E000:6ECB66BE00001600movesi,160000h
E000:6ED166BF00000800movedi,80000h
E000:6ED766B900800000movecx,8000h;2segment(128KB)
E000:6EDDFCcld
E000:6EDE67F366A5repmovsdwordptres:[edi],dwordptr[esi];copy2segment(128KB)from16_0000hto8_0000h
E000:6EDE;fordecompressionpurposes
E000:6EE25Fpopdi
E000:6EE366C1CB10rorebx,10h
E000:6EE78EC3moves,bx;es=HI_WORD(phyaddrofcompressedcomponent)
E000:6EE966C1CB10rorebx,10h;restoreebx
E000:6EED268B4F11movcx,es:[bx+11h];cx=decompressionsegmentaddress.
E000:6EED;Thecomponentwillbedecompressedintothissegmentaddress
E000:6EF151pushcx;pushdecompressionsegmentaddr
E000:6EF226FF37pushwordptres:[bx];push(LZHhdrlenandLZHhdrchksum)
E000:6EF5F6C480testah,80h
E000:6EF87436jzshortdecompress;allextensionBIOScomponent-->jmptaken
E000:6EFA26895711moves:[bx+11h],dx
E000:6EFE02CDaddcl,ch
E000:6F0002D6adddl,dh
E000:6F022ACEsubcl,dh
E000:6F0426284F01subes:[bx+1],cl
E000:6F08EB26jmpshortdecompress
E000:6F0A;---------------------------------------------------------------------------
E000:6F0Aabove_1MB:;CODEXREF:decompress_BIOS_component+68
E000:6F0A6681C300000E00addebx,0E0000h
E000:6F1126678B4B11movcx,es:[ebx+11h];cx=targetsegmentaddr(thecomponentwillbe
E000:6F11;decompressedintothissegmnt)
E000:6F1651pushcx
E000:6F172667FF33pushwordptres:[ebx]
E000:6F1BF6C480testah,80h
E000:6F1E7410jzshortdecompress
E000:6F202667895311moves:[ebx+11h],dx
E000:6F2502CDaddcl,ch
E000:6F2702D6adddl,dh
E000:6F292ACEsubcl,dh
E000:6F2B2667284B01subes:[ebx+1],cl
E000:6F30decompress:;CODEXREF:decompress_BIOS_component+AF
E000:6F30;decompress_BIOS_component+BF...
E000:6F3066C1CB10rorebx,10h
E000:6F348EC3moves,bx;es=phy_addr>>0xC(hi_wordofphyaddr)
E000:6F3666C1CB10rorebx,10h;bx=compressedcomponentoffset
E000:6F3A0Epushcs
E000:6F3B68496Fpush6F49h;retaddrbelow
E000:6F3E68FFDFpush0DFFFh
E000:6F41BA0030movdx,3000h;scratch_pad_seg
E000:6F44680020push2000h
E000:6F4757pushdi;callDecompression_Ngine
E000:6F48CBretf
E000:6F49;---------------------------------------------------------------------------
E000:6F496800E0push0E000h
E000:6F4C685A6Fpush6F5Ah
E000:6F4F6831ECpush0EC31h
E000:6F5268D4E3push0E3D4h;disable_A20...
E000:6F55EA30EC00F0jmpfarptrF000_Vector
E000:6F5A;---------------------------------------------------------------------------
E000:6F5AE83E7Ccallds_ss_Enter_Voodoo_Mode
E000:6F5D8CD8movax,ds
E000:6F5F8EC0moves,ax;es-->voodoomode,baseat0000_0000h
E000:6F61E8547Ccallss_Leave_Voodoo_mode
E000:6F646766A100000800moveax,ds:80000h
E000:6F6B67663B0500001600cmpeax,ds:160000h
E000:6F737518jnzshortrestore_header
E000:6F7566C1CB10rorebx,10h
E000:6F798EC3moves,bx
E000:6F7B66C1CB10rorebx,10h
E000:6F7F268F07popwordptres:[bx]
E000:6F82268F4711popwordptres:[bx+11h]
E000:6F8626668B5F0Bmovebx,es:[bx+0Bh]
E000:6F8BEB0Fjmpshortdisable_A20
E000:6F8D;---------------------------------------------------------------------------
E000:6F8Drestore_header:;CODEXREF:decompress_BIOS_component+12A
E000:6F8D26678F03popwordptres:[ebx]
E000:6F9126678F4311popwordptres:[ebx+11h]
E000:6F962667668B5B0Bmovebx,es:[ebx+0Bh]
E000:6F9Cdisable_A20:;CODEXREF:decompress_BIOS_component+142
E000:6F9C6800E0push0E000h
E000:6F9F68AD6Fpush6FADh
E000:6FA26831ECpush0EC31h
E000:6FA56824E4push0E424h;disablegateA20
E000:6FA8EA30EC00F0jmpfarptrF000_Vector
E000:6FAD;---------------------------------------------------------------------------
E000:6FADF8clc
E000:6FAEEB01jmpshortdecomprss_BIOS_componnt_ret
E000:6FB0;---------------------------------------------------------------------------
E000:6FB0no_cmprssd_component:;CODEXREF:decompress_BIOS_component+35
E000:6FB0;decompress_BIOS_component+3C
E000:6FB0F9stc
E000:6FB1decomprss_BIOS_componnt_ret:
E000:6FB1;CODEXREF:decompress_BIOS_component+46
E000:6FB1;decompress_BIOS_component+165
E000:6FB19Cpushf
E000:6FB26653pushebx
E000:6FB46800E0push0E000h
E000:6FB768C56Fpush6FC5h
E000:6FBA6831ECpush0EC31h
E000:6FBD68D4E3push0E3D4h;enablegateA20
E000:6FC0EA30EC00F0jmpfarptrF000_Vector
E000:6FC5;---------------------------------------------------------------------------
E000:6FC5E8D37Bcallds_ss_Enter_Voodoo_Mode
E000:6FC88CD8movax,ds
E000:6FCA8EC0moves,ax
E000:6FCCE8E97Bcallss_Leave_Voodoo_mode
E000:6FCF6766A100000800moveax,ds:80000h
E000:6FD667663B0500001600cmpeax,ds:160000h
E000:6FDE752Bjnzshortexit
E000:6FE066BF00000800movedi,80000h
E000:6FE666B900400000movecx,4000h
E000:6FEC6633C0xoreax,eax
E000:6FEFFCcld
E000:6FF067F366ABrepstosdwordptres:[edi]
E000:6FF466BE00001400movesi,140000h
E000:6FFA66BF00000900movedi,90000h
E000:700066B900400000movecx,4000h
E000:7006FCcld
E000:700767F366A5repmovsdwordptres:[edi],dwordptr[esi]
E000:700Bexit:;CODEXREF:decompress_BIOS_component+195
E000:700B6800E0push0E000h
E000:700E681C70push701Ch
E000:70116831ECpush0EC31h
E000:70146824E4push0E424h;turnoffGateA20
E000:7017EA30EC00F0jmpfarptrF000_Vector
E000:701C;---------------------------------------------------------------------------
E000:701C665Bpopebx
E000:701EB000moval,0;disableCPUcache
E000:7020E849FCcallF0_init_cpu_cache
E000:70239Dpopf
E000:70245Dpopbp
E000:702507popes
E000:70261Fpopds
E000:7027C3retn
E000:7027decompress_BIOS_componentendp;sp=-18h
其他部分的解压和处理与nnoprom.bin和rosupd.bin相似,如上。
通过上面的解释,我们只需要跟随“POSTjumptableexecution”来知道在哪个环境下哪个“执行路径”被bios得到。做完了这个方法,我们就能够做我们喜欢做的hackawardbios。不管怎样,我不准备在这里停止,下面的章节,我要给你呈现一些扩展部分的处理方法,他们很让我感兴趣。
7.2.7.MicrocodeUpdateRoutine
微代码升级历程从POST_9S调用,如下所示:
________________________________________
E000:3BBEinit_microcodeprocnear;CODEXREF:POST_9S+52
E000:3BBEE84E38callis_intel_CPU
E000:3BC1755Fjnzshortexit
E000:3BC366B801000000moveax,1
E000:3BC90FA2cpuid
E000:3BCBBB0020movbx,2000h
E000:3BCE8EDBmovds,bx
E000:3BD0assumeds:_2000h
E000:3BD0BB0090movbx,9000h
E000:3BD33B470Ccmpax,[bx+0Ch]
E000:3BD67505jnzshortdecompress_microcode
E000:3BD8E84800callget_cpu_microcode_ver
E000:3BDB742Cjzshortupdate_microcode
E000:3BDDdecompress_microcode:;CODEXREF:init_microcode+18
E000:3BDD6650pusheax
E000:3BDFBF0800movdi,8;compressedmicrocodeindex(4*(lo_byte(4001h)+1))
E000:3BE2E86432callnearptrdecompress_BIOS_component
E000:3BE56658popeax
E000:3BE77239jbshortexit
E000:3BE966C1EB0Bshrebx,0Bh
E000:3BED668BCBmovecx,ebx
E000:3BF0BB0040movbx,4000h
E000:3BF38EDBmovds,bx;pointtoseg4000h(microcodedecompressionrsult)
E000:3BF5assumeds:nothing
E000:3BF533DBxorbx,bx;initbx
E000:3BF7next_microcode:;CODEXREF:init_microcode+47
E000:3BF73B470Ccmpax,[bx+0Ch]
E000:3BFA7505jnzshortmicrocode_not_match
E000:3BFCE82400callget_cpu_microcode_ver
E000:3BFF7408jzshortupdate_microcode
E000:3C01microcode_not_match:;CODEXREF:init_microcode+3C
E000:3C0181C30008addbx,800h;lengthofonemicrocode
E000:3C05E2F0loopnext_microcode
E000:3C07EB19jmpshortexit
E000:3C09;---------------------------------------------------------------------------
E000:3C09update_microcode:;CODEXREF:init_microcode+1D
E000:3C09;init_microcode+41
E000:3C0966B979000000movecx,79h;'y'
E000:3C0F6633C0xoreax,eax
E000:3C126633D2xoredx,edx;microcodeupdatesign
E000:3C158CD8movax,ds
E000:3C1766C1E004shleax,4
E000:3C1B83C330addbx,30h;'0'
E000:3C1E8BC3movax,bx;eax=linearaddrofthemicrocode
E000:3C200F30wrmsr;startmicrocodeupdate
E000:3C22exit:;CODEXREF:init_microcode+3
E000:3C22;init_microcode+29...
E000:3C22C3retn
E000:3C22init_microcodeendp
8.激昂展望
Hey,ifyou'vereadthisarticlethisfar,youmustbecurious(^__^).Let'stakeabreakabit.Iwanttosaysomefactsthatareridiculous.Well,atleasttome.BIOScodeismeanttobe"twisted"sothatcodediggerlikeuswillfindahardtimetofigureitout.But,yeahhereweare,understandingthebigpicture.Codediggerrulesmyman!Nothingmoredangerousthancuriousity.
It'sfunnytoseethatthecoreLZHdecompressionroutinethatisusedbyawardbioses(atleastv4.51that'sdissectedhere)isjustacomplete"copyandpaste"fromHaruhikoOkumura'sLZHcodethatanyonecanfindintheweb.It'sjustthelanguagethat'sdifferent,Okumura'sisinCwhileaward'sisinx86assembly,thesubroutineswereexactlythesame!
Anotherfactis,Phoenixcodeisverysimilartoaward'scode.Idon'tknowwhois"stealing"who,orperhapsthere'sanothersourcewherebothofthemstealfrom(^__^).Ohno...Iguesstheyarejustdoingreverseengineeringlikemewiththeirtonsofmoney.UnfortunatelyIdon'thavethosetonsofmoneyhe..he..he..
Well,letmestoprantingandcontinuemyworkonAMIBIOS.Iguessweallwaitingforit,right?It'lltakesometimecozI'mverybusy.Ifanyoneofyouwhoreadthisarticlehavedoneitandhadsomethingtosayorwanttoshareyourworkwiththeworld,Ireallykeentoknow.Whydon'twejoinforces,right?mymailaddressisintheendofthisarticle.Iknowsomeofushavedoneit..wejusthaven'tbeenincontactorperhapsit'sbetterifwefindourownway.Timewilltell(-__-)
Greetzgoto:KrisKaspersky,PetrSoucek,Polaris,Havok,Zero,MikeTeddera.k.abpoint,apple_rom,IlfakGuilfanovandmanyotherswhosharetheirknowledgewiththeworld.
9.结束语
WhatI'veexplainedabovepossiblyfartooprematuretobeendedhere.But,IconsiderthisarticlefinishedhereastheBeta5version.Ifyoufollowthisarticlefrombeginningtoend,you'llbeabletounderstandthe"BIGPicture"ofhowtheAwardBIOSworks.Ithinkalloftheissuedissectedhereisenoughtodoanytypeofmodificationyouwishtodowithawardbios.Ifyoufindanymistake(s)withinthisarticleorhaveanysuggestion,pleasecontactmemamanzip@yahoo.com.GoodluckwithyourBIOSreverseengineeringjourney,IhopeyouenjoyitasmuchasIdo(^__^).

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics