找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 27625|回复: 8

[转载]Pinczakko的AwardBIOS逆向工程指导

[复制链接]
发表于 2007-11-16 13:27:03 | 显示全部楼层 |阅读模式
本来自己想写一个,但搜了一下网上,有一个现成的.; T- x) e4 E$ T* d( X  n  m
# `0 |5 d( j1 |1 W# u
关键词: Pinczakko    Award    BIOS    逆向工程    指导  BIOS反汇编
% D. }/ S1 d) U) m来自:[url]http://beiyu.bokee.com/[/url]9 I( E4 I$ }% B
1 |% ?$ Y" ~: o6 F
Pinczakko的AwardBIOS逆向工程指导  ?  _  \) n6 D% m
作者:Pinczakko. d3 Z) y& ~* @' h& Y3 q/ |$ ^
翻译:beiyu [url]http://beiyu.bokee.com[/url]# n4 P& E% d+ b. h
Email: [email]beiyuly@gmail.com[/email], z$ `" @; T7 i' y; r
时间:2006.6.6
2 _# c4 Y6 A* a; V, h) g( {* n0 D/ L5 o" s7 J
ida的使用和最后展望没有翻译,希望有兴趣的朋友能够补上。8 e2 b6 z( L. C5 a; B9 Y7 ?4 Z
( |' @% E% z: @+ O. l3 N+ F/ {8 i( X5 @
目录" f; Y5 k% Z5 A7 P& p  X( ?9 T
Pinczakko的AwardBios逆向工程指导  13 Z% p# ^1 x& i1 C  ~* I  u
1.序言  2, W! O2 }4 p6 K
2.准备工作  2
6 x0 X! @% \9 T) B: L2.1.PCI BUS  3( j9 }( B3 _" y( i  @/ n0 N
2.2.ISA BUS  4
5 K  Z6 c5 p; o6 ^' p0 }# F! V3.一些硬件特性  4
; a0 o0 Q; l' K' n% S3.1. BIOS 芯片地址  5
- t! j9 F+ a* R/ J3.2. 晦涩的硬件接口(Port)  6
* C: q& w/ R, R8 N* _4 E; v3.3. "可重定位" 硬件Port  87 u* a! l$ V3 m# a$ v
3.4. Expansion ROM Handling  9
" ~8 L6 ?: k  S) y. U4.一些软件特性  10' [0 B: Y  t" r' e, ^4 N- C. ~
4.1.call指令特性  107 M0 V) a/ Z8 W4 U* g/ [
4.2. retn Instruction Peculiarity  10
- y; ~" U$ \7 j5 _0 p5. 用到的工具  13
9 R9 [" Z$ Y/ N( g1 ~; q5.1. 我们的需求  134 c+ X' w% s, e2 R1 @/ w4 Y
5.2. IDA Pro技术介绍  13
/ m! Y& i' K) r+ ?2 e0 g1 U5.2.1. IDA Pro介绍  13& u* C% Y' ?) V+ _
5.2.2. IDA Pro Scripting And Key Bindings  19/ G/ F+ e7 l. J/ \2 t8 ~+ R0 @
6. Award BIOS 文件结构  26( f1 T! ]% Y9 @% [; `# U; V# O
6.1.压缩部分  262 j6 F* d* }0 [3 ~/ U
6.2. 纯二进制部分  27
6 ?" v6 [2 M) k% j3 W) o6.3. 真实系统(Mainboard)中的内存印象  27* j3 c, z* C$ g
7. 反汇编BIOS  288 y/ V+ `1 k) p$ {8 t: p
7.1. Bootblock  29+ `: n/ b- x0 V# f# v8 u) P
7.1.1. "Virtual Shutdown" routine  29$ K( e; J5 c5 V
7.1.2. Chipset_Reg_Early_Init routine  29+ I- X8 \  Y" u/ K
7.1.3. Init_Interrupt_n_PwrMgmt routine  35
& ~7 r& c0 v: `2 h7.1.4. Call To "Early Silicon Support" Routine  36- ^/ O" _% o, X, P' q& h
7.1.5. Bootblock Is Copied And Executed In RAM  37
: n( f) k8 ^" P; a! k6 Q7.1.6. Call to bios decompression routine and the jump into decompressed system bios  39! x/ }5 f  [* F0 i5 u. m
7.1.6.1. Enable FFF80000h-FFFDFFFFh decoding  40
6 }- ]+ h9 ]$ C; `: N1 {# H7.1.6.2. Copy lower 128KB of BIOS code from ROM chip into RAM  40
8 Y+ @, t, P8 s; d0 q! t! T7.1.6.3. Disable FFF8_0000h-FFFD_FFFFh decoding  40
" d3 Z( g- W5 C; L* R3 A( l. S7.1.6.4. Verify checksum of the whole compressed BIOS image  40
: u$ Y0 `$ ?( N, q/ p7.1.6.5. Look for the decompression engine  41& z. M. L2 p+ ]' L" U, e! O$ T
7.1.6.6. Decompress the compressed BIOS components  41
+ |! E5 U% O2 D7.1.6.7. Shadow the BIOS code  60- f3 P  ]4 J  E# P/ ]2 u
7.1.6.8. Enable the microprocessor cache then jump into the decompressed system BIOS  60
3 A6 g4 z9 g" v! K- v7.2. System BIOS a.k.a Original.tmp  61# A: V$ q, n" P/ g
7.2.1. Entry point from "Bootblock in RAM"  61
' y8 ~( g+ j! q3 B6 S, ]7.2.2. The awardext.rom and Extension BIOS Components (lower 128KB bios-code) Relocation Routine  62$ h4 d. V5 s1 A
7.2.3. Call to the POST routine a.k.a "POST jump table execution"  64
$ t& D0 T. G" k8 z, B$ H* i9 [7.2.4. The "segment vector" Routines  680 P( ^8 Q) R* g/ h) M% D
7.2.5. "chksum_ROM" Procedure  728 I; W6 [6 ?8 W1 ]3 X. g, T/ O
7.2.6. Original.tmp Decompression Routine for The "Extension_BIOS Components"  72
* i  D$ m. }. H1 Z4 L6 \# g9 @7.2.7. Microcode Update Routine  90  c% L8 o" R# W* j$ v3 i
8. 激昂展望  92( c* H0 p1 R9 q
9. 结束语  92# i6 G9 ^8 S2 f& f/ p$ k1 ~& i
5 z, G8 k, i3 ~" `  `
1.序言" _1 q- x  L# b. s5 M. }; d2 G
我非常欢迎你能够来实践复杂的Award Bios的代码研究工作。本文不是一篇官方的Award Bios逆向工程的文章,也不是由Award公司内部人员编辑的。我只是一个好奇的普通人,我真的很喜欢搞清楚我的电脑的Bios是怎样工作的。我写这篇文章的是为了公开我的发现和研究,从而回报那些我所犯的错误,都是我在逆向工程进程当中所犯的。你有几个可能性来读这篇文章,也许你是一个老资格的黑客,也许你是一个像我一样的系统程序设计爱好者,也许你只是一个好奇的外行。只有一点是肯定的,你肯定可以从这篇文章有所收获,可以提高你的技巧。无论如何,我已经写了一个准备章节,来保证你吸收这篇文章所具备的知识。
# k* p& y" `; E/ X除非你自己反汇编了Bios的文件,你是不会理解搞清楚BIOS的工作的。  o' ?  {) S8 H+ r1 `
  这篇文章的目的是消除疑惑,定位好你自己,在开始对BIOS的逆向工程工作中,为你提供一个参考。
0 N9 _+ @. J, B/ i2 D2.准备工作3 `6 u! \7 {* X% U: S
  1.我必须承认,这个工作需要x86的知识。
0 l1 ^; f0 g# f  2.保护模式下的编成开发知识。你必须学会怎样让x86机器从实模式转移到保护模式。也就是说,你必须学会初步的x86保护模式OS开发。www.osdever.net是一个很好的学习这方面知识的网站。最重要的事情是保护模式的数据结构是怎样工作的。我的意思是GDT、IDT、x86控制寄存器和段寄存器是怎样工作的,特别是award bios用他们来实现他的奇妙的地方——稍后文章解释。
; w$ ?" R( q7 X0 B  3.什么是x86的不真实模式。他是一个x86机器在真是模式和保护模式之间的的状态——稍后文章解释。( f& k3 ~, O, s$ Y
  4.X86直接硬件编程开发。你需要知道怎样编程直接制硬件,特别是在你主板上面的。你可以联系这个,通过windows上的直接访问硬件程序开发练习。这个不是必需的,但是如果你懂的话,会给你带来很多方便。你也需要知道一些x86总线协议,比如PCI和ISA——稍后文章解释。% n, ~: u- v, k; W. [7 r/ @5 V" O5 h
  5.你必须理解大部分你的主板芯片的手册。比如北桥和南桥控制寄存器。/ r6 }  z7 x5 z; N
2.1.PCI BUS- [6 j3 Q( I: \6 F- J! ]& M  Q( @
  官方的PCI总线标准系统是由PCISIG(PCI Special Interest Group)维持的。他可能是某种公司,他介于Intel和其他大公司,比如Microsoft。他将要被Arapahoe (PCI-Express a.k.a PCI-e) and Hypertransport代替。但是PCI曾经是在保持一种标准。Hypertransport向后兼容PCI。Arapahoe也是一样。只是这个PCI的标准是没有公开的。& ]! J5 T: y8 ~/ L/ `: y8 J
  首先,PCI BUS是一个32位宽度的总线。通讯需要32bit的地址模式。读写操作需要32位地址。64位PCI Bus不是天生就是,他使用了双重地址回路实现。所以你可以说PCI就是一个32位总线的系统。
& G7 |$ J: g& }  M  其次,这个总线系统定义位置是,控制端口PORT CF8h – CFBh,数据端口CFCh – CFFh。这些端口用来配置相应的PCI芯片,比如读写PCI芯片的配置寄存器值。
9 {3 c8 M' \5 l6 m  第三,这个总线系统强制我们和PCI通讯需要遵守下面的法则(从用户CPU观点):8 [  L" b3 Q7 @, C
1.  写目标总线号,设备号,功能号和偏移/寄存器号到配置地质端口,然后使能bit置1。通俗讲就是,写寄存器的地址到你想要写入的PCI地址端口。
% ^; [, X2 q( C2 s' W; E3 K4 x2.  从一个配置数据端口执行一个one-byte, two-byte, or four-byte I/O读操作或者写操作。通俗讲就是,读写数据从你想要读写的PCI端口。
; w7 o' X9 H/ g: `! ^作为一个提示,据我所知,每一个今天用到的BUS/通讯协议,使用简单的法则来使芯片互相通讯,而这些芯片有一个复杂的总线协议。7 I' `) u9 o8 t
有了上面的定义,这里提供一个x86的汇编码片断,来说明怎样使用这些配置端口。
! q& C+ ~0 A# f" E7 v4 i+ g% d  Q! kNo.  Mnemonic (masm syntax)  Comment$ i# z. [1 A  ^
1  Pushad  保存所有通用寄存器的值
# Y; f; d! K$ I0 N2  mov eax,80000064h  把将要访问的PCI芯片寄存器的地址放入eax" M8 F' t# a. H
(offset 64h device 00:00:00 or hostbridge)4 f* M1 |4 W0 Z9 O. x; R# K
3  mov dx,0CF8h  地址端口放入dx。因为是PCI,我们用CF8h作为端口,来打开访问这个设备。
" D. a( p8 {2 \7 |4  out dx,eax  发送PCI地址端口到processor的I/O空间0 d" ]0 T5 |  ?8 O2 G1 X8 c
5  mov dx,0CFCh  数据端口放入dx。因为是PCI,我们用CFCh作为端口,来和这个设备数据通信。7 Y# h" J) `% m" |. Q1 q
6  in eax,dx  将从这个设备读出的数据放入eax
# y# c" x$ V8 A* P8 D0 O, @. W7  or eax, 00020202  改变数据(this is only example, don't try this in your machine, it may hang or even destroy your machine)
' ^/ R, F  D7 b0 x, p. `1 ^" I4 P- ^8  out dx,eax  将数据发送回设备
5 q- L: S5 t, y) H$ g4 W$ T. o9 Y9  ............  -- _5 q$ t1 s( s( w! P; [1 ^
10  Popad  出栈所有寄存器值0 {) p* I) o6 ^8 J! [
11  Ret  返回
$ f; ^( ]: u& u  
0 ]2 Y9 l4 a& t/ T; i9 Q  我想上面的代码已经非常清晰了。这里有一个PCI寄存器地址格式例子:2 k5 \5 `) D* _# o
mov eax,80000064h1 k* G. [0 b- q# }. T

- ^* @2 C, h# @7 K% ^- F2 k% q  the 80000064h is the address. The meaning of these bits are:
7 g6 ]. Z, [% Pbit position  31  30  29  28  27  26  25  24  23  22  21  20  19  18  17  16  15  14  13  12  11  10  9  8  7  6  5  4  3  2  1  0: o) N6 u5 F3 O) @) \
binary value  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  1  0  0  1  0  0
, K- e9 K0 i2 _* [( Qhexadecimal value  8  0  0  0  0  0  6  4
; {3 u" J5 o  P- S?  Bit 31是一个使能标志。如果这个位置设置了,我们就给与PCI bus读写通信的权利了,否则就是禁止。那就是为什么我们在最左边有一个8的原因。6 p6 W% k6 D2 \  H1 w# g6 ?; ~+ X
?  Bits 30 - 24 保留 bits。1 {5 y! U6 A$ i# E+ S' U4 B
?  Bits 23 - 16 是 PCI Bus 号。
0 f4 |$ @- p) H1 c# H?  Bits 15 - 11是PCI 设备号。 . a/ @( b4 _, e4 d4 K) Z/ P
?  Bits 10 - 8 是PCI 功能号。9 }& ]& a* e1 W0 Q; O& B5 s5 a
?  Bits 7 - 0 是偏移地址。
5 O: k$ r& z& k( w80000064h的意思就是我们通讯的设备是bus 0, device 0, function 0, 偏移地址是64h。实际上这个是我们主板上面的北桥芯片中的存储控制配置寄存器。大多数环境下,bus 0, device 0, function 0是Hostbridge,你需要参考自己的芯片数据表来改变这个。大概来讲,他们要作如下工作:读取偏移地址,改写数据,写回设备。7 Q& b7 y$ p& i6 g- q
2.2.ISA BUS
' w6 i9 \0 u$ B  AFAIK(恕我直言),ISA bus 不是标准的总线。因此,实际上任何ISA设备可以存在于系统的16-bit I/O地址空间。我对ISA bus的经验很有限(CMOS chip ,mainboard's hardware monitoring chip- Winbond W83781D)。这两个芯片用了上面提到的PCI bus通用算法:
$ w; t" _9 V5 T' H# Z: m1.  先送出你想要读写的设备的地址。只有那样,你才可以通过这个设备的数据端口发送接收数据。
9 Y- r# V5 T, s. F$ q2.  通过数据端口,发送接收将要通过设备读写的数据。
: k- I! ~) ^, Z/ N( b* J! _8 M) f我的硬件监视芯片用端口295h作为地址端口,296h作为数据端口。CMOS用70h作为地址端口,71h作为数据端口。
+ h" D" ^& M% c+ c3.一些硬件特性1 c/ P9 x2 e$ }6 p, B3 T) Q2 ^
X86平台存在很多hack,特别是他的bios。这个要归功于向下兼容。这章要讨论一对在我BIOS反汇编中遇到的问题。4 b- j8 j  I9 e0 T- J* ~5 q# u
3.1. BIOS 芯片地址
; v! @+ Z. N/ S3 m& [8 {  j/ o  最重要的负责bios代码处理的芯片是南桥和北桥芯片。由于这方面,北桥负责系统地址空间管理,比如bios shadowing,处理访问RAM和处理事务,用bios ROM作为南桥的目标,南桥最后积存bios rom。南桥主要负责使能rom解码控制,这将要寄存要访问的bios rom的存储地址。下面展示的地址可以存在于系统DRAM和bios rom芯片中的任何一个,这取决于在bios代码执行时,南桥和北桥寄存器的设置。" L% |* m# p' L$ j  S
Physical Address  Also Known As  Used by  Address Aliasing Note. n% x% b! M# N4 F0 ?
000F_0000h - 000F_FFFFh   F_seg / F_segment   1 Mbit, 2 MBit, and 4 MBit BIOS   alias to FFFF_0000h - FFFF_FFFFh in all chipset just after power-up
2 Y( E2 v+ O, i! n000E_0000h - 000E_FFFFh  E_seg / E_segment  1 Mbit, 2 MBit, and 4 MBit BIOS  alias to FFFE_0000h - FFFE_FFFFh in some chipset just after power-up # ^, O- |; _, C; d. l
  上面的地址范围包含了bios代码和很多的系统特性。所以你不得不参考你的芯片数据表来理解它。而且,在bios代码运行后的时间里,注意上面的地址要被bios代码占据的是F_seg i.e. F_0000h - F_FFFFh。无论怎样,相当的操作系统可能会认为这段地址没有用,而且会把它用于自己的目的。上面提到的地址只是当bios代码访问或者其他代码直接访问bios rom的时候,反映了bios rom芯片到系统地址空间映射。就像我们要看到的一样,这个映射可以通过程序设计一些芯片寄存器来改变。
& d5 l+ S: [' Q) G. c3 u  超过1m的Bios芯片,比如2m和4m的芯片有一个非常与众不同的低bios区域地址,i.e. C_seg, D_seg和其他低"segment(s)"。大多数情况,这个区域被映射到了靠近4GB地址范围。这个地址范围处理是从类似北桥到PCI地址范围来解决。这个配置下芯片行为如下:
$ q. ~( F3 N* i?  北桥作为一个地址传送装置:在不同方式和普通内存地址比较的状态下,它对这个特别的内存地址有反应,内存地址直接指向RAM。相反,这个特别的内存地址由北桥转到南桥,从而解码。, W2 _' t' U- W7 `9 e3 h
?  南桥作为地址解码器:它解码这个特别的内存地址,这个地址指向正确的芯片,比如bios芯片。这方面,如果地址范围不被允许在南桥控制寄存器解码,南桥要返回“void”(bus地址周期结束)。
' ^' U6 G4 v0 B下面是一个例子: " F. G$ p$ ?4 Z9 K  I8 V% p9 _
Physical Address  Also Known As  Used by  Address Aliasing Note1 K7 ^( }& z9 \# h7 t# _$ l  }9 H
000F_0000h - 000F_FFFFh   F_seg / F_segment   1 Mbit, 2 MBit, and 4 Mbit BIOS   alias to FFFF_0000h - FFFF_FFFFh in all chipset just after power-up 9 B2 E4 }0 q6 E6 ?
000E_0000h - 000E_FFFFh  E_seg / E_segment  1 Mbit, 2 Mbit, and 4 Mbit BIOS  alias to FFFE_0000h - FFFE_FFFFh in some chipset just after power-up $ P# h* E% W# P" l7 n
FFFD_0000h - FFFD_FFFFh  D_seg / D_segment  2 Mbit, and 4 Mbit BIOS  -
5 i+ F& N2 g$ K6 N  iFFFC_0000h - FFFC_FFFFh  C_seg / C_segment  2 Mbit, and 4 Mbit BIOS  - - _6 _/ \, R: I: Q5 o
FFF8_0000h - FFFB_FFFFh  -   4 Mbit BIOS  - $ \, p9 B0 `. Q1 C' U( a

& d9 b: P+ }4 w结论是:现代芯片组表现为效法F_seg and E_seg 处理。这是一个证据,证明现代x86系统保持着向下兼容。无论如何,卖主已经远离x86,这些“杂牌电脑(cludge)”往往被认为是过去的东西。" p* i0 J6 ?+ F1 j. C; T
  下面是在刚刚系统加电启动后,VIA693A芯片组(北桥)系统内存映射,根据芯片数据表。
$ U7 M* m1 K# O5 ^/ OTable 4. System Memory Map
3 I5 G3 k; k; J8 zSpace Start    Size  Address Range      Comment
: W- W* F9 n1 RDOS   0        640K  00000000-0009FFFF  Cacheable
! i0 ?9 P' C+ x& y1 `% O1 v; cVGA   640K     128K  000A0000-000BFFFF  Used for SMM# g4 `! P/ f5 `2 |( A+ T0 ?9 t
BIOS  768K     16K   000C0000-000C3FFF  Shadow Ctrl 1
- L3 S/ m5 i( g$ pBIOS  784K     16K   000C4000-000C7FFF  Shadow Ctrl 1  ]8 c4 V0 w% f- }0 s! ^
BIOS  800K     16K   000C8000-000CBFFF  Shadow Ctrl 1! C1 y$ p( R: `3 q
BIOS  816K     16K   000CC000-000CFFFF  Shadow Ctrl 1, d5 M2 F; o2 i5 s
BIOS  832K     16K   000D0000-000D3FFF  Shadow Ctrl 2
) Z+ b0 T+ f+ K' j; |, FBIOS  848K     16K   000D4000-000D7FFF  Shadow Ctrl 2
3 k/ N" Q6 m7 `, p- U( v3 N. ?BIOS  864K     16K   000D8000-000DBFFF  Shadow Ctrl 2
, \+ V9 B5 D0 s. e3 `BIOS  880K     16K   000DC000-000DFFFF  Shadow Ctrl 2
, C: c* l' e/ W0 p. |( Z, |BIOS  896K     64K   000E0000-000EFFFF  Shadow Ctrl 30 [- t& D, s* H0 _! n* |% [( R
BIOS  960K     64K   000F0000-000FFFFF  Shadow Ctrl 3
. w: V  p- l8 a/ `Sys   1MB      ?    00100000-DRAM Top  Can have hole
# E1 c: \# a$ Q" N. \% OBus   D Top          DRAM Top-FFFEFFFF
( o0 W6 J/ `9 K2 h5 W' HInit  4G-64K   64K   FFFEFFFF-FFFFFFFF  000Fxxxx alias) \( b6 D0 ]2 M" y4 i: a2 N
  最重要的要考虑到的东西是地址别名,比如你看到的FFFE_FFFFh- FFFF_FFFFh范围就是000Fxxxxh别名,这个就是bios rom芯片地址映射的地方(我得主板)。但是,我们不得不认为,这个是在启动阶段最初的时候(reset后)。在芯片重新被bios改编程序后,这个地址范围就会映射到了RAM中。我们认为这个是作为加电启动默认值。作为一个标记,主要的x86芯片用这个地址作为别名,至少是F-segment地址范围。) X0 u- `5 {; F+ ~5 m
  另外一个事实就是我们不得不考虑:大部分芯片组在加电后,寄存器中,只提供默认F-segment地址配置,其他bios rom段保持不可访问。这些段的地址配置将要少后由bootblock代码在改变了相关芯片组寄存器后配置(大部分是南桥寄存器)。这里研究的芯片属于这个组。
) y- X. H. a3 f2 `3 J* x: Z, o  现代系统连接bios rom芯片和南桥芯片是通过LPC(Low Pin Count)接口。无论怎样,本文中的南桥没有这样的接口。它是一个老的芯片,使用ISA bus作为和bios rom的接口。
* X5 C2 `  j- @( o6 ]1 Q, `3.2. 晦涩的硬件接口(Port)
5 B" a, v  ~" `) D/ l5 r  下面提到的一些晦涩的硬件接口没有在芯片数据文档提到。注意,这些信息是从Intel ICH5,VIA 586B和VIA596B的数据表中得到。4 B! k8 A! O. ?- Y% q" A
I/O Port address     Purpose! |6 \) x" ?* G
92h                  Fast A20 and Init Register
/ c; G/ H& o9 E% k1 J+ L" H. M% H4D0h                 Master PIC Edge/Level Triggered (R/W)
+ e1 v5 q- J5 b% y4D1h                 Slave PIC Edge/Level Triggered (R/W)
0 m& I9 w; z1 R! u1 D, c- k& ^
, J. n- f2 t( C3 N0 @Table 146. RTC I/O Registers (LPC I/F桪31:F0)
/ m8 l) p: V' d( ]$ ?, XI/O Port Locations    If U128E bit = 0            Function9 m' m& N6 i# y; `
70h and 74h           Also alias to 72h and 76h   Real-Time Clock (Standard RAM) Index Register; E5 i, N( w2 @5 b# N5 Y- V
71h and 75h           Also alias to 73h and 77h   Real-Time Clock (Standard RAM) Target Register
$ B" `4 H) Q; k- O" o72h and 76h                                       Extended RAM Index Register (if enabled)4 g$ T/ `9 ^) e' R* c
73h and 77h                                       Extended RAM Target Register (if enabled)( A3 c5 n' G7 e1 [. K. e, X3 ]

. g5 ]2 C9 Y' y7 `. i# I注意:4 l1 @* T: v! }- P* K: d. a- k
1.  I/O位置的70h和71h是标准的服务于真实时间时钟的ISA接口。表格147所示。72h和73h作为访问扩展RAM。扩展RAM单元的访问依然通过索引配置。I/O地址72h作为地址指针,73h作为数据寄存器。索引地址127h以上不可用。如果不需要扩展RAM,它就变得不可用了。4 C5 _: X0 t" J  ?: y1 o- G8 l/ p: `& i
2.  软件比如保留地址70h的bit7。当顺序写入这个地址的时候,软件必须先读出这个位置的值,然后写入现同的值到bit7。注意70h不是可以直接读取的。唯一的方法是通过alt访问,读取相应寄存器的值。如果NMI#(不可屏蔽中断)使能没有在普通操作下改变,那么软件能够二者选一的读取这个bit一次,然后保留这个值,一边随后的所有写入端口70h操作。
  x4 `1 b( n9 Y! w  z; N' x7 h2 c4 a2 \! Y4 A& G6 [. {
RTC(通路控制)包含了两个索引寄存器配置,用于被两个分离索引和目标寄存器(70/71h or 72/73h)访问,如147表格所示。
) X1 Q: k7 b' y9 A" [2 w$ v- }% r9 ?5 ?1 o
Table 147. RTC (Standard) RAM Bank (LPC I/F桪31:F0)
' V& T9 z+ f9 k) M$ AIndex   Name$ F  P: F- k! J! X3 |5 @
00h     Seconds
: n* w; F, j7 {$ |* m01h     Seconds Alarm6 T% J! `. V1 E6 s7 J  \# N
02h     Minutes
0 r4 L* E; {$ ?+ R/ }6 E+ X0 r03h     Minutes Alarm
% r+ n6 s4 b$ E04h     Hours7 Q& f  z# Q7 J# S' T
05h     Hours Alarm% o" d0 D: ?* p3 T$ X) ?
06h     Day of Week8 B% A) C3 u) P$ U3 R
07h     Day of Month
5 b* O' w) J' K8 p0 ^08h     Month
/ V3 S& k9 `! s( i5 O09h     Year
6 C, k! t3 r% m' }( C0Ah     Register A1 ~+ `3 w+ q- B! Q2 Z( E6 z( U
0Bh     Register B
/ z# U; T& E7 l! V' C0Ch     Register C: j  y. c: t( A" L, L
0Dh     Register D
5 I% }- \" c0 o3 v+ v( U0Eh?Fh 114 Bytes of User RAM
% g" c+ l) y7 m
: g& j' C3 W. A0 ^  A- V1 A) M6 _! |4 ^3.3. "可重定位" 硬件Port0 d1 x+ o) K6 V" P
  系统I/O空间中,有一些硬件端口种类可以重定位。在这个bios,那些端口包括smbus-related端口和电源管理相关端口。这些端口当然是基本地址。这些所谓的基本地址是通过可以编程的基址寄存器控制的。Smbus由smbus基址寄存器,电源管理由电源管理I/O基址寄存器。所以这些端口是可编程的,bootblock历程在bios历程执行开始的时候初始化这些地址寄存器的值。由于这些端口的可编程特性,就必需要开始bios bootblock的逆向工程来查出哪个端口地址用来这些可编程硬件端口。否则,就会搞不清楚稍后逆向工程中怪异端口的事件。例如:; o8 x: y/ c9 _# k: h, Y
Address    Hex                  Mnemonic/ ]; u. }6 q2 @( f5 R& k' x! D" C
F000:F604 BE C4 F6                  mov   si, 0F6C4h          ; addr of chipset reg mask" ^6 I0 e0 }' u3 J
F000:F607                         next_PCI_reg:               ; CODE XREF: Chipset_Reg_Early_Init+290 K0 @6 o/ f6 g+ v7 `. z+ Y
F000:F607 2E 8B 0C                  mov   cx, cs:[si]: E+ V! y0 b$ Z: K- X
F000:F60A BC 10 F6                  mov   sp, 0F610h) I* I' N& s( \
F000:F60D E9 F8 00                  jmp   Read_PCI_Byte
- v. L4 i9 u$ E6 p/ Q. {F000:F60D                         ; ---------------------------------------------------------------------------0 q6 F) c9 {$ c  T' e( m
F000:F610 12 F6                     dw 0F612h
1 w* l6 \; ^0 ~$ c* zF000:F612                         ; ---------------------------------------------------------------------------
+ N: f- d. R0 M, W$ M% ]6 W* OF000:F612 2E 22 44 02               and   al, cs:[si+2]5 w. q6 h' t, a1 r8 n6 {( e
F000:F616 2E 0A 44 03               or    al, cs:[si+3]+ o' l0 H' `1 S9 @( {
F000:F61A BC 20 F6                  mov   sp, 0F620h8 p1 E0 R7 w9 ^
F000:F61D E9 02 01                  jmp   Write_PCI_Byte
4 X/ L+ K1 m2 D$ e7 dF000:F61D                         ; ---------------------------------------------------------------------------4 Z% D( n, I+ v: g% ?5 Q# |' t: M
F000:F620 22 F6                     dw 0F622h
  s7 ^7 Z$ `7 Z3 E* ?" HF000:F622                         ; ---------------------------------------------------------------------------+ |; M5 _2 j; Y( ?2 ~, O" k
F000:F622 83 C6 04                  add   si, 48 @& d/ k; y+ ~; x8 H
F000:F625 81 FE 04 F7               cmp   si, 0F704h          ; are we done yet?3 I9 `7 A: Y0 Z6 H9 K
.........0 q0 Y  k: N8 d4 s; t
F000:F6F4 48 3B                     dw 3B48h                  ; B#0 D#7 F#3: PwrMngmt&SMBus - PwrMngmt IO Base Addr lo_byte! `3 z: ?" T" Y- D% L$ c9 N, f
F000:F6F6 00                        db 0                      ; and mask
2 b) I) r6 L+ V5 D" `F000:F6F7 00                        db 0                      ; or mask& M; A" T: k: X+ T0 [9 E9 z
F000:F6F7                                                     ;& H8 y5 q! g6 i! @) c% J1 Y
F000:F6F8 49 3B                     dw 3B49h                  ; B#0 D#7 F#3: PwrMngmt&SMBus - PwrMngmt IO Base Addr hi_byte
; E$ g1 I! W  d; j, N  d9 UF000:F6FA 40                        db 40h                    ; and mask8 o, O& F% @6 R9 p3 F% m
F000:F6FB 40                        db 40h                    ; PwrMngmt IO Base Addr = IO Port 4000h
" W# ]1 H5 E9 u% _: Q.........
* A& u5 t" ]6 p0 W/ i7 JF000:F643 B9 90 3B                  mov   cx, 3B90h           ; B#0 D#7 F#3: PwrMngmt&SMBus - SMBus IO Base Addr lo_byte  k# a7 [; x$ K' J& V" z
F000:F646 B0 00                     mov   al, 0               ; set SMBus IO Base lo_byte to 00h
4 W0 p9 O7 E* G8 ^% j( w9 }F000:F648 BC 4E F6                  mov   sp, 0F64Eh: C0 F. Y8 Y+ ~% A$ \  j0 K
F000:F64B E9 D4 00                  jmp   Write_PCI_Byte
/ a! W( `/ @! D. AF000:F64B                         ; ---------------------------------------------------------------------------
4 O% H! b, y) g$ k7 W; P: dF000:F64E 50 F6                     dw 0F650h
# Y4 F! l1 J1 R, ~+ lF000:F650                         ; ---------------------------------------------------------------------------
4 R. V+ ~* J0 b# LF000:F650 B9 91 3B                  mov   cx, 3B91h           ; B#0 D#7 F#3: PwrMngmt&SMBus - SMBus IO Base Addr hi_byte" P) L3 u% y" @: w
F000:F653 B0 50                     mov   al, 50h ; 'P'       ; set SMBus IO Base hi_byte to 50h,  s0 g+ i! x5 M+ c8 i: n9 o7 H8 f
F000:F653                                                     ; so, now SMBus IO Base is at port 5000h !!!
% S/ E7 `# C' h  C- }F000:F655 BC 5B F6                  mov   sp, 0F65Bh
! o' k+ S0 z9 m1 x. mF000:F658 E9 C7 00                  jmp   Write_PCI_Byte3 |9 l; }6 U$ t0 V- {
F000:F658                         ; ---------------------------------------------------------------------------
' b; h' t/ }: s8 uF000:F65B 5D F6                     dw 0F65Dh: j5 N( T0 u/ g% [% z
.........6 ?/ D5 e0 G& q% f6 b" T
F000:F66A BA 05 40                  mov   dx, 4005h           ; access ACPI Reg 05h
7 ?  e. R, D% ?' l. v& f3 W: q' AF000:F66D B0 80                     mov   al, 80h ; '?       ; setting reserved bit?# l& L2 Z8 {9 q- l) d* R
........./ i' J+ p) i! ~, R; d
  当然,还有更多的可重定向硬件端口,但是至少你已经看到了这些提示。所以,一旦逆发现bios中的代码有点象访问怪异的端口,你将会知道它去哪里。9 S) V* O& O# x0 W8 W8 Q' \! ^
3.4. Expansion ROM Handling
* j+ o- L; i& u/ _1 H4 ]7 x  有一对问题需要考虑到,比如video bios和其他扩展rom处理。这里是基本bios中PCI扩展rom处理run-down:7 h1 X" z% d( G" T" \0 \. O+ T7 p. k
1.  系统bios检测所有的系统中的pci芯片,初始化他们的BARs(基址寄存器)。一旦初始化结束,系统就拥有了一个可用的广阔的系统地址配置。
9 B$ ?  A4 o" m" l# F2.  通过广阔的系统地址配置,系统bios一个接一个的拷贝需要的PCI扩展rom到RAM,这些扩展在(C000:0000h - D000:FFFFh),并且执行每一个模块或者初始化每一个模块。/ P/ f8 g2 f. @
至于ISA扩展rom,以后版本文章会讨论。
+ N4 ~+ U2 I; M- }* l, X4.一些软件特性
! f! L. a, ]& i, Y  在bios代码中有一些棘手的区域和rom中一些可执行部分有关。下面介绍:
9 o2 Y, _. }5 t7 H5 r9 e( ?' b% M/ ^4.1.call指令特性
. {2 P9 w0 R* s3 v! M  Call指令在rom bios芯片内部的bios代码执行时不可用。这由于call指令使用桟,而我们不能在bios rom中写入来使用桟。这里使用桟是因为要压入call指令执行时写入保存的返回地址。我们很清楚的知道,这个时候地址指针ss:sp指向的时rom:我们不能写入。DRAM这个时候不能使用。它还没有被bios代码检测。我们根本就不知道有RAM存在!; d6 M$ B% Y; k4 A  o& q8 Y$ r% J
4.2. retn Instruction Peculiarity3 s2 i8 S8 n: _' u( D6 _/ o
  Retn指令特性,这里有ROM_call宏定义:0 z0 B* ^4 D7 {$ [
ROM_CALL  MACRO    RTN_NAME% {3 M% ~0 T) N+ A4 X
      LOCAL    RTN_ADD7 z; W3 S3 R' ~
      mov  sp,offset   DGROUP:RTN_ADD" u0 C; l: }# B: k
      jmp      RTN_NAME
, f6 \2 T! N& qRTN_ADD:  dw      DGROUP:$+2
# B( P0 k* j3 @            ENDM' X8 q$ P' l8 _: y
例子:
" s/ x  m3 m  }/ M3 ], N0 yAddress    Hex                  Mnemonic
7 o# \0 z# D- ^1 B" }1 @. A9 ~% AF000:6000                       F000_6000_read_pci_byte proc near  3 e0 e$ U$ s1 D
F000:6000   66 B8 00 00 00 80   mov   eax, 80000000h% i9 W0 D. `$ y3 `* e
F000:6006   8B C1               mov   ax, cx          ; copy offset addr to ax; a1 e- }( j. f8 v& q" F) t+ A: f; U
F000:6008   24 FC               and   al, 0FCh        ; mask it# }! |4 O6 ~6 x* u  e
F000:600A   BA F8 0C            mov   dx, 0CF8h2 g5 f/ ~( |4 C  N7 C. G* j
F000:600D   66 EF               out   dx, eax1 j: c4 R  T) a/ Y. H5 }  y
F000:600F   B2 FC               mov   dl, 0FCh
: @: H" J- A5 Y$ C3 `, [0 S1 b4 [8 _+ PF000:6011   0A D1               or    dl, cl          ; get the byte addr
0 ~, q2 i6 d: b) E' V- H! bF000:6013   EC                  in    al, dx          ; read the byte+ c- H1 `) k7 C1 c+ [
F000:6014   C3                  retn                  ; Return Near from Procedure1 L8 {! l- i/ {5 _
F000:6014                       F000_6000_read_pci_byte endp
) A5 i0 h. O, Y0 q0 z! B% s......$ p( F; P* C) E( C3 ?9 s- M, t
F000:6043 18 00                   GDTR_F000_6043 dw 18h   ; limit of GDTR (3 valid desc entry)
% o3 R6 P$ \3 U. y' U0 }F000:6045 49 60 0F 00               dd 0F6049h            ; GDT physical addr (below)- j6 ]0 l% G! e$ H/ [& W  K; y
F000:6049 00 00 00 00 00 00 00 00   dq 0                  ; null descriptor
. h% J+ w, J& W/ ^( M6 Z9 Y( C5 k4 ]F000:6051 FF FF 00 00 0F 9F 00 00   dq 9F0F0000FFFFh      ; code descriptor:
( H0 f( X  _. F- |& M$ tF000:6051                                                 ; base addr = F 0000h; limit=FFFFh; DPL=0;
4 x; m1 _. n" v4 J6 _9 BF000:6051                                                 ; exec/ReadOnly, conforming, accessed;
% |# z  D3 B8 I7 F: l- u2 m  {F000:6051                                                 ; granularity=byte; Present; 16-bit segment3 F: T  E& \( p6 l' S
F000:6059 FF FF 00 00 00 93 8F 00   dq 8F93000000FFFFh    ; data descriptor:% s5 }- Q2 S* Y$ p
F000:6059                                                 ; base addr = 00h; seg_limit=F FFFFh; DPL=0;
. D- p2 A2 D2 H1 e( u9 f: @& DF000:6059                                                 ; Present; read-write, accessed;
$ O7 W; Q' P* k7 w; CF000:6059                                                 ; granularity = 4 KByte; 16-bit segment0 v5 _: X, o9 ^
......
5 |) l- U2 v- KF000:619B 0F 01 16 43 60        lgdt  qword ptr GDTR_F000_6043 ; Load Global Descriptor Table Register" z0 G' O$ M. e/ q0 S
F000:61A0 0F 20 C0              mov   eax, cr0
, V: l3 J8 d+ IF000:61A3 0C 01                 or    al, 1           ; set PMode flag; D3 x$ N. Z" I& ]4 l  Q3 M/ b
F000:61A5 0F 22 C0              mov   cr0, eax
! c8 \- \; }9 B: _0 UF000:61A8 EA AD 61 08 00        jmp   far ptr 8:61ADh ; jmp below in 16-bit PMode (abs addr F 61ADh)
$ O4 W: A: K  ]7 k: {4 lF000:61A8                                                 ; (code segment with base addr = F 0000h)+ r( K% a) a) z/ x2 b5 ?, M" r4 C, l
F000:61AD                       ; ---------------------------------------------------------------------
1 K$ V7 d: U/ o$ c0 I: M0 uF000:61AD B8 10 00              mov   ax, 10h         ; load ds with valid data descriptor
1 u+ o/ J4 E$ a4 bF000:61B0 8E D8                 mov   ds, ax          ; ds = data descriptor (GDT 3rd entry)4 d1 a3 o; N0 g% s" }2 z$ X
......
% c/ i) v4 Q& @  Y* g) EF000:61BC  B9 6B 00             mov   cx, 6Bh         ; DRAM arbitration control
  {% N: h4 p& ^! D. _6 s, k" uF000:61BF  BC C5 61             mov   sp, 61C5h
1 m* J* w% t$ d; ^& }8 tF000:61C2  E9 3B FE             jmp   F000_6000_read_pci_byte ; Jump. T' B, b* T# z+ W2 w0 [/ k) j. @" P
F000:61C2                       ; ------------------------------------------------------------------+ a2 n2 q5 e- s
F000:61C5  C7 61                dw 61C7h
5 E, K! q! h  z4 b* o0 AF000:61C7                       ; ------------------------------------------------------------------1 t7 x3 ~4 R* D" F+ u
F000:61C7  0C 02                or    al, 2           ; enable VC-DRAM
/ `4 ^/ r! l  V: w- J6 O' e3 }* G6 G  你看到的,必需要考虑retn指令被当前ss:sp寄存器值影响,ss寄存器还没有加载到正确的16-bit保护模式使用!这些代码怎么会执行?答案有点复杂。让我们看看ss寄存器的值,它在上述调用之前就巧妙的处理了。
. a' e) Z0 h. RAddress    Hex                  Mnemonic6 j  v! o2 G6 V/ R8 A6 n
F000:E060 8C C8                 mov   ax, cs2 s6 r( R8 |9 d( U  r& p% g3 @2 u% e% Z7 d
F000:E062 8E D0                 mov   ss, ax          ; ss = cs (ss = F000h a.k.a F_segment)
) z) t0 k3 r- \4 }F000:E064                       assume ss:F000
0 X" {$ i2 h. w$ o/ W$ ONote: this routine is executed in real-mode9 l4 {4 f0 b9 g" c
  就如你看到的,ss寄存器装入了f000h(当前bios代码16-bit段在实模式)。这段代码说明隐藏的描述缓存寄存器(存在为每一个选择/段寄存器)被加载入ss*16 or F_0000h 的物理地址值。并且这个值会返回,尽管机器转变成了上述的16-bit保护模式,因为ss寄存器没有重载。Intel Software Developer Manual Vol.3片断:
& t) ^# P6 E5 Z. y4 z  ) [; J% o+ J/ q: j) x( O1 }
8.1.4. First Instruction Executed0 s; N  t# U; ^$ q6 A+ ?8 N# Q! A, T
The first instruction that is fetched and executed following a hardware reset is located at physical address FFFFFFF0H. This address is 16 bytes below the processor抯 uppermost physical address. The EPROM containing the software-initialization code must be located at this address. The address FFFFFFF0H is beyond the 1-MByte addressable range of the processor while in real-address mode. The processor is initialized to this starting address as follows. The CS register has two parts: the visible segment selector part and the hidden base address part. In real address mode, the base address is normally formed by shifting the 16-bit segment selector value 4 bits to the left to produce a 20-bit base address. However, during a hardware reset, the segment selector in the CS register is loaded with F000H and the base address is loaded with FFFF0000H. The starting address is thus formed by adding the base address to the value in the EIP register (that is, FFFF0000 + FFF0H = FFFFFFF0H).
/ a7 v( b3 Y* P% K' k. AThe first time the CS register is loaded with a new value after a hardware reset, the processor will follow the normal rule for address translation in real-address mode (that is, [CS base address = CS segment selector * 16]). To insure that the base address in the CS register remains unchanged until the EPROM based software-initialization code is completed, the code must not contain a far jump or far call or allow an interrupt to occur (which would cause the CS selector value to be changed).
0 i! t# C" d0 |Ddj (Doctor Dobbs Journal)的一个小片断:) I% g! d7 k+ ?6 e8 K3 h; I

" }1 U0 O/ e% H7 T6 }% h, BAt power-up, the descriptor cache registers are loaded with fixed, default values, the CPU is in real mode, and all segments are marked as read/write data segments, including the code segment (CS). According to Intel, each time the CPU loads a segment register in real mode, the base address is 16 times the segment value, while the access rights and size limit attributes are given fixed, "real-mode compatible" values. This is not true. In fact, only the CS descriptor cache access rights get loaded with fixed values each time the segment register is loaded - and even then only when a far jump is encountered. Loading any other segment register in real mode does not change the access rights or the segment size limit attributes stored in the descriptor cache registers. For these segments, the access rights and segment size limit attributes are honored from any previous setting (see Figure 3). Thus it is possible to have a four giga-byte, read-only data segment in real mode on the 80386, but Intel will not acknowledge, or support this mode of operation.! Z  _5 d& D: f( z9 Y$ Y: v8 D% g2 C9 ]
; g9 g: a8 h1 a" W0 v/ V
  现在,你知道重点在于描述缓存寄存器,特别是它的基地址部分。Ss可见部分只是一个“place holder”和“register-in-charge”,对于真实地址计算/变换是一个隐藏的描述缓存。无论你对这个描述缓存做什么, 当任何代码、栈或者数据值地址被转换计算的时候,它都要受到影响。在我们看来,我们不得不在16-bit保护模式使用基址是F_0000h的物理地址的“堆栈段”。这不是问题,因为ss描述缓存寄存器的基址已经在上面的代码中赋予了F_0000h值。这就解释了为什么上面的代码能够正确执行,下面是一个例子:' K1 ~: Q. }6 |! w& q, x
Address    Hex                  Mnemonic3 j# M- W3 F, g2 d1 q, L
F000:61BF  BC C5 61             mov   sp, 61C5h
' S+ m9 g/ K% a; ^* fF000:61C2  E9 3B FE             jmp   F000_6000_read_pci_byte ; Jump
% X$ n- y" U# b) O4 `! wF000:61C2                       ; ------------------------------------------------------------------
0 }5 q6 d1 e  U/ yF000:61C5  C7 61                dw 61C7h
# H2 U# U! z' g3 u; h9 x  这段代码里面我们已经给ss:sp指向F_61C5h,为retn指令服务。实际上,我们已经做了,因为ss包含了F_0000h(它的描述缓存基址部分)和你看到(sp contains 61C5h)的物理地址,ss:sp是F_0000h+61C5h ,物理地址是F_61C5h。. t) k9 H( E$ L  \: [8 }- m
5. 用到的工具
" D7 `' _1 f% K" H* r0 j本节介绍逆向工程分析所需的工具。将有一节单独解释IDA Pro反汇编工具。) h; B7 P: W$ e  I2 R
5.1. 我们的需求
$ Y6 K" c3 r: p/ M% L3 z% h开始进行之前,我们需要以下工具:& u/ A: l* Y9 A+ `
1、  IDA Pro反汇编工具。我使用IDA Pro V4.3。你可以使用你喜欢的交互式反汇编工具。我觉得IDA Pro最适合我。我们之所以需要交互式反汇编工具,因为我们要反汇编的BIOS代码并不是普通的代码。当驻留在ROM中执行的一些时候并没有栈可用,而是使用了一些栈的技巧来进行过程/例程调用。
8 C$ e9 Z3 u% R8 f2 |2 s# s2、  一个好的二进制编辑器。我使用HexWorkshop ver3.0b。该二进制编辑器最大的一个好处是它可以计算打开文件的所选范围内的校验和。
$ k; k8 |) |1 Y3、  LHA2.55,用来修改BIOS二进制。如果你仅想解压缩并分析压缩的BIOS组件,也可使用winzip或其他可以处理LZH/LHA文件的压缩/解压缩工具。' z9 H/ z. |8 a
4、  BIOS修改工具,例如CBROM,我使用v2.08,v2.07和1.24。以及MODBIN,有两种:modbin6 for award bios ver. 6和modbin 4.50.xx for award bios ver. 4.5xPGNM。使用这些工具更容易查看BIOS组件。可从[url]www.biosmods.com[/url]下载。
' A4 B5 J! ^# b( `/ X+ g: G5、  一些芯片集数据表,这取决于你要解剖的主板BIOS代码。[url]www.com.by[/url]上有一部分pdf格式的数据表。我解剖的主板是VIA693A-596B,我当然有这个数据表。
7 Q( e8 a: H' u9 ?. Q. r7 {6、  Intel Software Developer Manual Volume 1, 2 and 3。BIOS有时使用一些外来指令集。另外有些很难记住的数据结构需要查询,如GDT、IDT等。  K' b9 `& C* ^; e7 c
5.2. IDA Pro技术介绍
& L- n+ f) b4 D9 ^( _& \# M本小节介绍使用IDA Pro。如果抓住了这些概念,你可以方便地使用IDA pro。$ t- B4 o; j' Z  p
5.2.1. IDA Pro介绍
$ s5 @* j( |% j; m  K逆向代码工程通过分析软件的可执行文件来实现对软件所使用算法的理解。在大多数情况下,软件仅发布它的可执行文件而没有源代码。BIOS也同样如此,我们可获得的仅仅是执行代码。逆向代码工程在以下工具的帮助下实现:调试器,反汇编工具,二进制文件编辑器即二进制编辑器,ICE()等。我们在本小节中仅讨论反汇编工具,例如IDA Pro反汇编工具。8 J2 a# ~8 `  n
IDA Pro是一款强大的反汇编工具。它支持插件和脚本组件支持50种以上的处理器结构。但功能强大的工具一般都有缺陷,就是难以掌握使用,IDA Pro也不例外。$ A: d1 k; B- X4 i+ ^
IDA Pro有多个版本:免费版、标准版和高级版。最新的免费版为IDA Pro version 4.3 (AFAIK),可在[url]http://www.dirfile.com/ida_pro_freeware_version.htm[/url]下载。/ t4 O8 H+ I- A6 ^6 Q; i% b
There are several editions of IDA Pro: freeware edition, standard edition and advanced edition. The latest freeware edition is IDA Pro version 4.3 (AFAIK) and it抯 available for download at [url]http://www.dirfile.com/ida_pro_freeware_version.htm.[/url] It抯 the most limited of all IDA Pro version. It only supports x86 processor and doesn't come with plugin feature, but it comes at no cost, that's why it's presented here. Fortunately, it still comes with scripting feature. The standard and advanced editions of IDA Pro 4.3 of course differ from this freeware edition, they come with support for plugin and support for much more processor architecture. We are going to learn how to use the scripting feature in the next section.
: d! A4 G1 ?( E5 xNow, let抯 start to use IDA Pro freeware version to open a BIOS binary file. First, IDA Pro freeware version has to be installed. After the installation finished, one special step must be carried-out to prevent unwanted bug when this version of IDA Pro opens up a BIOS file with *.rom extension. To do so, one must edit the IDA Pro configuration file that抯 located in the root directory of the IDA Pro installation directory. The name of the file is ida.cfg. Open this file by using any text editor (such as notepad) and look for the following lines: 2 G& J" C1 u& p: o2 Z' I
  DEFAULT_PROCESSOR = {   
/ x  g% h' @5 s$ g0 ?1 z/* Extension    Processor */    5 g5 @2 i5 j! X( ?! @7 E
  "com" :       "8086"                  // IDA will try the specified   
& L5 X2 _1 r  N1 S+ F  "exe" :       ""                      // extensions if no extension is   
2 s) _3 F: u. e* U  "dll" :       ""                      // given.     4 [# ~. w$ v3 D
  "drv" :       ""   
9 c7 H* a, P8 Z) P2 h  "sys" :       ""    * v! v) a( W1 d
  "bin" :       ""  // Empty processor means the default processor    * y8 h( p9 ]2 b: a2 C( n& o
  "ovl" :       ""   
4 w% c: L: _" P" x$ d# Q  "ovr" :       ""   
6 L* S0 B& V2 h6 o  "ov?" :       ""    ; z5 ~  H2 m3 h3 R3 ~
  "nlm" :       ""   
6 t4 p" V5 j" B  Z  "lan" :       ""   
& h+ Q  n% u* m/ D4 P7 Z  "dsk" :       ""    , @" ~  D  ~. G2 k3 x3 X3 c+ {
  "obj" :       ""  & y0 O+ P4 X% T) _6 ^5 k; K. [
  "prc" :       "68000"                 // PalmPilot programs  & B0 U5 ]3 I3 _3 [2 e. G
  "axf" :       "arm710a"    ; ^$ P% r+ M% d# m
  "h68" :       "68000"                 // MC68000 for *.H68 files    5 ^2 \0 _! Q2 p- h1 B7 |, K5 L
  "i51" :       "8051"                  // i8051   for *.I51 files   
7 X7 X5 |0 I" P5 l* [  "sav" :       "pdp11"                 // PDP-11  for *.SAV files   
+ C+ R- H3 }& ?- B0 W9 _3 `- [5 ]  "rom" :       "z80"                   // Z80     for *.ROM files   
! t3 z2 t, }7 O! w( O$ s  "cla*":       "java"    . H/ `, \6 `' E& y" ^* ^! m( C
  "s19":        "6811"   
7 z5 A$ p: y; }& N  "o":          ""    * {7 s  k9 _, v% o# F7 J  b
  "*":          ""                      // Default processor  
1 Q  v! X3 n  j  B1 p7 o& `}    ! p+ }( \" ]/ a1 Z4 D, t3 n
Notice the line: "rom" : "z80" // Z80 for *.ROM files
- L' F' z# d% ?* Y$ Y# OThis line must be removed or just replace the "z80" with "" in this line to disable the automatic request to load z80 processor module in IDA Pro upon opening a *.rom file. The bug occurred if the *.rom file is opened while this line is not changed ince freeware IDA Pro doesn't come with z80 processor module. Thus, opening *.rom file by default will terminate IDA Pro. Some motherboard BIOS files comes with *.rom extension by default, even though it's very clear that it won't be executed in z80 processor. Fixing this bug will ensure that we will be able to open motherboard BIOS file with *.rom extension flawlessly. Note that the steps needed to remove other file-extension to processor-type "mapping" in this version of IDA Pro is similar to the z80 processor that is just described. % t4 N+ A7 ]/ t/ J6 ?+ y2 _. A+ Z
Now let's proceed to open a sample BIOS file. This BIOS file is da8r9025.rom, BIOS file for Supermicro H8DAR-8 (OEM Only) motherboard. This motherboard used AMD-8131? HyperTransport? PCI-X Tunnel chip and AMD-8111? HyperTransport? I/O Hub chip. The dialog box below will be displayed when you start IDA Pro freeware version 4.3.6 Q2 A% B. N4 M1 P, i( S" |# @

! G, a3 Q- |7 rJust click OK to proceed. Then the next dialog box shown below will be displayed.
8 [2 [: D8 m! v5 ~9 T) J( p; W
  k) U( F% r' R- LIn this dialog box, you can try one of the three options, but we will just click on the Go button. This will start IDA Pro with empty workspace as shown below
2 R) x5 M  w; k6 [ ' k: j1 x0 @1 t, [5 V
Then locate and drag the file to be disassembled to the IDA Pro window (as shown above). In this case, IDA Pro will show the following dialog box. % K8 v7 A% V" ?1 H4 T, n' D
; p8 t" L. _( \7 T' |; x  M7 R+ `( t
In this dialog box, we will select Intel 80x86 processors: athlon as the Processor type in the drop down list box. Then click on the Set button to activate the new processor selection. Let the other option as it is. Code relocation will be carried out by using IDA Pro scripts in later section, then click OK. IDA Pro then shows the following dialog box.   u5 s3 t4 o" W4 y, r- N
# d5 X( }- Z  M& d) O$ T# l( p# B
This dialog box asks us to choose the default operating-mode of the x86 compatible processor during the disassembling process. AMD64 Architecture Programmer抯 Manual Volume 2: System Programming, February 2005 in section 14.1.5 page 417 states that:
) n7 l( M9 T% o! t4 L"After a RESET# or INIT, the processor is operating in 16-bit real mode."   i0 ~$ Y6 s/ Q2 ~
In addition, IA-32 Intel? Architecture Software Developer抯 Manual Volume 3: System Programming Guide 2004 section 9.1.1 states that: 5 Q8 L9 d" m, \
"Table 9-1 shows the state of the flags and other registers following power-up for the Pentium 4, Intel Xeon, P6 family, and Pentium processors. The state of control register CR0 is 60000010H (see Figure 9-1), which places the processor is in real-address mode with paging disabled." 6 G9 U+ f4 z2 b
Thus, we can conclude that any x86 compatible processors start their execution in 16-bit real mode just after power-up and we have to choose 16-bit mode in this dialog box. It抯 accomplished by clicking No in the dialog box. Then the following dialog box pops up.
2 n4 D) M3 _* l, n . {# b2 W% w5 d7 r
This dialog box told us that IDA Pro can抰 decide where the entry-point located. We have to locate it ourselves later. Just click OK to continue to the main window for the disassembly process. ) D' V0 ~* Z6 J3 i; ~

" b' U/ ~8 \0 R9 g; pUp to this point we are able to open the binary file within IDA Pro. This is not a trivial task for people new to IDA Pro. That's why it's presented in a step-by-step fashion. However, the output in the workspace is not yet usable. The next step is learning the scripting facility that IDA Pro provides to make sense about the disassembly database that IDA Pro generates. ) o# N  Y+ t% s2 {: \1 r& `
5.2.2. IDA Pro Scripting And Key Bindings, d' @6 V& D2 T
Now we will proceed to try to decipher IDA Pro disassembly database shown in the previous sub-section with the help of the scripting facility. Before we proceed to analyze the binary, we have to learn some basic concepts about the IDA Pro scripting facility. IDA Pro scripts syntax are similar to C programming language. The syntax as follows:
" F& H3 o8 x( ~/ `+ w1.  IDA Pro scripts only recognize one type of variable, i.e. auto. There are no other variable types such as int, char, etc. The declaration of variable in an IDA Pro script as follows:
8 ~" i* L1 p! _' t! f% o8 Eauto variable_name;
* v+ W, f, {- |# m2.  Every statement in an IDA Pro script ends with a semicolon (;), just like in the C programming language. 8 y6 t8 j4 P! l
3.  Function can return a value or not, but there抯 no return type declaration. The syntax as follows:
7 X6 m, W2 v6 wstatic function_name(parameter1, parameter2, parameter_n, ...)  
5 Q: o. ~+ o, x: e4.  Comment in an IDA Pro script starts with double-slash (//). The IDA Pro scripting engine ignores anything after the comment in the corresponding line.
5 y" ], l! \$ c4 s" N! V3 O! j5.  // comment                  , \% T. b( L) e+ n
6.  statement; // comment              
: v. r3 g% h+ A8 M# y2 M5 E9 F, s7.  IDA Pro "exports" its internal functionality to the script that we build by using header files. These header files must be "included" in our script so that we are able to access that functionality. At least one header file must be included in any IDA Pro script, i.e. idc.idc. The header files are located inside a folder named idc in the IDA Pro installation directory. One must read the *.idc files inside this directory to learn about the functions that are exported by IDA Pro. The most important header file to learn is idc.idc. The syntax used to include a header file in an IDA Pro script is:
3 z  k' o5 o* r: V6 r8.  #include < header_file_name >            
% w' l. v' y' u2 F' E% S9.  The entry point of an IDA Pro script is the main function, just as in the C programming language. ( H: [! q* d& J( k# t
Now is the time to put the theory into a simple working example, an IDA Pro sample script. * f; H& H" @! L" o: U, f
#include     
. F5 d9 a5 `" m, u// relocate one segment  
3 j& {, q" ]1 ~. w/ mstatic relocate_seg(src, dest)  
/ Q: O( C* _2 Y* q0 ~& G% u! p. z{    & ^5 M7 w- x4 @, n# r9 `% u
  auto ea_src, ea_dest, hi_limit;  * z+ p' k: Z5 q% _6 K/ _
   
6 [' B5 O/ c$ F6 F* i& ~2 s1 }  hi_limit = src + 0x10000;  2 |) h0 |0 |  ~; S8 C
  ea_dest = dest;    V1 ?% j  C) J9 i! l
   
# z' U; O* [$ ^- \* W% t3 }  for(ea_src = src; ea_src < hi_limit ; ea_src = ea_src + 4 )    8 ]' f7 {2 q2 y8 |& ~
    {  : R; J( J' z2 d. G; H. Q# g3 |
    PatchDword( ea_dest, Dword(ea_src));  
/ `# Q. z% R: m$ r    ea_dest = ea_dest + 4;  
. i* C6 E1 j- ]4 A1 J   }  
9 o0 O5 `3 ]6 t6 A* }     
' B. o- {5 U7 s& @- V" D  Message("segment relocation finished (inside relocate_seg function)..\n");  . a; U$ A- c3 _7 r, K; Z
}    ; @$ i% ?, f0 O0 z
    # N6 T6 u8 K$ S
static main()  
7 ]) L7 i2 x% B* u/ L# Z{   
7 Q& M! A# Y! i& T6 J  Message("creating target segment (inside entry point function main)...\n");  
& P5 m+ s1 N( o! O9 W8 X  SegCreate([0xF000, 0], [0x10000, 0], 0xF000, 0, 0, 0);  
' O4 g/ t- o$ K6 S4 I; r2 a  SegRename([0xF000, 0], "_F000");  7 u$ y% k4 N% }
    + o1 Z5 D: M, e+ M8 i3 v  Z
  relocate_seg([0x7000,0], [0xF000, 0]);  5 F6 `$ O8 l! `6 S5 m& s# O. p
}    - h# _9 K' y1 \+ q. `8 ?- c
The square bracket, i.e. [ ] in the script above is an operator used to form the linear address from its parameters by shifting the first parameter to left four bits and then adding the second parameter into the result, for example: [0x7000, 0] means (0x7000 << 4) + 0 , i.e. 0x7_0000 linear address. This operator is just the same as MK_FP( , ) operator in previous versions of IDA Pro. One must read idc.idc file to see the "exported" function definition to understand this script completely, such as the Message, SegCreate and SegRename function. Another "exported" function that maybe of interest can be found in numerous *.idc file in the idc directory of IDA Pro installation folder. To be able to use the function, its definition have to be looked up in the exported function definition in the corresponding *.idc header file. For example, SegCreate function is defined in idc.idc as follows:
; J! Y( H) P+ o% _9 D3 V8 ]// Create a new segment  $ j! Z) w& y8 g% W0 W. ?9 h
//      startea  - linear address of the start of the segment  7 x9 g8 H% I$ \4 c
//      endea    - linear address of the end of the segment  
" }6 X& j3 p$ m9 j8 L//                 this address will not belong to the segment  " L. T; M' W. P! C3 I: M1 O; L
//                 'endea' should be higher than 'startea'  + i1 x+ O% s5 v/ {8 y
//      base     - base paragraph or selector of the segment.  
7 |! e  N, L% D& H& U//                 a paragraph is 16byte memory chunk.  
  U* V: ~) |; a1 E! r//            If a selector value is specified, the selector should be  
$ j: @  G( B# g; o//                 already defined.  
. D4 }7 F3 G1 m+ ^' H1 `' z//      use32    - 0: 16bit segment, 1: 32bit segment  
$ {; f3 m/ G5 [2 }9 B, @# ^//      align    - segment alignment. see below for alignment values  
3 z) k- P5 w9 y  u$ V//      comb  - segment combination. see below for combination values.  " o, c1 ~1 C0 C
// returns: 0-failed, 1-ok  # J: ^, _+ W# ^' \- b
    & F: Z1 P- k8 s9 b' I
success SegCreate( long startea,long endea,long base,  long use32,   9 k& E* W  ~+ z2 V  N/ m: ~# Q
              long align,long comb);   
( L' O/ ^! V# ^* N! u( U9 Q5 `+ Y* RA 512KB BIOS binary file must be opened in IDA Pro with the loading address set to 0000h to be able to execute the sample script above. This loading scheme is the same as explained in the previous sub-section. In this case, we will just open the binary file of Supermicro H8DAR-8 motherboard as in the previous sub-section and then execute the script. First, we must type the script above in a plain text file. We can use notepad or another ASCII file editor for this purpose. We will name the file as function.idc. The script then executed by clicking on the File | IDC file... menu or by pressing F2, then the dialog box below will be shown.  P! {) \2 D$ ^) |, Q

- v; P! a0 T# q$ S- oJust select the file and click open to execute the script. If there抯 any mistake in the script, IDA Pro will warn you with a warning dialog box. Executing the script will display the corresponding message in the message pane of IDA Pro as shown below.
4 h, M3 i$ p- o5 T) F- Q 4 g6 |9 Z) F' c' D, g! K* L
The script above relocates the last segment (64KB) of the Supermicro H8DAR-8 BIOS code to the right place. One must be aware that IDA Pro is only an advanced tool to help the reverse code engineering task, it抯 not a magical tool that抯 going to reveal the overall structure of the BIOS binary without us being significantly involve in the process. The script relocates/copies BIOS code from physical/linear address 0x7_0000-0x7_FFFF to 0xF_0000-0xF_FFFF. The logical reason behind this algorithm is explained below. - `' ?; {+ N* T+ U; C1 a- {
AMD-8111 HyperTransport IO Hub Datasheet chapter 4 page 153 says that: " ?* q3 w4 l  w( V+ z" R& B
Note: The following ranges are always specified as BIOS address ranges. See DevB:0x80 for more information about how access to BIOS spaces may be controlled.
  v( D$ _' [% C, {0 b, `) c2 [0 TSize  Host Address Range[31:0]  Address translation for LPC bus
. y; |/ c$ h  J2 u" e8 z- h64K bytes  FFFF_0000h ?FFFF_FFFFh  FFFF_0000h ?FFFF_FFFFh! i- C! I1 P* \9 P
64K bytes  000F_0000h ?000F_FFFFh  FFFF_0000h ?FFFF_FFFFh
$ r/ b" n* x/ G, cIn addition, AMD64 Architecture Programmer抯 Manual Volume 2: System Programming, February 2005 in section 14.1.5 page 417 says that: $ k& ~+ `! G5 O5 |
"Normally within real mode, the code-segment base address is formed by shifting the CS-selector value left four bits. The base address is then added to the value in EIP to form the physical address into memory. As a result, the processor can only address the first 1 Mbyte of memory when in real mode. However, immediately following RESET# or INIT, the CS selector register is loaded with F000h, but the CS base-address is not formed by left-shifting the selector. Instead, the CS base address is initialized to FFFF_0000h. EIP is initialized to FFF0h. Therefore, the first instruction fetched from memory is located at physical-address FFFF_FFF0h (FFFF_0000h+0000_FFF0h). The CS base-address remains at this initial value until the CS selector register is loaded by software. This can occur as a result of executing a far jump instruction or call instruction, for example. When CS is loaded by software, the new base-address value is established as defined for real mode (by left shifting the selector value four bits)." + L( \' I: Y+ C
From the references above, we conclude that address 000F_0000h ?000F_FFFFh is an alias to address FFFF_0000h ?FFFF_FFFFh, i.e. they both points to the same physical address range. Whenever the host (CPU) accesses some value in 000F_0000h ?000F_FFFFh address range, it's actually accessing the value at FFFF_0000h ?FFFF_FFFFh range and the reverse is also true. From this fact, we know that we have to relocate 64KB of the uppermost BIOS code to address 000F_0000h ?000F_FFFFh for further investigation. This decision is made based on my previous experience with various BIOS binary files, they generally references address with F000h used as the segment value within the BIOS code. Also, note that the last 64KB of the BIOS binary file is mapped to last 64KB of the 4GB address space, i.e. 4GB-64KB to 4GB, that's why we have to relocate the last 64KB. . `3 o) P$ \0 K4 V. }6 m' \
Simple script that is only several lines can be typed and executed directly within IDA Pro without opening a text editor. IDA Pro provides a specific dialog box for this purpose and it can be accessed by pressing Shift+F2. This is more practical for simple task, but as the number of the routine grows, one might consider coding the script as described in the previous explanation due to limitation of the number of instruction that can be entered in the dialog box. In this dialog box, enter the script to be executed and click OK to execute the script. Below is an example script.
- W0 C( @$ D8 f2 X' ?) v3 [
1 G/ l+ J3 n- c8 ?* G* z2 HNote that there is no need for #include statement in the beginning of the script, since by default all of the functions that are exported by IDA Pro in its scripts header files (*.idc) is accessible within the scripting dialog box shown above. The main function is also doesn抰 need to be defined. In fact, anything you write within the dialog box entry will behave as if it's written inside the main function in an IDA Pro script file.
' u- R, @2 I: \" }0 q, N3 v% VAnyway, you might want to go to the IDA Palace for more IDA Pro script samples. It will take a while to grasp them, but IDA Palace is definitely the place to go if you're curious about IDA Pro scripting.
0 N! t4 _* K0 C; AAt present, we are able to relocate the binary within IDA Pro; the next step is to disassemble the binary within IDA Pro. Before that, we need to know how the default key binding works in IDA Pro. Key binding is the "mapping" between the keyboard button and the command carried-out when the corresponding key is pressed. The cursor must be placed in the workspace before any command is carried-out in IDA Pro. The key binding is defined in idagui.cfg file that's located in IDA Pro installation directory. An excerpt of the key binding (hot key) is provided below.
+ X: B# r" }+ @* \3 F"MakeCode"              =       'C'            2 h- ^6 a% R+ N/ l/ M8 f
"MakeData"              =       'D'            * _& A$ X4 V; E5 T  S2 }3 l
"MakeAscii"             =       'A'            6 J4 P! z- `3 d8 i1 j( \, K" T
"MakeUnicode"           =       0           // create unicode string  
; y/ t5 |3 G: M3 t"MakeArray"             =       "Numpad*"          : t& L0 @" h. p+ z% c' O5 c
"MakeUnknown"           =       'U'            
3 }  I' ]& C6 q3 a5 o5 V4 D                      ! k4 X  V6 a. H
"MakeName"              =       'N'            # o2 c$ ^! \* x
//"MakeAnyName"           =       "Ctrl-N"          2 w4 C& w9 D; u# O
"ManualOperand"         =       "Alt-F1"          ! y, D* j0 f; J2 R3 _6 \+ R
                      1 |; S$ r. D! J4 g$ F# S
"MakeFunction"          =       'P'            2 v( Y, Z4 j) Q& ^# Q  h. S" G
"EditFunction"          =       "Alt-P"            6 f5 n* k3 `5 B5 W
"DelFunction"           =       0            
( ?' F  L9 d5 |5 l# M+ Z. P9 N"FunctionEnd"           =       'E'            7 p  {7 b- w7 |. _
One can alter idagui.cfg to change the default key binding, but we will only consider the default key binding. Now we have grasped the key binding concept, let's see how to use it in our binary. In the previous example, we are creating a new segment, i.e. 0xF000. Now, we will go to the first instruction that's executed in the BIOS within that segment, i.e. address 0xF000:0xFFF0. Press G, the dialog box below will be shown. , ?2 g8 K' Y+ t, e

- U- \2 Q) R) p& b7 @) O& F7 I8 fIn this dialog box, enter the destination address. You must enter the address in complete form (segment:offset) as shown above, i.e. F000:FFF0. Then, click OK to go to the intended address. Note that you don't have to type the leading 0x character, since by default, the value within the input box is in hexadecimal. The result will be as shown below (inside IDA Pro workspace).
' |# O, Q9 Y9 l3 m4 O* e# H0 ?: w
) C4 v0 v% a  A' B6 h7 l; p3 UThe next step to do is to convert the value in this address into a meaningful machine instruction. To do so, press C. The result is as shown below.
' i# s9 o+ d' `4 J0 ?' n
0 P4 N  c5 r- w# _2 {6 N+ Q  SThen, we can follow the jump by pressing Enter. The result is as shown below.
9 z' t3 s& ~& |9 } 8 s1 y, u) L4 j8 j) W
We can return from the jump that we've just made by pressing Esc.
! V7 |- M0 t$ k/ |, ~8 wUp to this point, you've gained significant intuition to use IDA Pro. You just need to consult the key bindings in idagui.cfg in case want to do something and don't know what key to press. 0 M, D0 F* _% F% L+ d
________________________________________9 M6 M4 T7 [  N
Now we're armed. What we need to do next is to understand the basic stuff by using the hex editor before proceeding through the disassembling session. / g) i# b; F" }9 ?9 L* n0 Y
6. Award BIOS 文件结构
/ w. `+ t+ V: H& V0 f6.1.压缩部分
1 s( x9 r0 Y5 _5 a" ~2 g内存映射16进制表: + }( S$ ~* e+ r# m+ H- \/ l
1.  0000h - 3AACh : XGROUP ROM (awardext.rom), Award扩展rom. 包含由system bios调用的例程,比如original.tmp。
: L/ W/ k0 Y% r+ [2.  3AADh - 97AFh : CPUCODE.BIN, bios的微代码。4 w3 _9 C4 E3 c, v# W
3.  97B0h - A5CFh : ACPITBL.BIN, acpi 表。
* s: B) `- G9 I  ?7 m* i4.  A5D0h - A952h : Iwill.bmp, BMP logo。+ q5 e. M# w) K1 g$ _; b% n# u
5.  A953h - B3B1h : nnoprom.bin, I haven't know yet what this component's role。2 e% M/ \0 |+ k6 @: K! I% e
6.  B3B2h - C86Ch : Antivir.bin, bootsector 防病毒。
% k: C) p: K/ ~' O6 Z# Y7.  C86Dh - 1BEDCh : ROSUPD.BIN, 我得bios中的自定义部分,用于显示自定义的启动logo和提示符。
* n- F1 k2 k" ^5 O9 k) }8.  2_0000h - 3_5531h : original.tmp, 我得特殊的bios中的system BIOS部分。大多数的2m的bios在2_0000h - 3_xxxxh (if you look from within hex editor)都有original.tmp。 有一些4M的bios有original.tmp在bios二进制文件的最开始的部分,比如0000h。6 n: @5 b# K. Q
注意:* `6 z0 c4 E  C) t8 R! `& d1 ?2 ?: w
a.  在压缩的 ROSUPD.BIN 和 original.tmp 之间有填充 FFh bytes. 这些填充bytes 在压缩 original.tmp 和纯二进制BIOS 部分之后都有发现。一个例子: ' |/ G! P) O' D2 s) s6 {
  Address  Hex                                     ASCII1 ^# W7 j/ U0 t
+ y, w% V8 ~3 e8 H; t  b9 H2 c
00037D00 2A42 4253 532A 0060 0070 0060 0060 00A0 *BBSS*.`.p.`.`..
& m% L# K+ ^5 n% c3 ]% l; Z" `; D00037D10 3377 4670 8977 ACCF C4CF 0100 00FF FFFF 3wFp.w..........
0 {/ K6 w8 z- T# @( j! t, S00037D20 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF ................7 ]! t/ r6 t& z
00037D30 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF ................
. j2 F. Y1 N. Hb.  这些压缩了的部分可以很容易的,通过拷贝和粘贴到新的二进制文件,通过Hexworkshop 。然后,解压这个新的文件,用LHA2.55或者winzip。如果我们使用winzip,那么改编扩展名为.lzh,这样winzip就可以自动识别了。识别我们剪切的部分非常简单,只要看到“-lh5-”字符串就可以了。2 bytes的“-lh5-”在文件的最前面,文件最后面总是00h,正好在下一个压缩了的文件前面,正好在填充bytes或者某些checksum前面。我要给你两个例子下面。高亮的bytes是要所的文件的最初和最后的标志。* C2 K$ Q3 j0 V5 B
我得bios中的压缩的CPUCODE.BIN: 8 y# d1 n% n: {/ Q$ N/ r  ]2 U
Address  Hex                                     ASCII" t, k. J: y2 O3 b) }6 m( q/ c) L
00003AA0 4E61 19E6 9775 2B46 BA55 85F0 0024 382D Na...u+F.U...$8-* Y2 Y- {' P4 g- x$ ^% Y+ E
00003AB0 6C68 352D DC5C 0000 00A0 0000 0000 0140 lh5-.\.........@
! b7 j, Q2 v6 G, g& E; Z: @: F00003AC0 2001 0B43 5055 434F 4445 2E42 494E BCAA  ..CPUCODE.BIN..
" t& R7 V, b) F7 H00003AD0 2000 0038 3894 9700 52C4 A2CF F040 0000  ..88...R....@..
: p2 b7 p+ J6 Y% e2 B- t: g00003AE0 4000 0000 0000 0000 0000 0000 0000 0000 @...............) m+ k' w& `: I! u# k, H+ _3 S
........
- P# b$ h' ~+ k% R/ g' F; S: N" ^. h0 ]* J000097A0 0E3C 8FA7 FFF4 FFFE 9FFF D3FF FFFB FF00 .<..............
% c  L' `* y+ X7 \$ H000097B0 24D9 2D6C 6835 2DFA 0D00 00A6 2100 0000 $.-lh5-.....!...% W2 H7 z3 j3 t' p. z" d% T
. s/ o0 b4 [2 J& U. a
我得bios中的压缩的 ORIGINAL.TMP:
- x& d( s+ C& o, Z& e( E7 [' cAddress  Hex                                     ASCII" ]7 t; @0 E% ]2 Y9 e$ K
0001FFF0 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF ................
& E0 P, O( `2 |& u+ V; f. p00020000 251A 2D6C 6835 2D09 5501 0000 0002 0000 %.-lh5-.U.......
7 Z$ h+ @# u  ?" ]00020010 0000 5020 010C 6F72 6967 696E 616C 2E74 ..P ..original.t
  W. a! ~; p6 ?, e" T% o00020020 6D70 0CD9 2000 002D 7888 F0FD D624 A5BA mp.. ..-x....$.." |, x! B9 M! @) A2 V6 V+ e1 z- a
........0 W  C! S+ `2 N1 o5 e- f
00035510 019E 6E67 BF11 8582 88D9 4E7C BEC8 C34C ..ng......N|...L) ?5 O+ n: X* |2 U" P
00035520 401D 189F BDD0 A176 17F0 4383 1D73 BF99 @......v..C..s..
: m3 c4 V+ @/ D5 C00035530 00C9 FFFF FFFF FFFF FFFF FFFF FFFF FFFF ................6 T) W7 O) \! P3 |! X6 x
00035540 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF ................5 B# ^! }% U1 w
; k1 X  k0 J+ K
6.2. 纯二进制部分3 Z5 X2 j0 f' C* Y/ x
内存印象:
) i, `) W; b, V1.  3_6000h - 3_6C4Ah : 这个例程初始化DRAM控制器(在host btidge中的),和我的bios中的DRAM时钟。
& ]' F( W* n" ?& ^2.  3_7000h - 3_7D1Ch : 解压缩例程部分。这个例程包含了LZH解压引擎,可以解压缩上面的bios压缩部分。
0 o- o+ u  \% M  A* X7 c% |3.  3_C000h - 3_CFE4h : 这个区域包含了不同的例程,低128KB是bios地址解码启动,默认的VGA初始化(如果系统bios错误执行),剩下的是Hostbridge初始化例程。
2 r: L# Y! g: D3 }4.  3_E000h - 3_FFFFh : 包含Boot Block代码。
- s% T6 m, o9 ^0 a9 K% m3 P' E注意:一些部分之间是填充. 一些是FFh bytes 一些是 00h bytes.. ~" `: q' J* ?% @, c
6.3. 真实系统(Mainboard)中的内存印象
5 x! N" D1 {& @% v% W9 S  我们已经注意到了内存映象,前面提到了bios二进制代码的。在主板bios芯片中,有一点不太一样,并且更加复杂。我得主板的映象如下(和你的可能不一样,参考芯片组文档):
, S4 [/ v$ i- F# _( P$ s% b2 a: s- L% i& ~( x
1.Bios二进制文件中的0_0000h - 3_FFFFh映射到了系统内存中的FFFC_0000h - FFFF_FFFFh。由于我得系统中的北桥,地址FFFF_0000h-FFFF_FFFFh 只是F_0000h - F_FFFFh 的别名或者也可以说是在“实模式行话” F000:0000h - F000:FFFFh。注意这个映射适合在加电后,因为它是芯片组加电默认的值。在芯片组被bios重新编程后,不保证是否有效。有一些“kludge(杂牌电脑)”,它们是由系统决定的。你不得不参考Intel Software Developer Manual Volume 3(system programming)和你的芯片数据表。
; R+ b, r6 c) R, R, W- T9 v2 L2.归功于第一点的解释,bios中的纯二进制部分映射如下(加电后):  d' c6 y' G( `* u" V  M3 B% O- Q
1)BootBlock : F000:E000h - F000:FFFFh 7 a8 w; O( z( \8 _0 j( t, q6 L4 z
2)Decompression Block : F000:7000h - F000:7D1Ch
$ k, x" I% ]+ v0 J" N4 E) A$ M3)早期 DRAM 控制器 和 DRAM 初始化 : F000:6000h - F000:6C4Ah
: U0 w3 r: Q6 N/ L0 A0 A3.压缩的bios部分在他们通过不同方式被释放后映射到系统内存空间。他们依靠这个解压模块例程,但是不同的bios文件中,他们的映射很少有看起来相同的。这些映射(我得如下,你的可能不一样,但是段地址很可能相同):: e+ l' {( N2 N5 |1 n
1)original.tmp a.k.a System BIOS : E000:0000h - F000:FFFFh
8 g2 l8 e6 _' R& v" ?2)awardext.rom a.k.a Award 扩展 ROM : 4100:0000h - 4100:xxxxh。稍后被original.tmp重新部署到6000:0000h - 6000:xxxxh,比如在它执行之前。! G! R9 _7 ~$ k6 G6 S
( m2 K) o  K# D
  在我们进行我们的旅途中,我们必需要注意这样的映射。
% i# k5 u. A1 X- n; Q) Q0 n8 M% p' V+ y7 w
注意:
4 g- e; P; G4 k; r) Q. b; ?# U  由于完全复杂的映射到真实系统bios二进制地址,我们很容易迷路。但是,有一个技巧可以方便我们的工作,在我们反汇编进程中,通过使用IDA Pro:! v( a, ~  h! I  D# g, F7 P
  从纯二进制部分开始反汇编进程。在地址F000:FFF0h (3_FFF0h 从hex editor看二进制)开始反汇编。为了做到这个,用IDA Pro打开二进制文件(VD30728.BIN , i.e. Iwill VD133 BIOS binary),然后反汇编这个文件,通过设置它的地址映射到C000:0000h ,记住让段名无效,那样我们就可以在系统中,执行的时候看到实模式地址。通过IDA Pro的Scripts调整另外的段地址,记住调整地址配置来符合芯片数据表。, C. x9 m4 Y( b' q
7. 反汇编BIOS7 K& v( S; ?& |
  由于Intel system programming Guide,我们就要开始在f000:fff0h地址反汇编了(看看上面的内存映射,调整IDA Pro来适应它)。你可能会问:这怎么可能?Intel Software Developer Manual Vol. 3 (PROCESSOR MANAGEMENT AND INITIALIZATION - First Instruction Executed) 介绍:% m% Q. r% p, J& t. L, P' z
  在硬件reset后得到并执行的第一条指令所在的物理地址是FFFFFFF0H。
4 l4 N9 l$ A* K  答案是:北桥芯片组使用000F_xxxxh 作为FFFE_FFFFh-FFFF_FFFFh 的别名。而且,注意在这个地址的转移之后南桥没有意义。它只是直接将地址传到Bios Rom芯片。因此,在加电reset后,地址FFFF_FFF0h 和 F_FFF0h (or F000:FFF0 in "real-mode lingo")没有什么困难。它是那么简单。这个是BootBlock区域。它总是有一个far jump跳入bootblock区域,主要的在F000:E05Bh 。从这点看,我们能够继续主要的纯二进制部分的反汇编。实际上,很多纯二进制部分代码没有执行,因为你的系统bios很少错误,并且Bootblock POST进程发生了,除非你把它搞糟了。
 楼主| 发表于 2007-11-16 13:29:03 | 显示全部楼层
7.1. Bootblock! Y) M, c6 W! ]" v4 T, e, z! t
  从这点看,我们可以返汇编bootblock例程了。现在,我要给你一些不明显的和重要的在已经反汇编了的bios代码区域。这个是关于我的bios,你的可能不同,但是恕我直言很相近。  
8 H8 P' [4 y( Y7.1.1. "Virtual Shutdown" routine * y, R/ Q% H$ C' a9 v, i3 H
Address    Hex                     Mnemonic
+ _; |/ ?" e+ q6 O' j- m# ]4 G" g' BF000:E07F BC 0B F8               mov   sp, 0F80Bh          ; ret from this jmp redirected to 0E103h (F000:E103h)4 u0 d0 I& [5 F  D. F
F000:E082 E9 7B 15                  jmp   Chipset_Reg_Early_Init' x9 W9 w" w9 i% k2 X. B# D
7.1.2. Chipset_Reg_Early_Init routine , p, J5 \# B( N2 z* W
Address    Hex                       Mnemonic4 I8 `, ~( Z1 s
F000:F600                         Chipset_Reg_Early_Init proc near ; CODE XREF: F000:E082j
( j8 G  I4 v$ U/ n, \7 ?0 r8 s* x. AF000:F600 66 C1 E4 10               shl   esp, 10h- B$ S* ?/ W9 s
F000:F604 BE C4 F6                  mov   si, 0F6C4h          ; addr of chipset reg mask3 V" ?) U% f( \2 B
F000:F607                         next_PCI_reg:               ; CODE XREF: Chipset_Reg_Early_Init+29j& |& f; X3 t+ R' k  N
F000:F607 2E 8B 0C                  mov   cx, cs:[si]% K: C& C( v8 P4 ?: V* W/ o1 V4 D
F000:F60A BC 10 F6                  mov   sp, 0F610h7 O4 J, y/ c) e5 }
F000:F60D E9 F8 00                  jmp   Read_PCI_Byte/ |0 A, v: u" g, E5 P! x* _* S
F000:F60D                         ; ---------------------------------------------------------------------------1 ?# q; z4 E0 K( {1 [
F000:F610 12 F6                     dw 0F612h
) V" p. j6 N5 fF000:F612                         ; ---------------------------------------------------------------------------
, l( F7 @- a( b) z5 L* n0 P% PF000:F612 2E 22 44 02               and   al, cs:[si+2]
- @* |5 M/ j: N: j. GF000:F616 2E 0A 44 03               or    al, cs:[si+3]
$ y/ L# y6 B+ ^5 n$ E* TF000:F61A BC 20 F6                  mov   sp, 0F620h
# o# @% A/ M/ ~$ c( n# h1 m! }F000:F61D E9 02 01                  jmp   Write_PCI_Byte9 k0 U6 D8 g; a6 H
F000:F61D                         ; ---------------------------------------------------------------------------
( E2 ]# }( H/ _6 }2 SF000:F620 22 F6                     dw 0F622h
$ U9 c0 p' d. F. h. |* zF000:F622                         ; ---------------------------------------------------------------------------/ N7 k7 `) Q5 A  D$ _, O8 D8 Q
F000:F622 83 C6 04                  add   si, 4* M4 A% V5 K0 d8 O; J  L( F
F000:F625 81 FE 04 F7               cmp   si, 0F704h          ; are we done yet?( l% g( d7 a/ x0 g/ |/ \  _% f5 R
F000:F629 75 DC                     jnz   next_PCI_reg9 x" ^# |$ a( q, v5 u
F000:F62B BA D0 04                  mov   dx, 4D0h            ; Master PIC Edge/Level Triggered% y0 J& B3 o' y# s% }: o
F000:F62E 32 C0                     xor   al, al7 N0 {6 R0 n: |1 K5 O
F000:F630 EE                        out   dx, al
+ k# _% I9 Y$ `0 n, N/ a; ~F000:F631 FE C2                     inc   dl                  ; Slave PIC Edge/Level Triggered
2 \( `7 E' Q% fF000:F633 EE                        out   dx, al
: a  |  X) }- G0 G% r4 u# i% tF000:F634 B9 08 38                  mov   cx, 3808h           ; Bus#0 Dev#7 Func#0 (PCI2ISA Bridge) reg 8h(revision id)
3 H- `& p3 c) I! F  sF000:F637 BC 3D F6                  mov   sp, 0F63Dh
$ n4 E; I$ r& I! s5 eF000:F63A E9 CB 00                  jmp   Read_PCI_Byte
3 V# @- O2 `0 G/ CF000:F63A                         ; ---------------------------------------------------------------------------; p: w# l" Z! v8 D+ `; c
F000:F63D 3F F6                     dw 0F63Fh
! n) {% C; E' G- cF000:F63F                         ; ---------------------------------------------------------------------------. f6 @" p; ?* |' Q/ u& C' V
F000:F63F 3C 10                     cmp   al, 10h             ; is silicon revision > 10h5 C8 S  d- j. |" P; x% ]
F000:F641 72 53                     jb    silicon_rev_lt_10h  ; in current mobo this jmp NOT taken (rev id = 12h)
: ~9 [- [2 y' s( C7 `% k7 VF000:F643 B9 90 3B                  mov   cx, 3B90h           ; B#0 D#7 F#3: PwrMngmt&SMBus - SMBus IO Base Addr lo_byte& I5 @+ a" i0 |# D1 z1 B
F000:F646 B0 00                     mov   al, 0               ; set SMBus IO Base lo_byte to 00h
" O  \  ?' N. m- c, YF000:F648 BC 4E F6                  mov   sp, 0F64Eh
4 a! I7 v' v8 @4 a% V& DF000:F64B E9 D4 00                  jmp   Write_PCI_Byte8 D% q4 s8 C5 m+ x; x* i2 w: M
F000:F64B                         ; ---------------------------------------------------------------------------  @! N% l% V/ k
F000:F64E 50 F6                     dw 0F650h
# q7 i0 M9 x2 B0 MF000:F650                         ; ---------------------------------------------------------------------------
& T7 o3 A( V9 |+ ]( V" }F000:F650 B9 91 3B                  mov   cx, 3B91h           ; B#0 D#7 F#3: PwrMngmt&SMBus - SMBus IO Base Addr hi_byte" S: P$ f! L+ w( B! H$ V0 b
F000:F653 B0 50                     mov   al, 50h ; 'P'       ; set SMBus IO Base hi_byte to 50h,
3 p" e" ?" }0 ^0 G& T4 vF000:F653                                                     ; so, now SMBus IO Base is at port 5000h !!!
! _( T1 m7 f3 X7 ^# W8 k* tF000:F655 BC 5B F6                  mov   sp, 0F65Bh  F1 a8 x; n# f
F000:F658 E9 C7 00                  jmp   Write_PCI_Byte, E( f: }9 b& g6 J: E& z3 Q
F000:F658                         ; ---------------------------------------------------------------------------/ s2 x! k8 H- q0 g5 R
F000:F65B 5D F6                     dw 0F65Dh
, B) ^3 R) l, {F000:F65D                         ; ---------------------------------------------------------------------------6 _( f% G9 E. \
F000:F65D B9 D2 3B                  mov   cx, 3BD2h           ; B#0 D#7 F#3: PwrMngmt&SMBus - SMBus Ctrl
, R( U4 ~8 ?9 x- a: T+ MF000:F660 B0 01                     mov   al, 1               ; SMBus Controller Enable
& n0 L$ {# {* R  x  bF000:F662 BC 68 F6                  mov   sp, 0F668h6 D3 I$ b/ v# ?& h. B3 u: [- @" R
F000:F665 E9 BA 00                  jmp   Write_PCI_Byte/ q6 p# }9 I$ N) n/ e: x% B: Y. v% Q9 [6 c
F000:F665                         ; ---------------------------------------------------------------------------" S' r8 B& ?  d- ~8 M5 ?( R$ h
F000:F668 6A F6                     dw 0F66Ah0 n+ ?7 K# @: c% j( q0 v) F# X1 Z
F000:F66A                         ; ---------------------------------------------------------------------------
) S. b9 W: i( _" l  }2 ~6 |( `F000:F66A BA 05 40                  mov   dx, 4005h           ; access ACPI Reg 05h # _& G2 D3 l6 a2 m
F000:F66A                                                     ; (see chipset init above for init of port 4000h as ACPI IO): ]; s, E: Z1 ~5 m- u- n# M
F000:F66D B0 80                     mov   al, 80h ; '?       ; setting reserved bit?
5 L% `3 T1 H/ g9 H& {" M8 O5 mF000:F66F EE                        out   dx, al) ?0 j# c- D) T6 |) K3 ?* D1 _( |
F000:F670 B9 41 3B                  mov   cx, 3B41h           ; general config
7 q0 [3 x+ |9 iF000:F673 BC 79 F6                  mov   sp, 0F679h
4 D$ S6 Z. P5 r4 s- |* WF000:F676 E9 8F 00                  jmp   Read_PCI_Byte$ i# `7 X, X3 {3 P- T- j( t
F000:F676                         ; ---------------------------------------------------------------------------
' }6 C% j9 M6 N% a( |4 ?) {  iF000:F679 7B F6                     dw 0F67Bh
$ R' N3 q2 }. [* j+ j! g/ XF000:F67B                         ; ---------------------------------------------------------------------------
* b5 G9 S' M; E6 YF000:F67B 0C 04                     or    al, 4               ; RTC Enable Signal Gated with PSON (SUSC#) in
5 F5 b$ o+ J' }1 o; H7 P' e5 [0 RF000:F67B                                                     ; Soft-Off Mode& P* q+ w+ S1 B0 t  s# T# m' M" E
F000:F67D BC 83 F6                  mov   sp, 0F683h
* G( o6 H0 p6 K5 H% pF000:F680 E9 9F 00                  jmp   Write_PCI_Byte. R5 X! h$ E/ I! u! I
F000:F680                         ; ---------------------------------------------------------------------------
; E) h1 s# O% TF000:F683 85 F6                     dw 0F685h# \6 w! u+ S6 \
F000:F685                         ; ---------------------------------------------------------------------------
: i- z; B$ g. CF000:F685                         reinit_SCI_interrupt:       ; CODE XREF: Chipset_Reg_Early_Init+92j
$ ]5 l8 b5 Y" Q2 rF000:F685 B9 42 3B                  mov   cx, 3B42h           ; B#0 D#7 F#3: SCI Interrupt Configuration
& V) {! j' @0 I1 U3 Z& YF000:F688 BC 8E F6                  mov   sp, 0F68Eh
0 w& e2 e6 H; H$ OF000:F68B EB 7B                     jmp   short Read_PCI_Byte9 a4 j4 {7 P' t* o, t% q( S
F000:F68B                         ; ---------------------------------------------------------------------------" q% n; b4 H* G$ j& K
F000:F68D 90                        db  90h ; ?$ J8 W2 q# l* q2 e! ~: _$ U
F000:F68E 90 F6                     dw 0F690h
$ g3 \( }$ J9 v3 X' MF000:F690                         ; ---------------------------------------------------------------------------
4 B% R. L; C! p; l/ c! S  yF000:F690 A8 40                     test  al, 40h             ; check SUSC State# z& g1 l/ q/ k) K& f( P2 a  W: p
F000:F692 74 F1                     jz    reinit_SCI_interrupt% Z9 T9 t" g+ W# m  B
F000:F694 EB 27                     jmp   short exit
3 _7 [+ F2 T& `) V+ w; SF000:F696                         ; ---------------------------------------------------------------------------  a# o/ K. w. N
F000:F696                         silicon_rev_lt_10h:         ; CODE XREF: Chipset_Reg_Early_Init+41j* \' l4 H6 ?. f# m% @0 T% ?
F000:F696 B9 80 3B                  mov   cx, 3B80h0 Q$ Q# B- {& S
F000:F699 B0 00                     mov   al, 0
3 \3 u  Q1 `- ?0 L* _! G. w3 XF000:F69B BC A1 F6                  mov   sp, 0F6A1h
* M7 S) Q  l1 E; o: gF000:F69E E9 81 00                  jmp   Write_PCI_Byte
; _, Y% @# ?" S# rF000:F69E                         ; ---------------------------------------------------------------------------
; C" J4 b& M, x3 G3 ?# t' uF000:F6A1 A3 F6                     dw 0F6A3h4 m- _7 E5 a7 b: i8 u
F000:F6A3                         ; ---------------------------------------------------------------------------4 H7 |% ?5 {, q8 C
F000:F6A3 B9 81 3B                  mov   cx, 3B81h3 v9 P0 e2 K' d) y$ P( p
F000:F6A6 B0 50                     mov   al, 50h ; 'P'+ j6 O; {8 M: W" @4 h. H& F
F000:F6A8 BC AE F6                  mov   sp, 0F6AEh7 Q+ v5 P3 w% o/ c
F000:F6AB EB 75                     jmp   short Write_PCI_Byte
6 g5 W, @; a% u  G5 rF000:F6AB                         ; ---------------------------------------------------------------------------
* x. w  n! j. K" \8 KF000:F6AD 90                        db  90h ; ?
: M  s3 L) `" E( l2 L& FF000:F6AE B0 F6                     dw 0F6B0h
" u1 ~& N3 ?; W6 l  BF000:F6B0                         ; ---------------------------------------------------------------------------2 H3 W# @. u; f- Z1 ?2 m
F000:F6B0 B9 84 3B                  mov   cx, 3B84h
# o7 T5 X2 l9 r: m, TF000:F6B3 B0 07                     mov   al, 7" M) ~( r$ K2 H2 R) P, l
F000:F6B5 BC BB F6                  mov   sp, 0F6BBh
2 F; y0 o( {$ P3 e3 {F000:F6B8 EB 68                     jmp   short Write_PCI_Byte6 y7 e) S% x/ X8 [* j% z3 [
F000:F6B8                         ; ---------------------------------------------------------------------------
5 j9 G  D5 N  |+ K- EF000:F6BA 90                        db  90h ; ?. j% a1 J5 V8 H% }7 H
F000:F6BB BD F6                     dw 0F6BDh' ~( a. n) R4 ]; D8 R
F000:F6BD                         ; ---------------------------------------------------------------------------' |7 y( j% z! B* X7 ^1 r
F000:F6BD                         exit:                       ; CODE XREF: Chipset_Reg_Early_Init+94j
$ _) D& _! K' D) B, T8 e; ~/ e$ {F000:F6BD 66 C1 EC 10               shr   esp, 10h
! H4 U6 ~) P* B' f0 A1 v0 UF000:F6C1 C3                        retn! }; t! I( T1 y/ Z
F000:F6C1                         Chipset_Reg_Early_Init endp
. o2 r3 r* `+ a4 u- O. v.........
3 z$ H+ p3 P. u% J! x5 {& RF000:F6C4                         Begin_Chipset_Reg_Val
" Z5 u1 W* g( ?5 o' ^) OF000:F6C4 47 38                     dw 3847h                  ; bus#0 dev#7 func#0: PCI2ISA Bridge reg 47h
/ u7 S3 w6 Y) ?$ oF000:F6C6 BF                        db 0BFh                   ; disable PCI delay transaction2 e) c2 ?1 [2 Z3 T3 r& j6 w
F000:F6C7 A0                        db 0A0h                   ; - Use INIT as CPU Reset1 S. C3 \9 Y' z2 K  N' Z& h
F000:F6C7                                                     ; - Enable (ports 4D0-1 per EISA specification)/ p7 m* S* _: t6 M( ?7 A! w, P
F000:F6C7                                                     ;   M9 i/ r+ ]; d7 c+ u. D
F000:F6C8 50 00                     dw 50h                    ; Host Bridge reg 50h Request Phase Control
8 {! X# ^( C: w7 [  x$ R; s4 ?F000:F6CA FF                        db 0FFh                   ; and mask0 R7 j. U& |( {; a
F000:F6CB 10                        db 10h                    ; enable Defer Retry When HLOCK Active& O4 x, P9 O9 t. V
F000:F6CB                                                     ; $ i0 U5 K8 f1 F" a# G0 }
F000:F6CC 51 00                     dw 51h                    ; Host Bridge reg 51h Response Phase Control/ \9 A) F( \+ s5 M! j! f9 n, R8 h% H
F000:F6CE DD                        db 0DDh                   ; reset reserved bits8 h# \) z9 y8 S0 H# {) r) u1 A
F000:F6CF 0D                        db 0Dh                    ; enable:
, ~' y) q5 N% y9 z+ k7 |F000:F6CF                                                     ; - Non-Posted IOW
8 q$ i; |- w8 y' Q7 nF000:F6CF                                                     ; - Concurrent PCI Master / Host Operation
' t/ g; W7 _7 @) O# M  C1 |% g( k/ MF000:F6CF                                                     ;
: K, [6 c4 V$ ]7 V7 l  FF000:F6D0 52 00                     dw 52h                    ; Host Bridge reg 52h Dynamic Defer Timer2 \+ A. k- |# h! x( D
F000:F6D2 E0                        db 0E0h                   ; disable dynamic defer
" X! I+ V* _/ U' @& R1 u- o0 V/ VF000:F6D3 08                        db 8                      ; snoop stall count = 8
( H! N) T9 [! oF000:F6D3                                                     ; " O; t2 i' [. e- K5 S+ q. P/ s# ^
F000:F6D4 6B 00                     dw 6Bh                    ; Host Bridge reg 6Bh DRAM Arbitration Control: Q! i; ^" `* b7 @" _- }
F000:F6D6 00                        db 0                      ; - Park at last bus owner) X2 O9 P  w. ^5 m# r: G
F000:F6D6                                                     ; - Disable Fast Read to Write turn-around
* f# b4 `6 a3 DF000:F6D6                                                     ; - Memory Module Configuration - Normal Operation
+ r$ a! X6 \1 Q6 {F000:F6D6                                                     ; - MD Bus 2nd Level Strength Control = Normal Slew rate
, f: l0 q* e& R3 g) f1 d. DF000:F6D6                                                     ; - CAS Bus 2nd Level Strength Control = Normal Slew rate
2 Y: a1 D  m+ m1 |: p; U; ^F000:F6D6                                                     ; - VC-DRAM disable
6 z) @$ _: ~# B, {F000:F6D6                                                     ; - Multi-Page Open disable
9 e& z8 X) H( x+ {7 w' H0 H% t7 RF000:F6D7 01                        db 1                      ; Enable Multi-Page Open6 ^1 B& T  a( v* w
F000:F6D7                                                     ; , }$ i) |( H! b9 i5 u
F000:F6D8 71 00                     dw 71h                    ; Host Bridge reg 71h CPU to PCI Flow Control 18 Q! ?/ g5 P& e
F000:F6DA 00                        db 0                      ; Disable:
6 i# _$ d& r. V/ n5 B7 b% _; \F000:F6DA                                                     ; - Dynamic Burst
0 ]* a* s$ E0 x3 ^  a7 D, n, M# CF000:F6DA                                                     ; - Byte Merge
, x5 n! `7 Q' o3 v5 I& P& Z1 NF000:F6DA                                                     ; - PCI I/O Cycle Post Write$ G+ V6 B! r. M0 {
F000:F6DA                                                     ; - PCI Burst- Z+ Y1 V" m* s* b' {
F000:F6DA                                                     ; - PCI Fast Back-to-Back Write
: F( U( K5 q# H# h# D% \4 eF000:F6DA                                                     ; - Quick Frame Generation% C. _8 Y1 @" }0 N$ z
F000:F6DA                                                     ; - 1 Wait State PCI Cycles( U7 ]/ [8 @; T; O  q9 D' q# O: `
F000:F6DB 08                        db 8                      ; Enable PCI Burst# b- S# ]4 k, v: I( e
F000:F6DB                                                     ; $ J, V! j- _7 Q" T% p  E
F000:F6DC 75 00                     dw 75h                    ; Host Bridge reg 75h PCI Arbitration 1
; j% k) R1 G5 F$ wF000:F6DE 00                        db 0                      ; - PCI has priority
& Z% e$ M, ?  l/ @- Z% b0 R/ U& DF000:F6DE                                                     ; - REQ-based (arbitrate at end of REQ#)
4 e6 T2 I$ p0 Q2 Y- P% ~5 O& ]F000:F6DE                                                     ; - Disable PCI Master Bus Time-Out
0 W  m0 o% Y- O9 \0 s- tF000:F6DF 80                        db 80h                    ; Fair arbitration between PCI and CPU
1 J2 A  n) ?# cF000:F6DF                                                     ;
# y6 J7 U( t, Q+ }F000:F6E0 76 00                     dw 76h                    ; Host Bridge reg 76h PCI Arbitration 2; j/ s- Z1 ]& v; g: h
F000:F6E2 CF                        db 0CFh                   ; and mask
! x; l8 v; E* N/ i; ^8 g7 l, r: XF000:F6E3 80                        db 80h                    ; or mask/ i/ @5 W2 _# c$ y; ^
F000:F6E3                                                     ; ; b! h9 J0 \4 `" y
F000:F6E4 41 38                     dw 3841h                  ; bus#0 dev#7 func#0: PCI2ISA Bridge reg 41h - ISA Bus control
/ _) }4 p# o. x9 `4 ^F000:F6E6 FF                        db 0FFh                   ; and mask' f- P0 v1 O8 }4 X9 X
F000:F6E7 01                        db 1                      ; ROM Write Enable1 L2 L$ A. ~+ e( K6 r/ K
F000:F6E7                                                     ; 0 r9 p" I! c0 C
F000:F6E8 43 38                     dw 3843h                  ; bus#0 dev#7 func#0: PCI2ISA Bridge reg43h-ROM Decode Control5 P+ {& P4 ?  k" y* p8 r+ y
F000:F6EA 00                        db 0                      ; Disable ROMCS# decode for all ranges* o1 L8 O$ h; C8 E) @4 H: Y
F000:F6EB 30                        db 30h                    ; Enable ROMCS# decode for the following ranges:
' F9 U7 V8 t/ p6 E! |+ W, PF000:F6EB                                                     ; 1. FFF00000h-FFF7FFFFh9 t1 p9 M* \- ]- }
F000:F6EB                                                     ; 2. 000E0000h-000EFFFFh- `8 w/ l2 |6 R1 c/ Q' }
F000:F6EB                                                     ;
, I7 O, u2 r: S# y& JF000:F6EC 4A 38                     dw 384Ah                  ; bus#0 dev#7 func#0: PCI2ISA Bridge reg4Ah-IDE Interrupt Routing
! _! M" z3 h- b8 L5 bF000:F6EE FF                        db 0FFh                   ; and mask0 D5 N) a) X/ v9 ]2 G( {
F000:F6EF 40                        db 40h                    ; Access ports 00-FFh via SD bus (applies to
# A1 y3 Z# u5 PF000:F6EF                                                     ; external devices only; internal devices such as, W1 e8 U2 X6 P! {, A
F000:F6EF                                                     ; the mouse controller are not effected)9 ]) Y, u5 ?: M( s! r$ o# W
F000:F6EF                                                     ;
5 E) N' B+ n- \9 qF000:F6F0 5A 38                     dw 385Ah                  ; bus#0 dev#7 func#0: PCI2ISA Bridge reg5Ah-KBC / RTC Control3 v( H7 P; M) R7 h8 _6 W5 F  E
F000:F6F2 F8                        db 0F8h                   ; Disable:
# V) K( M6 }- y/ z) xF000:F6F2                                                     ; - Internal RTC
* f* C* h1 {; c* z1 n- j0 F- YF000:F6F2                                                     ; - Internal PS2 Mouse
' ~" ]* R! R* `5 e: ?; [( jF000:F6F2                                                     ; - Internal KBC
9 b- g: a# e6 j  G+ }1 uF000:F6F3 04                        db 4                      ; Internal RTC Enable1 m$ n- ]( F. G( D  Y6 D6 B6 Q. A
F000:F6F3                                                     ;
9 g+ X. ^: |1 d: Y% uF000:F6F4 48 3B                     dw 3B48h                  ; B#0 D#7 F#3: PwrMngmt&SMBus - PwrMngmt IO Base Addr lo_byte4 d5 T: e9 S1 b# V
F000:F6F6 00                        db 0                      ; and mask
" k  _0 ?: K, o" g" I  {8 ?F000:F6F7 00                        db 0                      ; or mask
0 @9 A  j9 S8 [: f  XF000:F6F7                                                     ;
0 q9 ~, D+ X- D7 g& i) HF000:F6F8 49 3B                     dw 3B49h                  ; B#0 D#7 F#3: PwrMngmt&SMBus - PwrMngmt IO Base Addr hi_byte4 h% J6 [# l9 A/ k6 J- @( z
F000:F6FA 40                        db 40h                    ; and mask. Z5 S4 `7 x) L& o
F000:F6FB 40                        db 40h                    ; PwrMngmt IO Base Addr = IO Port 4000h
! M* X! D1 N' x, Q+ ~F000:F6FB                                                     ;
6 O% b" t) Q# e, e4 A( j, `+ \F000:F6FC 41 3B                     dw 3B41h                  ; bus#0 dev#7 func#3: PwrMngmt&SMBus - General Config* A8 D, I. Y( g* D
F000:F6FE FF                        db 0FFh                   ; and mask
+ F/ x5 X# X" Q, z2 \  jF000:F6FF 80                        db 80h                    ; enable: I/O for ACPI I/O Base1 Q, Y* E+ o0 R, W  x3 D, u$ V
F000:F6FF                                                     ;
( R8 \8 C6 z" d7 l' g9 kF000:F700 76 38                     dw 3876h                  ; bus#0 dev#7 func#0: PCI2ISA Bridge reg76h-GPIO/Chip Select Control
0 X7 G# s; t. ]  v& hF000:F702 00                        db 0                      ; Disable GPO 24-26
  Q$ A# O& C' d5 q5 f. DF000:F703 02                        db 2                      ; Enable GPO 259 e, a4 w8 N& r/ l, T2 q9 Q; E+ i
F000:F703                         End_Chipset_Reg_Val2 N2 R  B( s3 x& S# U1 g
  I9 o4 D2 Z4 X+ ~! `
7.1.3. Init_Interrupt_n_PwrMgmt routine ! q6 i% {" c4 d5 Q4 q, q2 a
Address    Hex                       Mnemonic
6 G3 H4 [0 Q* F6 N: t2 z$ i5 O1 YF000:E1A0 BF A6 E1                  mov   di, 0E1A6h          ; ret addr below- g0 W+ v( r3 _$ `+ V4 g+ E# M
F000:E1A3 E9 42 99                  jmp   Init_Interrupt_n_PwrMgmt5 h6 U# h: f  b' H3 ]9 J. b. a
F000:E1A6                         ; ---------------------------------------------------------------------------* `* ~4 Q: P' ^2 W0 k) o8 w  B' N+ U  K
F000:E1A6 B0 C1                     mov   al, 0C1h ; '+'
, I7 n2 Y4 F% \# ?+ ]....
9 V9 }+ w1 w  e+ }F000:7CDD                         delay:                      ; CODE XREF: Init_Interrupt_n_PwrMgmt:delay
: S2 Z  O, d! K' Z1 x+ m- Z' rF000:7CDD E2 FE                     loop  delay
1 j- {$ E, h6 S5 iF000:7CDF FF E7                     jmp   di                  ; jmp to F000:E1A6h% p4 s# ?, g8 u4 s* ?) y
F000:7CDF                         Init_Interrupt_n_PwrMgmt endp* q) {; |0 q' @9 A- A$ S9 f
( d' a5 `+ p4 p; S
7.1.4. Call To "Early Silicon Support" Routine   y* P8 m5 c! ?! r5 f
Address    Hex                       Mnemonic
9 @# f' J+ \& j% i  EF000:E1AD E9 47 02                  jmp   Search_BBSS_Signature
6 S; R4 |' M1 f0 \* m. CF000:E1AD                         ; ---------------------------------------------------------------------------
! J0 {! `, H7 z+ E9 A0 fF000:E1B0 B2 E1                     dw 0E1B2h& \9 G" j1 m8 u, {) Q5 F
F000:E1B2                         ; ---------------------------------------------------------------------------
% `3 y1 U- Z! V& N0 b- o4 |! aF000:E1B2 0B F6                     or    si, si
" s( \0 B- p4 M/ ?F000:E1B4 74 38                     jz    short _BBSS_not_found
9 M/ y; c7 n$ ~F000:E1B6 8B DE                     mov   bx, si ;checksum start here
+ m- |" [4 _3 m. r- ~F000:E1B8 2E 8B 04                  mov   ax, cs:[si]; t+ e, l& @+ m1 G* L: z
F000:E1BB 25 00 F0                  and   ax, 0F000h
- _% A2 J+ {% F% E6 _. T+ \F000:E1BE C1 E8 04                  shr   ax, 4! J3 Z( I& a+ |& J2 W
F000:E1C1 05 00 F0                  add   ax, 0F000h/ n8 ^$ @0 H9 @7 U& `) U8 g6 D* h0 g
F000:E1C4 8E D8                     mov   ds, ax              ; ds=base addr for calculation of BBSS checksum
% v6 G9 }1 J7 |/ y4 zF000:E1C6                           assume ds:nothing# |  ?) s* {8 o9 v  c. }9 N' w5 E
F000:E1C6 32 E4                     xor   ah, ah6 j6 W; f6 p$ |: T+ C6 s. J& f
F000:E1C8 33 F6                     xor   si, si
3 o- Z/ B* X( t5 vF000:E1CA B9 FF 0F                  mov   cx, 0FFFh           ; length of BBSS4 [) h' |& w$ O6 `& _
F000:E1CD                         next_byte:                  ; CODE XREF: 000FE1D0 j6 s# ]; F- P' m! _
F000:E1CD AC                        lodsb* t$ x3 @" Q! H
F000:E1CE 02 E0                     add   ah, al              ; calc 8-bit chksum for BBSS
1 Z4 @, T8 I8 f5 H6 h( u; O) TF000:E1D0 E2 FB                     loop  next_byte2 |' S! Y; }( z" w* D- G/ Q9 }( Z. ]
F000:E1D2 3A 24                     cmp   ah, [si]
/ s. Y' e: Z! qF000:E1D4 75 18                     jnz   short _BBSS_not_found
4 t, D7 m2 y  ~0 _: L$ W9 XF000:E1D6 2E 8B 07                  mov   ax, cs:[bx]         ; chsum ok, jump to (exec) the BBSS engine. _, M7 \5 C( }& ?: \1 U( F
F000:E1D9 25 00 F0                  and   ax, 0F000h
* N; }# ^( R; }" Q$ l; G5 V0 S1 {F000:E1DC 8B F0                     mov   si, ax
3 h* n: [8 Y& G* t( Z+ H, g  {F000:E1DE 81 C6 FC 0F               add   si, 0FFCh
3 ?/ h# S& G* k! w9 OF000:E1E2 2E 8B 34                  mov   si, cs:[si]7 S( [/ {7 U* B% ~6 T) g
F000:E1E5 BC EC E1                  mov   sp, 0E1ECh
5 \+ Y+ s! K  Z) @0 ?) h7 A, E( X$ EF000:E1E8 FF E6                     jmp   si                  ; jmp to F000:60B4h (BBSS Engine), returns at F000:E1F8h, ?' C! e- |2 E
F000:E1E8                                                     ; the BBSS engine is silicon support routine, used to
# N, v( B0 W; D6 \F000:E1E8                                                     ; initialize PwrMgmt GPIO Ctlr, Host Ctlr and DRAM Ctlr
6 `6 o" x8 \/ X5 DF000:E1E8                         ; ---------------------------------------------------------------------------6 O! Q% [6 t$ h7 P
F000:E1EA 87                        db  87h ; ?
7 z/ d  z( p. N5 c3 j* m& gF000:E1EB DB                        db 0DBh ; -1 R4 c- o2 e9 v- ~
F000:E1EC F8 E1                     dw 0E1F8h/ u0 S( I/ i" v
.........3 Q0 j8 z9 ^, B& E8 y
F000:E1F8                         BBSS_exec_done:
9 p% B$ q8 n) g  s% {+ V; [F000:E1F8 B8 00 00                  mov   ax, 0
, a+ R8 F3 |) W/ L/ H. D4 B  O; H.........+ T, C' m* g# s3 f! T* G" u) }5 U
这段代码在bootblock拷贝到RAM之前执行。万一RAM有错误,系统就要halt并且从扬声器输出错误代码。
% y6 F! e8 X  p3 c7.1.5. Bootblock Is Copied And Executed In RAM " g  N7 p0 D/ E0 M; _$ `
Address    Hex                       Mnemonic
9 p) e; J, ]9 T; j. aF000:E2AA                         ;----------- Enter 16-bit Protected Mode (Flat) ------------8 E% s0 v+ |' w5 ]
F000:E2AA                           assume ds:_F000h
0 X$ w$ ?. v+ ^5 E9 O% z1 s" FF000:E2AA 0F 01 16 F6 E4            lgdt  qword ptr word_F000_E4F6
$ P4 ?1 a0 p; O! b" L% D5 J& `F000:E2AF 0F 20 C0                  mov   eax, cr0/ s6 o* s5 H8 X
F000:E2B2 0C 01                     or    al, 1
' z' r& d1 x- h, n7 V$ CF000:E2B4 0F 22 C0                  mov   cr0, eax
. H* x/ I6 k# V* [, T( u. L' f- wF000:E2B7 EB 00                     jmp   short $+2           ; clear prefetch, enter 16-bit PMode. We're! {( b- o4 r! [. P. r; _+ c
F000:E2B7                                                     ; using the "unchanged" hidden value of CS: m7 O7 a& U7 r3 C9 h: Z$ w! o
F000:E2B7                                                     ; register (descriptor cache) from previous, q: z7 y- X$ N/ N
F000:E2B7                                                     ; "PMode session" in memory_check_routine
$ ^4 _- |& w/ m0 a7 F0 cF000:E2B7                                                     ; for code segment desc. `7 F. E) `, m) ^/ Y
F000:E2B9 B8 08 00                  mov   ax, 8
/ N9 _  g, x" Q3 h5 j' [, HF000:E2BC 8E D8                     mov   ds, ax              ; init ds to 4GB-wide segment
( F6 t8 [' A( eF000:E2BE                           assume ds:nothing( u4 o! N7 u% e3 t( n4 Z6 F# ^
F000:E2BE 8E C0                     mov   es, ax              ; init es to 4GB-wide segment+ \3 ?$ t: i2 F# K$ e
F000:E2C01 b" K( ~$ x$ d8 _$ C0 k( Q7 h0 n
F000:E2C0                         There are two locations to access E0000H ROM space, one is 0E0000H
/ t9 @2 I+ T# A$ b  `F000:E2C0                         and another is 0FFFE0000H. Some chipsets can not access onboard ROM5 C- ?4 j/ ~9 A; c1 R0 S' L
F000:E2C0                         space at 0E0000H if any device also use the space on ISA bus.& w3 Y4 X( b3 V9 F1 F6 S2 Z* v9 u, y2 k7 U
F000:E2C0                         To solve this problem , we need to change address to 0FFFE0000H
! Y6 {8 H" }( g/ i' s7 e" V+ iF000:E2C0                         to read BIOS contents at 0E0000H space.
# q7 f# P& F, r- \. Z5 bF000:E2C0                           assume es:nothing0 f4 _8 j) c0 d2 K3 o* e# T
F000:E2C0 66 BE 00 00 0E 00         mov   esi, 0E0000h* m' g) ?9 V% R6 d
F000:E2C6 67 66 81 7E 02 2D 6C 68+  cmp   dword ptr [esi+2], '5hl-'
/ @$ Q) S; q! R& qF000:E2CF 74 07                     jz    short LHA_sign_OK- b9 [) p: E- x$ F2 O. K
F000:E2D1 66 81 CE 00 00 F0 FF      or    esi, 0FFF00000h
! v- l6 H) m% J5 bF000:E2D8) J9 Y! g+ W) X9 i  d2 h0 {1 I4 w
F000:E2D8                         move entire BIOS (i.e. original.tmp and bootblock)5 q, G* F# ?3 V6 Q
F000:E2D8                         from ROM at E0000h-FFFFFh to RAM at 10000h-2FFFFh0 C9 F( _1 Q4 g% x
F000:E2D8                         LHA_sign_OK:                ; CODE XREF: 000FE2CF
# U  G3 l. I, nF000:E2D8 66 BF 00 00 01 00         mov   edi, 10000h         ; destination addr = 1000:0
/ v7 W- H7 }' I/ o( A8 f7 h7 nF000:E2DE 66 B9 00 80 00 00         mov   ecx, 8000h          ; copy 128 KByte to buffer (original.tmp n Bootblock)/ h3 A1 ^0 y* x1 K! T0 c" `
F000:E2E4 67 F3 66 A5               rep movs dword ptr es:[edi], dword ptr [esi]3 ^- H/ q+ J% u: D- ~8 W" p6 S
F000:E2E8 0F 20 C0                  mov   eax, cr0
0 ?+ t* w! V' g& oF000:E2EB 24 FE                     and   al, 0FEh
$ |6 ?5 i, N7 s" r3 g3 Q* m. HF000:E2ED 0F 22 C0                  mov   cr0, eax) g0 S# _& T: W- l5 T
F000:E2F0 EB 00                     jmp   short $+2           ; leave 16-bit protected mode (voodoo mode)+ [, \8 B& q* N2 g6 w# O
F000:E2F2 EA F7 E2 00 20            jmp   far ptr _bootblock_in_RAM
6 `1 r3 \9 N' Q5 M5 {$ C! a, P.........
, A: ^0 D( N* \5 }1 L6 ]+ n; K2000:E2F7                         ; ---------------------------------------------------------------------------
) q2 J; _$ g% A# C! S' N% e2000:E2F7                         Setup temporary stack at 0:1000H, at this point
6 t0 w$ f0 A0 _/ B7 J- W( B/ r# Y2000:E2F7                         Bios code (last 128 Kbyte) is still compressed
8 s" R5 |* b# x+ d# }% u2000:E2F7                         except the bootblock and decompression code
  J. V' v0 ?$ O* _+ L2000:E2F7( G2 ~- g% z& ^: O; `
2000:E2F7                         _bootblock_in_RAM:
9 t, g% B0 h1 d2000:E2F7 33 C0                     xor   ax, ax
3 d) a1 ^" [; v2000:E2F9 8E D0                     mov   ss, ax, I5 a3 |% {+ m3 |
2000:E2FB                           assume ss:nothing
: G3 o/ ~2 [/ U8 `$ Y" A& t2000:E2FB BC 00 10                  mov   sp, 1000h
: @# s  ]. @% `6 B* K, \最后128KB的bios代码(E000:0000h - F000:FFFFh)拷贝到RAM如下:
( o3 v/ T5 Z8 v5 Q. e  1.北桥加电的时候默认把F_0000h-F_FFFFh 放入空间FFFE_FFFFh-FFFF_FFFFh 这里也是bios rom芯片的地址空间映射。那也是下马面的代码能够安全运行的原因:9 ~+ l+ M4 C$ V( G- j
Address    Hex                       Mnemonic0 @- s: y: x4 Q+ v  a! }" x4 K; R
F000:FFF0 EA 5B E0 00 F0    jmp   far ptr entry_point ; Northbridge is responsible for decoding
" a6 y; V- O) ?, v' B7 ]  I- EF000:FFF0                                         ; the target address of this jump into BIOS# j0 t: J( C! X
F000:FFF0                                         ; chip through address aliasing. So, even if- T/ K3 C3 Q! g% I* a
F000:FFF0                                         ; this is a far jump (read Intel Software 5 e5 I( s4 `& ~: V, E* @6 j  p
F000:FFF0                                         ; Developer Guide Vol.3 for info)
, i5 L' y+ S' {F000:FFF0                                         ; we are still in BIOS chip d00d ;)* P& {8 c+ W5 L3 R+ O, u2 U5 O
F000:FFF0                                         ; vi693A: FFFE_FFFF-FFFF_FFFF is 000F_xxxx alias., e. j) _* q6 ]3 n
  并且,北桥加电默认禁止这段空间的DRAM shadowing。所以读写这段区域空间就不会送到DRAM。同时,在南桥没有控制寄存器控制这个地址空间的映射。所以,对这个地址空间的读操作就会直接指向了bios rom芯片,而没有被南桥转换地址。当然,这个读操作首先通过北桥,那样应用地址重名配置。# A& x8 E$ }' H+ x
  2.非常靠近bootblock执行的开始,例程Chipset_Reg_Early_Init开始执行。这个例程重新编程PCI-to-ISA桥(在南桥中),能够编码E_0000h-E_FFFFh 地址,比如促进这个地址的读操作到bios rom芯片。北桥加电默认禁止对这个地址空间的DRAM shadowing 。所以,读写这个空间就不会写入DRAM。& a4 x0 C( q3 I
  3.然后上面的例程,拷贝bios rom芯片最后128KB(E_0000h - F_FFFFh)内容到DRAM(1000:0000h - 2000:FFFFh)中去。这个可以实现,因为这个地址空间已经用芯片映射到了DRAM中,没有特别的地址翻译。! g6 z; M3 v  s/ p2 |, I: z
7.1.6. Call to bios decompression routine and the jump into decompressed system bios
1 S# x9 y( c  H9 ZAddress    Hex                       Mnemonic- [0 q0 i- O9 N/ L
2000:E3DC E8 33 01                  call  Decompress_System_BIOS
; ~8 m, m2 ?) B- Q! u* ]2000:E3DF EB 03                     jmp   short _sysbios_chksum_ok$ G! A9 B3 i- X* e/ o. @- n& K# @
2000:E3E1                         ; ---------------------------------------------------------------------------8 t8 ~% K' t  s* D
2000:E3E1                         _sysbios_chksum_error:      ; CODE XREF: 0002E347* Z* N4 i) |8 ]4 Y8 i) ^5 B5 v. L
2000:E3E1                                                     ; 0002E350 ...! K0 ~4 ]$ }3 |# r% W% J* r
2000:E3E1 B8 00 10                  mov   ax, 1000h
6 |; C( l/ a! Z: p0 P; e2000:E3E4. g3 E8 s& v8 m$ R: Y8 G5 W
2000:E3E4                         _sysbios_chksum_ok:         ; CODE XREF: 0002E3DF4 _, e0 }/ ^+ M3 g# C& z! a! [7 ^
2000:E3E4 8E D8                     mov   ds, ax              ; ax = 5000h if decompression successful, otherwise ax = 1000h
  y; `# l! a& g# }* q" q2000:E3E6                           assume ds:_1000h
8 @5 y/ p' p& C) Z2000:E3E6 B0 C5                     mov   al, 0C5h ; '+': b# u0 [/ a$ [5 D7 D
2000:E3E8 E6 80                     out   80h, al             ; manufacture's diagnostic checkpoint
- G7 O1 ]/ Z* B5 f+ ?; F7 Q2000:E3EA
2 k# d2 l; {' g( c% x2000:E3EA                         The source data segment is 5000H if checksum is good.0 F7 W- R  N% _' h6 l
2000:E3EA                         the contents in this area is decompressed by routine "Decompress_System_BIOS".
- v* g+ V/ D3 |) [2 I- M" f& k) K8 P2000:E3EA                         And segment 1000H is for shadowing original BIOS image if checksum
: R& v$ V8 Z( z  [# _, {# ]  F2 c) X2000:E3EA                         is bad. BIOS will shadow bootblock and boot from it.9 A' o' H- S) u  G. N0 p
2000:E3EA E8 87 EB                  call  Copy_Decomprssd_E_n_F_Seg ; relocate dcomprssed from decompression seg to
# _. c# X+ S+ m+ o2000:E3EA                                                     ; E_n_F_seg in RAM (Shadow the system BIOS)- Y( o3 H5 T: P3 ~& {. b. ^- y2 ?
2000:E3ED B0 00                     mov   al, 02 `. p5 A$ A  n5 a5 r4 K
2000:E3EF E8 C7 10                  call  Setup_Cpu_Cache
8 f: C8 F7 X4 \* R/ Y3 {) A/ N2000:E3F2
3 E: R5 L) M! R- ]3 B( D2000:E3F2                         BIOS decide where to go from here.9 i; G( B6 {+ k# |
2000:E3F2                         If BIOS checksum is good, this address F80DH is shadowed by
0 {3 q! X1 ~8 w1 W6 ?6 u/ n* e2000:E3F2                         decompressed code (i.e. original.bin and others),4 w3 a9 ~) N8 m8 r$ a. o
2000:E3F2                         And "BootBlock_POST" will be executed if checksum is bad.
) j& Q+ O2 |$ g1 x; Y3 x2 a& E2000:E3F2 EA 0D F8 00 F0            jmp   far ptr loc_F000_F80D ; jump to decompressed system BIOS (F_seg) in RAM if decompression
* B% U. a' a9 k& q. k2000:E3F2                                                     ; successful, otherwise jump to bootblock at the same address if
/ h8 a0 e5 n  o( P2000:E3F2                                                     ; decompression failed.2 [# n+ q7 }: _
8 R9 B# Q$ p0 d' t( `
  在执行例程Decompress_System_BIOS时,在RAM地址1000:0000h - 2000:FFFFh中的bios code(original.tmp)解压到了RAM中的5000:0000h - 6000:FFFFh 。这个解压了的system bios然后重新定位到了RAM中的E000:0000h - F000:FFFFh 。尽管如此,如果这个解压进程失败了,当前压缩的E_seg和F_seg定位到了RAM中的1000:0000h - 2000:FFFFh (包括在RAM中的bootblock)将要重新定位到RAM中的E000:0000h-F000:0000h ,然后bootblock错误处理代码就要运行了。注意那个问题是由于地址混淆,并且在重新定位时DRAM shadowing被通过设置一个适当的芯片寄存器而处理。下面是这个例程基本run-down:
5 y$ M" N9 ], [7.1.6.1. Enable FFF80000h-FFFDFFFFh decoding
9 b; O1 Z$ ]$ P5 L4 O' e  1.使能FFF80000h-FFFDFFFFh解码。对这个地址的访问就会通过PCI-to-ISA桥直接到bios rom芯片。PCI-to-ISA 桥rom解码控制寄存器在这里管理。这是必要的,所以我的256KB的bios芯片只有128KB是拷贝到RAM中的,比如original.tmp和bootblock目前正在地址1000:0000h-2000:FFFFh上。2 ?! X/ V3 n6 @2 F2 E
7.1.6.2. Copy lower 128KB of BIOS code from ROM chip into RAM ) w+ ?$ D" o/ ^$ A
  2.拷贝低128KB的bios代码,从ROM芯片中的FFFC_0000h-FFFD_FFFFh到RAM中8000:0000h - 9000:FFFFh。' f6 h3 S; ^/ ^5 \2 V
7.1.6.3. Disable FFF8_0000h-FFFD_FFFFh decoding ; q) _, `- g9 D0 `5 w8 B$ L4 _
  3.禁止FFF8_0000h-FFFD_FFFFh解码。这个地址的访问将不会通过PCI-to-ISA桥到bios rom芯片中去。
; `+ }% R+ F- ]( k& o8 S7.1.6.4. Verify checksum of the whole compressed BIOS image ; }4 k- E- v' b/ ?  L. ~
  4.改变整个bios映像的checksum。计算在内存RAM中的压缩的8bit的checksum(比如8000:0000h - 9000:FFFFh + 1000:0000h - 2000:7FFDh),并且和储存在2000:7FFEh的值比较结果。如果8bit不匹配,那么goto _sysbios_chksum_err ,否则继续解压缩例程。 * d- g* i9 ~* y; S. n* ]. s- [4 Y
7.1.6.5. Look for the decompression engine
' M$ [. Z& o0 U0 ]  5.在段2000h 通过搜索*BBSS*来查找解压引擎。
# \) u8 ?8 [/ Y8 y; u+ W9 {9 N% F. X7.1.6.6. Decompress the compressed BIOS components 7 c: s; f# B2 p+ }* G4 E' v% G
  6.通过调用上面的解压引擎,解压缩压缩了的bios部分。注意这一步中,只有original.tmp和它的扩展(awardext.rom)被解压(其他的版本的awardext.rom也可能适用,我没有验证)。另外的部分通过其他方式处理。这个解压例程至处理他们自己的解压和压缩区域,并把他们放入RAM中的某些地方。我们需要一些预备信息,在深入研究这一步之前:
9 d* ?5 ^1 d* ^- I) F& P- B. R7.1.6.6.a. The format of the LZH level-1 compressed bios components # Y( e  c4 o3 k" V$ w
  A.LAH level-1压缩bios部分格式。这些bios部分在解压缩之后的地址范围也是这样的结构。结构如下(适用于所有的压缩部分):
. h6 T# d- K* vOffset from 1st byte  Offset in Real Header  Contents$ m, m# {' I+ i7 z
00h  N/A  The header length of the component. It depends on the file/component name.* `4 `+ O+ l+ r3 x
01h  N/A  The header 8-bit checksum, not including the first 2 bytes (header length and header checksum byte).0 K+ i3 H0 f. u3 ]- J9 G
02h - 06h  00h - 04h  LZH Method ID (ASCII string signature). In my BIOS it's "-lh5-" which means: 8k sliding dictionary(max 256 bytes) + static Huffman + improved encoding of position and trees.6 ^/ H# F) w) i0 G6 w$ O
07h - 0Ah  05h - 08h  compressed file/component size in little endian dword value, i.e. MSB at 0Ah and so forth2 |8 O" {: n7 E
0Bh - 0Eh  09h - 0Ch  Uncompressed file/component size in little endian dword value, i.e. MSB at 0Eh and so forth5 W# i+ |9 @! v4 W* v
0Fh - 10h  0Dh - 0Eh  Decompression offset address in little endian word value, i.e. MSB at 10h and so forth. The component will be decompressed into this offset address (real mode addressing is in effect here).% p/ d9 z# y) _8 ^/ t
11h - 12h  0Fh - 10h  Decompression segment address in little endian word value, i.e. MSB at 12h and so forth. The component will be decompressed into this segment address (real mode addressing is in effect here).# }6 B% h- X1 Q9 e: |  {7 n4 E! f
13h  11h  File attribute. My BIOS components contain 20h here, which is normally found in LZH level-1 compressed file.( f6 h5 L. U5 v$ A2 a1 z8 M
14h  12h  Level. My BIOS components contain 01h here, which means it's a LZH level-1 compressed file." i& f& c1 L& m3 o# A6 u
15h  13h  component filename name length in byte.
% }- f* V: w' P/ u/ e0 t1 b16h - [15h+filename_len]  14h - [13h+filename_len]  component filename (ASCII string)# H% E5 E! E+ R' J4 x
[16h+filename_len] - [17h+filename_len]  [14h+filename_len] - [15h+filename_len]  file/component CRC-16 in little endian word value, i.e. MSB at [HeaderSize - 2h] and so forth.
: P& i0 \  Q: W$ E8 p+ z8 m' F[18h+filename_len]  [16h+filename_len]  Operating System ID. In my BIOS it's always 20h (ASCII space character) which don't resemble any LZH OS ID known to me.
% W) k; A) h) p5 u$ o4 f[19h+filename_len] - [1Ah+filename_len]  [17h+filename_len] - [18h+filename_len]  Next header size. In my BIOS it's always 0000h which means no extension header., S; c+ W( a* E% Z5 K$ B) z
注意:' W/ h' l1 R8 I1 |# P) y3 e; w
1.上面最左边的和在列中用到的地址是从部分的第一个字节计算的。这个“真正头部偏移”就像上面解释得的“便签RAM”使用。3 s9 @, ~( Y; r+ j( j
2.每一个部分结束是EOFbyte,比如00h byte。# ^! m2 @7 R" ?7 ]* d
3.在我的bios中,有read_header例程,包含读写这个头部内容的例程。访问Calc_LZH_hdr_CRC16 有一个关键“procedure call”,它读出这个bios部分头部到“便签本”RAM中,从3000:0000h (ds:0000h)开始。这个便签本区域由"real-LZH-header value"填充,没有包含最前面的2bytes(头大小,头8bit校验和),但是包含了第三byte(offset 02h)直到HeaderSize+02h。. V* `3 @, J5 r& q2 t
7.1.6.6.b. The location of various checksums # v0 V$ I9 b, t
B.解压前和解压时的不同的checksum位置:! d9 f$ E8 _! a" k2 N! I3 U1 T
Location  Calculation Method2 \8 g2 P7 x* ?
Right after compressed original.tmp  original.tmp 8-bit checksum. This value is calculated after it's copied to RAM at segment 1000h and 2000h. The code as follows : 2 b2 j9 v" {- p# p" p
Address    Assembly Code
3 |2 x: R% e6 j; t+ u8 P2000:E307 ;verify System_BIOS checksum, h/ D4 y: p2 O: f1 p: q
2000:E307   mov   ax, 1000h  f' T* `' j7 E: f/ w- A
2000:E30A   mov   ds, ax              ; ds = E_seg_in_RAM5 \* E( M1 ^5 _. [
2000:E30C   assume ds:_1000h
$ ]8 a+ g% k8 n- p( e2000:E30C   mov   bx, cmprssd_size_hi_word
' u/ L, o- J+ |: C. k( M; U9 E2000:E310   mov   cx, cmprssd_size_lo_word
3 x" ~; Q. ?  C; N4 h8 c# M( I2000:E314   add   cl, hdr_len         ; cl = LZH hdrlen
% z0 b/ a/ I4 Y* ?2000:E318   adc   ch, 0
( L1 @4 u, c$ P* t5 p( z2000:E31B   adc   bx, 0+ D0 g! {) X5 k9 h- c% `! u3 D2 h+ N
2000:E31E   add   cx, 3. N+ P( M. x7 `; `" Q9 Z
2000:E321   adc   bx, 0
) \6 N  e& a8 J$ a/ s2000:E324   jz    short hi_word_zero
' C; N4 C0 X3 w0 v. h2000:E326   mov   bx, cx
! W' u$ u- Z9 ?! T2 w" U2000:E328   xor   cx, cx
" [7 v1 c# Y" n* k& Z2 Y; b2000:E32A hi_word_zero:               ; CODE XREF: 0002E324
! E0 c( w+ @# d5 c) C2000:E32A   xor   si, si1 v' C" E' {& O, M/ x) Y( c5 q8 \
2000:E32C   xor   ah, ah% _2 N' w9 Q9 N+ p5 q" x9 D
2000:E32E _next_byte:                 ; CODE XREF: 0002E331 0002E343
0 Q8 S" }, a1 B7 b' o% h( J2000:E32E   lodsb1 E; `& v5 ^! @( O/ {; i, C4 A! u2 p
2000:E32F   add   ah, al- Y# U- g$ A, q% [6 u
2000:E331   loop  _next_byte4 \1 s* c1 L. S& V
2000:E333   or    bx, bx              ; compressed BIOS bigger than 64kb ?
1 E: ^7 b6 G# T, B& [+ n6 U2000:E335   jz    short cmp_chksum! [1 u* C* [, m3 ?+ u
2000:E337   mov   cx, bx; A2 ?# l6 |1 y7 Z- }% ?5 \* S6 d
2000:E339   mov   bx, ds% t, x* O* [# g* H! h0 z8 o
2000:E33B   add   bx, 1000h           ; proceed to F_seg in RAM
4 q& E9 A$ P. b) s6 ~2000:E33F   mov   ds, bx4 L* ]9 R+ i* V% o9 I
2000:E341   assume ds:_2000h
% f0 e; X% c& {  x) y- X) B2000:E341   xor   bx, bx
3 J( ?0 X3 ]  i+ ^/ N. b2000:E343   jmp   short _next_byte- d0 q" |5 R0 c8 y3 w/ @
2000:E345 ; ---------------------------------------------------------------------------5 e5 m4 E' C& i+ c
2000:E345 cmp_chksum:                 ; CODE XREF: 0002E335: |+ ~% T8 L/ F3 Q; i5 v
2000:E345   cmp   ah, [si]            ; cmp calc-ed original.tmp chksum with& t5 J( O6 N+ N. t) ^2 _
2000:E345                             ; chksum in BIOS image. A  ^, D3 ~: i6 c& O% \" {
2000:E347   jnz   _sysbios_chksum_error
5 B: m" C" l  TRight after the decompression engine  This is the 8-bit checksum of the decompression engine which starts at F000:7000h (2000:7000h after copied to RAM) in my BIOS. I guess this is the thing that some people call Decompression Block. The code as follows: 0 M, r) l% F: g# n! a+ ^
Address    Assembly Code  ^4 Y7 m) f% y3 m8 d, ~& Y5 j
2000:E35E ; Verify checksum of decompress engine
2 o7 M; k7 t3 h2 N- L5 |% z! `2000:E35E   mov   ds, ax              ; ds = 2700h (2000:7000h)
* x( w! T8 |6 _* Q# E3 Q. ?2000:E360   assume ds:nothing
2 `8 b" H5 a0 j1 x7 [+ Y$ i: i2000:E360   xor   ah, ah
* G/ |. G% s2 B% X. N, O, i2000:E362   xor   si, si6 `4 y/ l0 o( R, I  b
2000:E364   mov   cx, 0FFFh           ; cx = size of BBSS_engine (4KB-1)
) S& B4 m8 D4 D: s+ n. _9 }2000:E367 __next_byte:                ; CODE XREF: 0002E36A3 U* Z' u7 b! B" }2 p
2000:E367   lodsb
/ b0 _% w; j$ }9 ~2000:E368   add   ah, al
3 ^% R# c- c. ~- b2000:E36A   loop  __next_byte
% J( x6 q( k1 J# R2000:E36C   cmp   ah, [si]            ; decompression engine chksum OK ?8 a4 m) ^; v6 N7 l, k6 h6 y# e
2000:E36E   jnz   short _sysbios_chksum_error
* w. u0 L  M8 u1 byte before decompression engine checksum (that's explained above)  This is the 8-bit checksum of all compressed BIOS plus the 8-bit checksum of the decompression engine (not including its previously calculated checksum above). The code : % C6 b/ t; z8 S8 X& u# {
Address    Assembly Code
# r3 K. e1 h! j# T2000:E512   call  Copy_C_seg_n_D_seg  ; copy lower 128 KByte bios code from ROM (at FFFC_0000h -" `: `$ `- r+ o# y8 t' Z
2000:E512                             ; FFFD_0000h) to RAM (at 8000:0000h-9000:FFFFh); T5 e" k1 M( f# H
2000:E515   xor   ah, ah
+ R# L/ F3 G5 h. `: N" J# a2000:E517   xor   cx, cx& `  v$ n% X4 m  k
2000:E519   mov   bx, 8000h
% U1 G& @+ H" K0 C# d/ ~8 v2000:E51C   mov   ds, bx              ; ds = 8000h, contains compressed1 O  W) A) q$ ^
2000:E51C                             ; lower 128KB bios components (awdext,etc.)) f4 a9 O" O6 A( J  ~& d
2000:E51E   assume ds:nothing7 W! B. j) C/ j" s' R5 [- N+ U: L: {
2000:E51E   xor   si, si
( l1 ^7 c/ R/ a- W  x6 C2000:E520 next_Cseg_Dseg_byte:        ; CODE XREF: Decompress_System_BIOS+11' T( a: a+ L1 d3 f
2000:E520                             ; Decompress_System_BIOS+1F
1 v% g5 U% O3 H9 y& j5 s" T5 E2000:E520   lodsb
+ e6 n8 N2 _! p6 ]8 }% U2 ~* R2000:E521   add   ah, al              ; calc 8-bit chksum of C_seg n D_seg9 ^" c7 k0 Y5 Q0 x$ e% {' s
2000:E523   loop  next_Cseg_Dseg_byte/ [7 _6 G# A- z6 G! A3 m! U
2000:E525   mov   bx, ds4 Z% y& G5 v, x, r- g7 e! v6 I
2000:E527   cmp   bh, 90h ; '?       ; are we in seg 9000h?
# z) p) k. I6 N4 E* Z/ i+ r2000:E52A   jnb   short done
+ r# O4 m' \$ c, o2000:E52C   add   bh, 10h             ; move to next higher segment5 @; q3 u; B8 m1 Y! q% i2 u" I
2000:E52F   mov   ds, bx( m2 S9 B1 g; I& z
2000:E531   assume ds:nothing
. Q4 o$ t' t" X0 X9 H/ x2000:E531   jmp   short next_Cseg_Dseg_byte
: A2 F" M% W2 C" w- Z' E4 @$ z: @2000:E533 ; ---------------------------------------------------------------------------  }5 }, O0 {" u9 m  z
2000:E533 done:                       ; CODE XREF: Decompress_System_BIOS+184 x* G4 V# N* v3 m9 O& G
2000:E533   mov   bx, 1000h4 A, ~6 m* n4 \. C) j
2000:E536   mov   ds, bx              ; ds = start_addr_of E_seg n F_seg in RAM
6 r/ M  h8 R+ d8 m2000:E536                             ; (compressed original.tmp + bootblock); K$ O  h  Y- I# v
2000:E538   assume ds:_1000h
; v+ ]% e3 _: {2000:E538   xor   si, si
$ D7 a' q- Y& W, @! N2000:E53A   cld
0 g: s7 Q1 ?9 |2000:E53B next_Eseg_Fseg_byte:        ; CODE XREF: Decompress_System_BIOS+2C
4 H, J  Z7 G3 u# G( e1 ?2000:E53B                             ; Decompress_System_BIOS+3B# u3 P/ b2 a8 W
2000:E53B   lodsb
1 f& D2 c% R% Z; S: H2000:E53C   add   ah, al              ; calc 8 bit chksum, contd from chksum above5 o' B) ^# X+ O% H& G# e( H; g$ @0 L
2000:E53E   loop  next_Eseg_Fseg_byte
" `$ [8 A& L: i. [# J2000:E540   cmp   bh, 20h ; ' '       ; are we in seg 2000h?- F" Q/ B: f1 b# C9 j8 o: e; n
2000:E543   jnb   short chksum_done4 D. s+ {. J" r+ c0 b
2000:E545   add   bh, 10h             ; move to next higher segment4 R/ k2 r8 v- e- t2 D  X" m
2000:E548   mov   ds, bx/ ?; J. ?6 L5 B0 a, R7 `3 I! p" h
2000:E54A   assume ds:_2000h
+ ?( g8 u3 _& M2 u2000:E54A   mov   cx, 7FFEh           ; amount of byte in last seg (F_seg in RAM) to calc" P6 V6 L4 Z5 l+ S1 Q, o
2000:E54D   jmp   short next_Eseg_Fseg_byte
. _/ H# {1 n! u1 @: G! v2000:E54F ; ---------------------------------------------------------------------------
% |/ F* J# W- s* N$ M' J! x2000:E54F chksum_done:                ; CODE XREF: Decompress_System_BIOS+314 K/ E! R# {8 g  S: H
2000:E54F   cmp   ah, [si]            ; cmp calc-ed chksum and chksum pointed to by [si].- e5 t" o, x, F" }- {% |0 `
2000:E54F                             ; this is the chksum for the bios binary
8 V  D- H1 J! j& L" w2000:E54F                             ; from 00000h to 37FFDh (C000:0h - F000:7FFDh)
, M6 H# d  ^, e- v2000:E551   jnz   _sysbios_chksum_error ; jmp back and continue to bootblock error handling routine
回复

使用道具 举报

 楼主| 发表于 2007-11-16 13:29:48 | 显示全部楼层
7.1.6.6.c. The key parts of the decompression routine
% M' }, L6 R2 Z# ^5 qC.解压例程的关键部分
! t& y% l( M: z2 p: w  u    Address    Assembly Code) F8 b) n# }4 \
2000:E512 Decompress_System_BIOS proc near ; CODE XREF: 0002E3DC: I( _' r% I0 h7 f% o% ~- X
.........4 ?+ F1 e6 U( D
2000:E555   mov   bx, 01 I0 p1 h2 Z: y4 ~: d8 c  f
2000:E558   mov   es, bx
$ S3 v# P8 \5 F2000:E55A   assume es:nothing
, F; ]; z0 R# H+ j& Y2000:E55A   mov   word ptr es:7004h, 0FFFFh- V, e0 p5 f# m! S
2000:E561   xor   al, al
, p8 a7 h. M* f' U7 R! I2000:E563
! d- |, V0 g, _* {% N2000:E563 ; System_BIOS Decompression started here, c  \( p9 T% i, ^! w- j
2000:E563   mov   bx, 1000h- C* h4 w+ F+ D, B9 y/ e* O- ?
2000:E566   mov   es, bx              ; es = src_seg
( [! i( E" C, I/ m2 G2000:E568   assume es:_1000h
3 s$ K  J- j+ i( v! W2000:E568   xor   bx, bx              ; bx = src_offset# s( l7 B4 H- H% \4 ?( k
2000:E56A   call  Decompress          ; on ret, CF=1 if error occured
6 k' ^5 J% t/ X$ S% D" _. T2000:E56D   jb    short sysbios_decomp_error
5 x1 E2 @+ B4 G; x0 ^. I" ^& @& Q* m2000:E56F   test  ecx, 0FFFF0000h     ; compressed component size more than 64KB?
* C" n: f, U0 X$ p# f2000:E576   jz    short sysbios_decomp_error ; jmp if compressed component size <= 64KB3 ~: ]7 ]+ X% e0 M/ k
2000:E578   mov   bx, 2000h  G) p/ F1 w4 H
2000:E57B   mov   es, bx              ; proceed2next cmprssd componnt (in next segment)
$ g' U; p& K9 V% s' H3 l1 P7 U  N  v: j2000:E57D   assume es:_2000h
) K7 p8 v' c! f* l+ g& @  e5 L. f2000:E57D   mov   bx, 1               ; bx = index to be added to previous src_offset in cx+ i8 q* J0 [) `" f6 j
2000:E580   jmp   short repeat_decompress ; decompress remaining component (1st pass jmp taken); u( a) x5 R0 \+ ?# ]2 ]
2000:E582 ; ---------------------------------------------------------------------------9 D# I. \2 I6 ]% g' X1 |
2000:E582 sysbios_decomp_error:       ; CODE XREF: Decompress_System_BIOS+5B
. `4 D6 X8 A+ z* k% ^- \2000:E582                             ; Decompress_System_BIOS+64
/ k2 x# ^9 H8 M2 R2000:E582   rcl   al, 1
5 _# ^+ b, w% C2 P. y* p' ?) y2000:E584   mov   bx, 2000h
1 z! S5 y% e5 q6 o2 N* ~2000:E587   mov   es, bx
/ I; Y/ D! p! D9 k$ ]2000:E589   xor   bx, bx- D1 C/ x6 g7 Q4 k8 D1 v+ H
2000:E58B   call  Decompress
3 d/ k9 O+ i) \+ Q* a2000:E58E   rcl   al, 1
, d8 B, M) G! `# y$ @2000:E590   cmp   al, 32 {# \; ~4 j( N! {& [! k7 E
2000:E592   jnz   short decompress_successfull
4 m6 T1 x: Q6 I* s/ T% _0 b4 u2000:E594   mov   ax, 1000h
+ C( U* @; b4 Y* h2000:E597   stc
' F7 o3 t2 k# y9 c0 `2000:E598   retn( N8 D% X0 x; b5 _) V
2000:E599 ; ---------------------------------------------------------------------------4 k; i' p6 U2 k* z, P# j
2000:E599 decompress_successfull:     ; CODE XREF: Decompress_System_BIOS+80
# W; a: `, B4 a* e1 A  {0 \8 k& A2000:E599   or    al, al
' v9 a# g' ?5 _3 r. P+ B/ ]2000:E59B   jnz   short sys_bios_dcomprss_done
/ Z* M% u3 o5 n- z0 l! O* ]* U2000:E59D repeat_decompress:          ; CODE XREF: Decompress_System_BIOS+6E
8 [% |, b4 X3 u- t. K2000:E59D                             ; Decompress_System_BIOS+996 n; h( q9 `9 m8 S4 r% ?" n# p. y. Z
2000:E59D   add   bx, cx              ; bx = point to next compressed component" V7 F' Y  n+ M$ B  T
2000:E59F   call  Decompress9 r# e( j: y6 }$ |
2000:E5A2   jb    short sys_bios_dcomprss_done ; 1st pass jmp taken (original.tmp)
$ t3 L8 M# E2 S, c0 L" w2000:E5A4   test  ecx, 0FFFF0000h7 `( I* }3 T9 W/ e$ |
2000:E5AB   jz    short repeat_decompress
' x3 R  ]2 l2 i) _2000:E5AD sys_bios_dcomprss_done:     ; CODE XREF: Decompress_System_BIOS+89
. M9 `" Y- }7 M& b. X# |! f6 f" X2000:E5AD                             ; Decompress_System_BIOS+90$ P* R; C" ^9 A1 y1 r0 |
2000:E5AD   call  Decmprss_Sysbios_Extension
7 @6 L! Q( ^% E  U; o2000:E5B0   jz    _sysbios_chksum_error* ]# \+ k; k! B( G# T
2000:E5B4   mov   ax, 5000h
2 X! X2 K* Z! W- y; a# J2000:E5B7   clc
% W# G- G, R, k% L2000:E5B8   retn
7 q0 s8 I& N+ u7 p/ N6 U2000:E5B8 Decompress_System_BIOS endp" k) E$ h/ ]+ K) O0 [
________________________________________# N  N1 q& x4 X% h
2000:E5B9 --- Decompress ---6 j* ?7 P0 g  m. B2 x+ G
2000:E5B9 in: es = component_seg' _- y3 Z+ h4 f5 r/ a
2000:E5B9     bx = component_offset0 a* e; S) Y: w, F
2000:E5B9 out: ecx = overall_compressed_component_length
( \2 e, W1 b1 ~. U2000:E5B9      edx = original_component_size
; ]! u( @2 {0 I$ r; A# ?# G' f2000:E5B9      CF, set if failed, cleared if success0 s2 [5 }8 J9 {* ?, L
2000:E5B9 ; --------------- S U B R O U T I N E ---------------------------------------
4 D6 ]. L6 |) j/ z2000:E5B9 Decompress proc near        ; CODE XREF: Decmprss_Sysbios_Extension:not_awdext- y& x; a: Q9 M( a
2000:E5B9                             ; Decmprss_Sysbios_Extension:not_awdext2 ...
, m* Q5 K3 u' H0 R$ i5 ]2000:E5B9   cmp   dword ptr es:[bx+0Fh], 40000000h ; is extension component?
7 t- R, e3 I8 n& ^) u- O( [9 O2000:E5C2   jnz   short not_xtension_component ; 1st pass jmp taken
* @5 g! C; D7 s* B* f1 ~+ l" B2000:E5C4   mov   si, 04 x' G, J0 |& W2 `9 D. F9 o% C# s
2000:E5C7   mov   ds, si
- _$ z# S: R, B2 }& W2000:E5C9   assume ds:nothing
( [" C8 F- ~9 c% j9 G2 ?2000:E5C9   mov   ds:7000h, bx1 R+ }0 X% K9 w  V8 q
2000:E5CD   mov   si, es
) b' a* W+ G& J4 x2000:E5CF   mov   ds:7002h, si. G3 V2 z5 |" [7 _. K$ Q+ B
2000:E5D3   lea   si, ds:7789h0 F  P+ ^1 Z1 D4 a1 D, R* O" m
2000:E5D7   mov   ds:7004h, si  {! i8 r( ?" {8 x& {- L
2000:E5DB   movzx ecx, byte ptr es:[bx]$ H/ h3 j: ^) E
2000:E5E0   add   ecx, es:[bx+7]
" z: i6 X# {. @* o  E2000:E5E5   add   ecx, 3; z/ v' y6 R, f1 \2 z1 a% y
2000:E5E9   retn
; [% d7 _+ R) b$ P2000:E5EA ; ---------------------------------------------------------------------------5 O0 ]. J' R6 W$ o
2000:E5EA not_xtension_component:     ; CODE XREF: Decompress+9
0 E" R* P' ]7 S$ a2000:E5EA   mov   dx, 3000h           ; dx = scratchpad_seg for decompression; h6 [% n2 h" n! ~1 |9 c+ j% H
2000:E5ED   push  ax
8 l& P8 o5 T" d3 a9 o) O0 i% I3 B# [2000:E5EE   push  es( b8 R! `7 ?; V9 ]( T5 V. @, i
2000:E5EF   call  Find_BBSS           ; on ret, si contains offset right after BBSS sign
: Y1 k. e3 c1 |; F2000:E5F2   pop   es) ?; C! \( n  _" N
2000:E5F3   assume es:nothing% l) a% |7 ~9 w6 Q& _5 `. {. J! M
2000:E5F3   push  es
; u( @4 r4 @% X) s$ k5 g2000:E5F4   mov   ax, es) N' _! S6 j* {1 H4 j  j- ^# h) T
2000:E5F6   shr   ax, 0Ch
" a4 N1 G$ q6 l, f1 l- z4 b5 m2000:E5F9   mov   es, ax8 S; e7 l+ P! O
2000:E5FB   assume es:nothing! _; a# p0 |: r* m  v2 d8 b
2000:E5FB   mov   ax, cs:[si+0Eh]# i1 v2 [3 |% i3 C! {7 O
2000:E5FF   call  ax                  ; call decompression engine at 2000:7789h
5 s" P& h- [4 L1 a2 g2000:E601   pop   es: M* e. F7 B$ T& D) s: R
2000:E602   assume es:nothing/ a9 \3 N/ N/ ]$ [5 v
2000:E602   pop   ax
% W# G4 N+ C/ _" n2000:E603   retn
. }1 ?7 Y3 |1 v, v4 [2000:E603 Decompress endp
2 p# {: o( I2 {4 Q8 m3 j________________________________________
' P: g% C  y3 T2000:7789 --- Decomprssion_Ngine ---0 s" u/ d% n' _6 U: |$ P  _& ~
2000:7789 in: dx = scratch-pad_segment_for_decompression
) c& t) Q" C( Y# |: p& a2000:7789      es = (compressed_segment_addr>>0xC) [hi_word of src phy addr]
9 n& G) e- N; p: S2000:7789      bx = compressed_offset_addr) L3 m' `  x/ ^9 D4 {
2000:7789
" P0 p/ g( O+ ]- B0 h0 y2000:7789 out: ecx = overall_compressed_component_length
4 q6 [; s' ~# g2000:7789       edx = original_file_size* v$ V: j; g7 _+ L- I
2000:7789 ; --------------- S U B R O U T I N E ---------------------------------------
: R5 P, F2 c' f2000:7789 Decompression_Ngine proc near: B, o( `% w+ I4 a# d
2000:7789   push  eax6 v+ h! s% e1 Q+ B3 j2 {) s
2000:778B   push  bx
& e5 {* M) f! K2000:778C   push  es. L8 O1 x1 a7 \0 `4 Z* S3 X- p
2000:778D   mov   ds, dx
3 e* ~1 C5 \# J  m, i/ v2000:778F   push  ds+ j/ U' s( h; L8 |
2000:7790   pop   es! L5 U7 e4 y* M; ]4 t$ O
2000:7791   xor   di, di1 f) ]% m4 @. ]
2000:7793   mov   cx, 4000h
; j: Z! I6 I6 p6 T, M" w2000:7796   xor   ax, ax
" P" R# I* v3 R  p0 m2000:7798   rep stosw                 ; zero-init 32KB starting at Scratchpad_Seg:0000h
# V0 q# M6 V" j2 ?4 J0 l% ~2000:779A   pop   es
8 q. V6 Q4 p" M" g& v+ g2000:779B   push  es3 A% j0 v0 Q7 u0 p$ ^* V) `
2000:779C. r6 p0 ?4 {  E9 w- j, R' A
2000:779C ;Setup GDT to be used to get src bytes (Fetch_Byte) later
& a) w4 `5 D& m2000:779C   mov   word ptr ds:100h, es ; ds:100h = compressed_seg_addr>>0xC, W3 y8 d1 T8 ~& _3 _
2000:779C                             ; 1st pass ds:100h = 1
+ ]7 a! s! M2 w6 G) N' i5 N2000:77A0   mov   ds:102h, bx         ; ds:102h = compressed_offset_addr
( D0 m+ `- i5 J( h$ I; S2000:77A0                             ; 1st pass bx = 0
$ B# x: A5 @3 @+ ~6 z6 d' V& v2000:77A4   xor   ecx, ecx: }! T+ o4 \! x6 z2 v+ Q
2000:77A7   mov   ds:57A8h, ecx: ]/ ?% p0 ?( s) W1 q
2000:77AC   mov   ds:57ACh, ecx) L! a( _, v1 v) ^) f" n$ b8 K# ~
2000:77B1   lea   cx, ds:57A8h9 R* D) C* X) [2 c# S% E' |' Y( K
2000:77B5   ror   ecx, 4
2 A. }% ?2 u1 [8 D6 m2 \4 T0 S1 v2000:77B9   mov   ax, ds$ d' b0 O: p2 s; }+ ^/ K
2000:77BB   add   cx, ax
) F& p# o( V) E7 m4 ]2000:77BD   rol   ecx, 4
8 Q7 W: W/ k: Q2000:77C1   mov   word ptr ds:57A2h, 18h
- Z3 ?: A) L% }- l; m  Z0 n8 ^$ l$ M2000:77C7   mov   ds:57A4h, ecx/ i$ g/ |* g; Q8 |
2000:77CC   mov   dword ptr ds:57B0h, 0FFFFh
* l9 n# S6 ^, L# ?  d- |( L8 M+ z2000:77D5   mov   ax, es
+ d5 V( P+ x# f- V2000:77D7   movzx ecx, ah             ; es = hi_word addr of desc_base$ }& E' \9 I4 E* c
2000:77DB   ror   ecx, 8              ; ecx = base_24_31 << 24
6 Z% M* m5 S: ]) \2000:77DF   mov   cl, al$ @7 r  e# `3 B$ R! q5 ?5 w3 @
2000:77E1   or    ecx, 8F9300h6 J+ _' G) m2 w- k
2000:77E8   mov   ds:57B4h, ecx9 d; ~. N6 d" z( H5 ~4 L, ~
2000:77ED   mov   dword ptr ds:57B8h, 0FFFFh
- \' B& P$ L/ q2000:77F6   mov   dword ptr ds:57BCh, 8F9300h
, J1 m" O$ z7 v- o! ~1 F! T# L: |2000:77FF   push  gs
( k, a* u% o; i) q2000:7801   mov   di, 09 m( I" z6 h) M- y# ]
2000:7804   mov   gs, di/ j9 X$ S0 c; ?- A5 [
2000:7806   assume gs:nothing
- g, _: N1 o7 S% Z3 |1 ^& v2000:7806   mov   di, 6000h
# O3 K$ n3 t0 I0 s2000:7809   mov   word ptr gs:[di], 7789h
; {* S4 s* t$ _! h  ]2000:780E
. \2 V8 }: Q& @% [7 f, J& B/ h2000:780E ;check LZH header
( J! J+ v9 h# ^3 {2 L* G% i( s2000:780E   add   bx, 12h             ; LZH-header decomp_seg_addr_hi_byte index
1 `8 l) i' f1 m7 F2000:7811   call  Fetch_Byte
. T; j+ g$ R4 Z; B: X2 a, K2000:7814   sub   bx, 12h             ; restore bx to point to first byte7 Z0 d1 w1 `8 R  r; m" x) d
2000:7817   cmp   al, 40h ; '@'       ; is extension component?
) f# w, V1 k: n. c2000:7817                             ; at 1st: al equ 50h (original.tmp); ?* R2 X' g, ?+ Z* S8 v
2000:7817                             ; at 2nd: al equ 41h (awardext.rom)
: `! C: \7 W# `/ J2000:7819   jnz   short not_extension_component ; 1st-pass jmp taken# K5 u( O1 ~6 Z
2000:781B   add   bx, 11h6 O! M" z+ ^( b1 ~
2000:781E   call  Fetch_Byte          ; fetch "dest_seg_addr" lo_byte) P) \# K0 ]: f2 L9 N  y$ l$ B
2000:7821   sub   bx, 11h             ; restore bx to point to first byte* H6 ?( V" x& q% o0 z& u7 Q
2000:7824   or    al, al              ; if extension component, jmp taken! x# D: U* ?' ^$ l4 m
2000:7826   jnz   short extension_component
' B2 k; ]( l+ P* M( f! a2000:7828   cmp   dword ptr gs:[di+4], 0
  g7 j* B& y: L4 M# s2000:782E   jnz   short not_extension_component* N/ ?3 [( V8 `& M; [" z
2000:7830 extension_component:        ; CODE XREF: Decompression_Ngine+9D
: ?) B2 _" T5 e0 A5 I2000:7830   movzx dx, al              ; dl = "dest_seg_addr" lo_byte
. z2 b! c, m& [  r) R9 u2000:7833   inc   bx                  ; bx = LZH_hdr_chksum byte index
: Y, n' u9 i3 ?) q2000:7834   call  Fetch_Byte
4 G" q/ j$ h& T3 G7 s+ o5 c2000:7837   sub   al, dl              ; LZH_hdr_chksum = LZH_hdr_chksum - "dest_seg_addr"_lo_byte
. U0 [  D2 J% I2000:7839   call  Patch_Byte          ; store new checksum4 n6 P! y0 q, {# s
2000:783C   dec   bx                  ; restore bx, F/ e5 n( P+ h1 A
2000:783D   xor   al, al              ; al = 00h
6 g5 |- Y, Z; x2000:783F   add   bx, 11h             ; bx = "dest_seg_addr"_lo_byte index3 G# X7 X) J3 W# Y* h, v* n
2000:7842   call  Patch_Byte          ; patch "dest_seg_addr"_lo_byte to 00h
+ |: d' ]- E) g) |4 }1 Z2000:7845   sub   bx, 11h2 l2 @4 x/ w+ w$ ]7 f- p3 }' d
2000:7848   inc   dx                  ; dx = "dest_seg_addr"_lo_byte + 1
4 N, R" A" Y4 }7 S. F2000:7849   shl   dx, 2               ; dx = 4*("dest_seg_addr"_lo_byte + 1)
" O2 y/ D+ h8 i+ n2000:784C   add   di, dx              ; di = 6000h + dx  -- look above!
9 l' z: G7 Q- e( ], ?; Z2000:784E   mov   gs:[di], bx         ; 0000:[di] = compressed_offset_addr
) B) I+ u: }4 [- \2000:7851   mov   cx, es
4 }4 Q- q) q& z( v1 ^, _! ~5 t2000:7853   mov   gs:[di+2], cx       ; 0000:[di+2] = compressed_seg_addr>>0xC (hi_word of src phy addr)" ]: {5 h1 Q4 _! Y
2000:7857   call  Fetch_Byte          ; al = LZH_hdr_len. I9 P" j: C. T* M) Q2 Z
2000:785A   movzx ecx, al             ; ecx = LZH_hdr_len
  P/ B. b2 n- {& S3 b2000:785E   add   bx, 76 U1 O& }% n8 O" Y/ E0 F
2000:7861   call  Fetch_Dword         ; eax = compressed_file_size2 f# Z# c6 W8 T8 k- Q: v
2000:7864   sub   bx, 7
% ?, L6 Z0 m7 u/ Y. Q2 k4 w) q2000:7867   add   ecx, eax            ; ecx = LZH_header_len + compressed_file_size- F" |' n6 W" V+ z3 V. k3 J  T
2000:786A   add   ecx, 3              ; ecx = total_compressed_component_size
$ K* q3 n+ F+ b$ Q. I2 l2000:786E   pop   gs+ F2 N# ~% _6 U
2000:7870   assume gs:nothing
6 K6 f& J6 c3 \5 V, Y; e- S2000:7870   jmp   exit, i8 H) Z* t  ~" ], z+ w+ R" _
2000:7873 ; ---------------------------------------------------------------------------
" R: z- G2 f$ @7 \$ m$ z9 V2000:7873 not_extension_component:    ; CODE XREF: Decompression_Ngine+90
( o4 L  n$ x2 K- ^2000:7873                             ; Decompression_Ngine+A5. ^+ \0 [2 S, S9 a' O5 m9 v
2000:7873   pop   gs+ d/ Y8 N+ ]9 T# f- ?' Q0 a& P# {8 ~
2000:7875   call  Make_CRC16_Table
  {) q. h) ^5 P' e3 I2000:7878   call  Read_Header         ; fetch header component to scratchpad_seg, on error CF=1
4 R! z, P% F, A9 g$ Z2000:787B   jb    exit                ; ret with error code set' U- J4 R& }  J# d% ^
2000:787F   mov   ax, ds:108h         ; mov   ax, decomprss_seg_addr& }# I" @* I4 L+ j1 b
2000:7882   mov   ds:104h, ax         ; mov   nu_decomprss_seg_addr, ax) I, J: @$ _8 Z9 e* m
2000:7885   mov   ax, ds:10Ah         ; mov   ax, decomprss_offst_addr, E+ l# j& v( O4 i4 c% ~+ Q5 C# O
2000:7888   mov   ds:106h, ax         ; mov   nu_decomprss_offst_addr, ax' P1 n7 k) |9 g! I1 a; S+ [
2000:788B   mov   ecx, ds:310h        ; ecx = compressed_component_size8 j3 K) `4 Z' q/ ^$ Z6 m& @1 Z
2000:7890   xor   eax, eax1 m9 J- e( f, r6 F/ e; H2 ^- q% M
2000:7893   mov   al, ds:571Ch        ; al = LZH_hdr_len
5 L- b/ k5 b* d2000:7896   add   ecx, eax            ; ecx = compressed_cmpnnt_size + LZH_hdr_len
) X: y, ^% P! N0 z3 N2000:7899   add   ecx, 3              ; ecx = compressed_cmpnnt_size + LZH_hdr_len +
5 g2 ~7 r, c8 J6 e9 T% c% A9 z' \* Y! }2000:7899                             ;       sizeof(EOF_byte) + sizeof(LZH_hdr_len_byte) +5 z# B# `: x- f/ u7 p. S- z
2000:7899                             ;       sizeof(LZH_hdr_8bit_chk_sum)
/ q/ P: ]2 o8 P; X* q  o  \2000:7899                             ; i.e. ecx = overall_component_len7 B: V9 s; ]- U1 B
2000:789D   mov   edx, ds:314h        ; mov   edx, original_file_size
" p- F) u9 w' c2000:78A2   push  edx
6 }2 v8 q' l$ O% A2000:78A4   push  ecx
% W8 E* o& y  I2000:78A6   push  bx; ?5 @" c8 W5 l& b8 @
2000:78A7   add   bx, 5               ; point to LZH ID byte% k+ Y9 I# d# b8 C1 v
2000:78AA   call  Fetch_Byte! ]/ b/ h% B/ R5 I+ v7 _
2000:78AD   pop   bx
+ k$ m" {! {! l7 N# I, y' G; ?2000:78AE   cmp   al, '0'             ; is '-lh0-'?3 ~6 d) }1 u& i2 a$ E3 P( K. t) R
2000:78B0   jnz   short decompress_part5 M; b& i# J$ {9 o
2000:78B2   push  ds( }- ^. G) V9 r7 T
2000:78B3   push  si% g" k) a4 C' V" o' y/ Y
2000:78B4   push  bx
; m2 f; N+ ~, Q* n2000:78B5   mov   di, ds:10Ah
" i, ?1 ?3 n2 C  l  _# e. m, X3 H2000:78B9   movzx ax, byte ptr ds:571Ch
0 @) V% [" h- z- r! I6 p% U7 [2000:78BE   add   ax, 2
9 c( X7 `6 o* X2 j, c( ?8 O  Z. d; \2000:78C1   add   bx, ax
, D9 g8 y" C/ N" V6 c# e2000:78C3   mov   cx, ds:310h. c9 t, ]2 @2 \
2000:78C7   mov   ax, ds:108h* X- q! F( d* o" ~
2000:78CA   mov   es, ax
: b; E" M2 Y/ ?- k  B- K4 F8 K6 H2000:78CC   add   cx, 36 i0 M( ~  _# g% v
2000:78CF   shr   cx, 25 T4 a  w0 S( D/ s9 A+ Q
2000:78D2 next_dword:                 ; CODE XREF: Decompression_Ngine+151- m( e8 R- u. {
2000:78D2   call  Fetch_Dword- _; V; k3 n% w1 b: P- R2 d
2000:78D5   add   bx, 4
  u; {6 ?4 F2 n) Q2000:78D8   stosd
" F% p( k4 `$ v) G1 c5 R2000:78DA   loop  next_dword4 V, W# F2 o, j$ B- }: v
2000:78DC   pop   bx% t' H# M4 m1 Y+ W- r, y- @2 A
2000:78DD   pop   si
9 S: ~) ^6 J% V- @7 {8 q& M2000:78DE   pop   ds! W- R2 c9 m: T
2000:78DF   jmp   short LZH_hdr_OK& A* M5 {3 v- }$ u3 g0 }
2000:78E1 ; ---------------------------------------------------------------------------
9 K6 M# ^$ X4 |, |) Q& c2000:78E1 decompress_part:            ; CODE XREF: Decompression_Ngine+127
+ }- \% H) b- d% a  u( V2 G2000:78E1   push  word ptr ds:104h    ; save destination seg addr
, a* h9 ~( d$ F9 ~  V2000:78E5   push  word ptr ds:106h    ; save destination offset addr
. |* `9 W, }. |( r- h: x2000:78E9   push  large [dword ptr ds:314h]. \( o  k/ G2 I" I. R* x
2000:78EE   call  Lzh_Expand          ; Lzh_Expand capable of handling compressed
; X" U/ u( j, n# E9 s2000:78EE                             ; component bigger than 64KB (1 segment)
. c( d. ]; y% R. Z7 w# l7 U5 |2000:78F1   pop   dword ptr ds:314h, c2 e5 R6 o! p7 b
2000:78F6   pop   word ptr ds:106h( j* b& i3 [0 l7 M$ W, |
2000:78FA   pop   word ptr ds:104h2 K: |4 A9 s% F0 ^
2000:78FE LZH_hdr_OK:                 ; CODE XREF: Decompression_Ngine+156
* o: `+ O& w' M  ]( W. B5 P2000:78FE   call  Zero_Init           ; zero init 32KB of scratchpad_seg
: U" s2 j% ?4 B2000:7901   pop   ecx. l: p$ ]' Q( s) H; w  b* N/ ^; k
2000:7903   pop   edx- b- x2 H& O/ p3 |6 A1 k
2000:7905   clc
# D/ _. E& _& a& b6 I0 e2000:7906 exit:                       ; CODE XREF: Decompression_Ngine+E7
- g" u' k" a2 @+ T, r( Y2000:7906                             ; Decompression_Ngine+F2# [" E7 u  N/ q
2000:7906   pop   es
4 R, a' `' E! V$ v2 Q* ~4 ]2000:7907   pop   bx! H, g& w$ T% ^; L# H
2000:7908   pop   eax
* j+ a' o+ h( C3 k2000:790A   retn
  {; X  U2 ?& h2 }2000:790A Decompression_Ngine endp
  Q2 B( E& z6 {$ c3 E________________________________________
9 G/ p9 d: Z+ o$ x$ F; s6 X) `" o
: n$ y9 D; e7 b1 i8 g1 X' R. K2000:790B                         --- Make_CRC16_Table ---& m' O! c% o0 \5 e
2000:790B                         1st pass, the base address for DS is 3_0000h
6 F/ X2 D+ G% _6 w8 O# A2000:790B                         in: ds = scratch_pad_segment for CRC table
# B* z) H& b5 _! T2000:790B                         out: ds:10Ch - ds:11Bh = CRC-16 table
" F; u5 y7 B& O( w( B2000:790B                         ; --------------- S U B R O U T I N E ---------------------------------------
5 o0 T6 \1 \1 w* r; v  B2000:790B                         Make_CRC16_Table proc near  ; CODE XREF: Decompression_Ngine+EC
- m" U- S( a: l; ^& U- w6 ]( s2000:790B 51                        push  cx
, t# |2 s" C: [1 s+ L5 s1 F2000:790C 53                        push  bx, l" w5 V) A$ X: e( g
2000:790D 50                        push  ax
: t2 x; i+ x' X# H3 |$ @2000:790E 56                        push  si
3 q5 d  |. {, i& u% }2000:790F BE 0C 01                  mov   si, 10Ch
. G5 F. N) b. g. u9 T2000:7912 B9 00 01                  mov   cx, 100h' _+ m: b6 C7 E/ ~! p# Z7 Q# t: K
2000:7915                         next_byte:                  ; CODE XREF: Make_CRC16_Table+2B
8 w) ^0 P# S3 C3 b! K) {2000:7915 B8 00 01                  mov   ax, 100h
% J( Z9 x/ Z- d* I2000:7918 2B C1                     sub   ax, cx5 v% C  V; q, p# @# f! Y/ W
2000:791A 50                        push  ax
* d* C4 V; z/ w) r5 O+ e2000:791B BB 00 00                  mov   bx, 0
& N/ u% |8 m( x3 E# Z, U& ]2000:791E                         is_bit:                     ; CODE XREF: Make_CRC16_Table+25. b1 h) y% H* v8 }4 F: k2 v
2000:791E A9 01 00                  test  ax, 1  h9 Z; u2 D8 H% C4 N; C& L& Y
2000:7921 74 07                     jz    short not_bit" E- h. F3 l* V8 q
2000:7923 D1 E8                     shr   ax, 1
1 C, B- B# n8 S7 S1 s& C2000:7925 35 01 A0                  xor   ax, 0A001h          ; CRC poly
: P% i! n' Z3 J' k7 u. G; d2000:7928 EB 02                     jmp   short point_to_next_byte
6 |9 w/ k4 k5 a, ~0 |/ u# l2 t9 p2000:792A                         ; ---------------------------------------------------------------------------7 m( x. ?. P  X# O
2000:792A                         not_bit:                    ; CODE XREF: Make_CRC16_Table+16+ t3 S, ~% f2 T: c
2000:792A D1 E8                     shr   ax, 1% E2 X: T5 l2 R( A
2000:792C                         point_to_next_byte:         ; CODE XREF: Make_CRC16_Table+1D
6 Q* s, N6 D1 I2000:792C 43                        inc   bx3 l# s- S- d6 u% |7 e* W
2000:792D 83 FB 08                  cmp   bx, 8* f" z0 ]6 o. n6 L
2000:7930 72 EC                     jb    short is_bit
  {% {6 f, F( \! w* t2000:7932 5B                        pop   bx
7 b9 e8 B1 _- D; ]& j2000:7933 89 00                     mov   [bx+si], ax5 d; D$ N- l& J, R+ E
2000:7935 46                        inc   si
- X( ?6 t, R& |& ~2000:7936 E2 DD                     loop  next_byte
  W+ `" Q+ m$ `) d/ |3 P3 m- x2000:7938 5E                        pop   si
$ ?6 i% o4 @0 L+ ^2 {2000:7939 58                        pop   ax- [& q5 j( v5 b& E* l1 x
2000:793A 5B                        pop   bx# r9 U4 g0 D8 i3 L
2000:793B 59                        pop   cx4 J, [- D1 Z) Y, [9 r
2000:793C C3                        retn6 s" t; q0 s; p6 H0 g
2000:793C                         Make_CRC16_Table endp
# J8 R% c8 K7 E9 I9 f8 n________________________________________' i- h+ L+ O. j% A$ ~( k* t! n( J
! l/ [1 a; o$ S  x1 Y' [
2000:79E8                         --- Read_Header ---) @& q- F$ h5 X- T- i& g/ a
2000:79E8                         in: ds = scratchpad_segment* Q) \' `$ R; X& `+ ~+ o7 S2 \
2000:79E8                               ds:102h = LZH_hdr_byte_index
2 g- k4 v! R$ Y( K+ ?: i1 u2000:79E8
1 ~* F- N  w: D2 s8 r& h$ _2000:79E8                         out:  ds:102h = LZH_hdr_byte_index7 A( [  P; R$ R0 _3 {
2000:79E8                               ds:108h = componnt_decomprrsion_seg_addr
6 l' f, L. ^) j5 y5 U* ^2000:79E8                               ds:10Ah = componnt_decomprrsion_offset_addr+ G+ o" h& E7 F0 w" A, B9 ?: f8 @
2000:79E8                              ds:310h = uncompressed_componnt_size7 Z' |' w" s$ j6 O6 h. v! I/ `: G! @7 C
2000:79E8                              ds:314h =  component_seg:offset_decompression_addr! F( \3 ^1 w7 A' b
2000:79E8                              ds:571Ch = LZH_hdr_len) Y6 \1 z+ x) M( e
2000:79E8                              ds:571Dh = LZH_hdr_chksum1 a: H6 E( K% N5 w3 C
2000:79E8                              ds:571Eh = LZH crc16 val
* c0 G) G& `' n+ `2000:79E8                              ds:0 - ds:LZH_hdr_len = copy of current component LZH hdr9 l/ |( x) X: l' b
2000:79E8                         ; --------------- S U B R O U T I N E ---------------------------------------0 k! y& U& S+ z+ M; u# m9 j9 n
2000:79E8                         Read_Header proc near       ; CODE XREF: Decompression_Ngine+EF
" n# Q' T. b& \' `2 J- N, S4 o3 V; W2000:79E8 60                        pusha
. Z$ Q# ~! t2 p/ Y7 v2000:79E9 06                        push  es1 U) |, N) f) \# h- q( Z; v$ L
2000:79EA 8B 1E 02 01               mov   bx, ds:102h
. v( }1 k1 b0 d7 a( T7 m3 D, ?2000:79EE E8 DA 00                  call  Fetch_Byte
) |5 y% V7 ?$ y4 h" V2000:79F1 FF 06 02 01               inc   word ptr ds:102h
3 W) g( t7 l! d2000:79F5 A2 1C 57                  mov   ds:571Ch, al* Z+ G& u% S5 q3 v% M
2000:79F8 07                        pop   es
9 y1 i+ G. I  K7 }+ W" Q2000:79F9 80 3E 1C 57 00            cmp   byte ptr ds:571Ch, 0, @# n2 ?5 n4 l; C) h
2000:79FE 75 04                     jnz   short read_LZH_hdr_ok
/ G/ M3 e; Q: s2000:7A00                         error:                      ; CODE XREF: Read_Header+38
  c! ^- y. d+ `2000:7A00                                                     ; Read_Header+71 ...) q1 D( @) X7 w2 w- ^) N
2000:7A00 F9                        stc
& s2 r* b& S7 m  W/ u2000:7A01 E9 86 00                  jmp   exit
, f4 ]/ c& @8 x) p. c2000:7A04                         ; ---------------------------------------------------------------------------
) p1 P8 S: ?0 w4 T! i- U+ W2000:7A04                         read_LZH_hdr_ok:            ; CODE XREF: Read_Header+164 k5 t  B% M: n  w' _. |6 q
2000:7A04 06                        push  es
; w/ @  p- g- H  c# O7 B2000:7A05 8B 1E 02 01               mov   bx, ds:102h2 _9 N# O' M1 Q8 i$ ]) |
2000:7A09 E8 BF 00                  call  Fetch_Byte          ; read LZH_hdr_chksum byte$ ?7 q' L5 l% y! C, ?
2000:7A0C FF 06 02 01               inc   word ptr ds:102h% l4 E+ \) Y: k2 F" R
2000:7A10 A2 1D 57                  mov   ds:571Dh, al        ; 1st pass: 3000:571D = LZH_hdr_chksum
! Z2 A5 l, T0 t& S2000:7A13 07                        pop   es
' z& f% g, s- ]: L5 k2000:7A14 E8 26 FF                  call  Calc_LZH_hdr_CRC16  ; fetch compressed component value to RAM,* i* Z  a/ g+ V. r" r
2000:7A14                                                     ; then calc its CRC16 checksum
+ e; _; Y: p3 S9 e) h2000:7A17 E8 88 FF                  call  CalcHdrSum  ) z/ U4 {: e- Y
2000:7A1A 3A 06 1D 57               cmp   al, ds:571Dh        ; is the stored LZH_hdr 8-bit chksum match the one that read?- O- _3 x+ I+ _7 v. _/ R
2000:7A1E 74 02                     jz    short LZH_hdr_8bit_chksum_ok" q6 |: Y& j( [1 R
2000:7A20 EB DE                     jmp   short error( L) h& B; h4 Z( [. F& T- P) D" ?- J
2000:7A22                         ; ---------------------------------------------------------------------------
7 N0 |8 l8 k* w% h) p  M2000:7A22                         LZH_hdr_8bit_chksum_ok:     ; CODE XREF: Read_Header+367 c( l0 V; J+ p
2000:7A22 BB 05 00                  mov   bx, 55 i2 c2 i' N+ O" J" b+ m8 s
2000:7A25 B9 04 00                  mov   cx, 4               ; bx+cx = compressed_component_size_index (Dword)
, R" A8 _& r4 c+ ]  C3 O) u2000:7A28 E8 99 FF                  call  GetFromHeader8 Y; M6 f+ H( x0 ^  c" J+ g  S
2000:7A2B 66 A3 10 03               mov   ds:310h, eax
9 n& R% J1 _# h: z  P( N3 K; @2000:7A2F BB 09 00                  mov   bx, 9
* s4 f! h+ Z: Q2000:7A32 B9 04 00                  mov   cx, 4               ; bx+cx = original file size (Dword)
1 _3 ]0 ?9 n0 m: r3 c  r2000:7A35 E8 8C FF                  call  GetFromHeader
/ ^7 Q9 R% H1 Q2000:7A38 66 A3 14 03               mov   ds:314h, eax
3 J8 `* l$ F- u* q; P3 h2000:7A3C BB 0D 00                  mov   bx, 0Dh
( C1 A/ U0 B) U3 L& q; j2000:7A3F B9 02 00                  mov   cx, 2               ; bx+cx = decompression_component_offset addr (Word)
5 c4 n3 R* p, l; U) X2000:7A42 E8 7F FF                  call  GetFromHeader
" S) N% M# @% u; M! T2000:7A45 A3 0A 01                  mov   ds:10Ah, ax
/ T' m" U" e6 I- @2 _2000:7A48 BB 0F 00                  mov   bx, 0Fh: d% n# I$ T$ b: M0 W) m
2000:7A4B B9 02 00                  mov   cx, 2               ; bx+cx = decompression_component_segment addr (Word)
- f# J: [7 h2 k; L" F4 J+ Q2000:7A4E E8 73 FF                  call  GetFromHeader6 N) Y1 O2 |8 s! F, u1 _8 y
2000:7A51 A3 08 01                  mov   ds:108h, ax
0 v+ t8 J6 F- N8 `8 o2 Z2000:7A54 80 3E 11 00 20            cmp   byte ptr ds:11h, 20h ; ' ' ; is LZH level 1 file attribute?
! x! ~& S5 d" O' c2 w2000:7A59 75 A5                     jnz   short error
+ s0 P, N8 q8 m* c. t2000:7A5B 80 3E 12 00 01            cmp   byte ptr ds:12h, 1  ; is LZH level 1 ?
$ `( g4 d- h0 R2000:7A60 75 9E                     jnz   short error
7 r6 u8 T" B' `0 @2 l) P2000:7A62 0F B6 1E 1C 57            movzx bx, byte ptr ds:571Ch ; bx = lzh_hdr_len7 x# P( u8 x: H( ^: I, B0 y! L
2000:7A67 83 EB 05                  sub   bx, 5               ; bx = CRC16_byte_index
6 `( |& ^! X2 x7 e) l2 p7 m2000:7A6A B9 02 00                  mov   cx, 2& B2 c1 z+ Z% b, ?, U7 {
2000:7A6D E8 54 FF                  call  GetFromHeader       ; read CRC16 value: o" t6 q$ u4 s! Y" v8 Y
2000:7A70 A3 1E 57                  mov   ds:571Eh, ax        ; ds:571Eh = CRC16_val
6 L5 |* d( Y2 ?+ j: `2000:7A73 BB 13 00                  mov   bx, 13h             ; bx = filename_len byte index: l' F( L! y" i& ~" S' u4 u
2000:7A76 8A 9F 00 00               mov   bl, [bx+0]          ; bl = filename_len
/ n2 \$ N2 Y- d0 ~3 r2000:7A7A B8 14 00                  mov   ax, 14h) Y" V. D  b" R, t& L# r, T* v2 G
2000:7A7D 03 D8                     add   bx, ax              ; bx = CRC16_byte_index+ y, c2 T( t5 ]! N) D+ Z
2000:7A7F C6 87 00 00 24            mov   byte ptr [bx+0], 24h ; '$'" @0 g  D" _3 G4 p5 o* w
2000:7A84 C6 87 01 00 00            mov   byte ptr [bx+1], 0% G3 X1 C* R0 }( I; i6 Z
2000:7A89 F8                        clc& C4 [3 F" |3 b" a% l
2000:7A8A                         exit:                       ; CODE XREF: Read_Header+19
0 D8 o* q1 |, Q! o0 K  g2000:7A8A 61                        popa
/ J# {0 N9 a& ^3 B2 ]1 ^2000:7A8B C3                        retn
1 W# G) L* C. z6 w5 G7 i. [! `2000:7A8B                         Read_Header endp1 E2 w, `3 G6 d0 b( x
________________________________________- j% L" Y% ?4 L2 G4 a% g7 O
3 E8 h5 }9 `1 h* C& k
2000:793D                         Calc_LZH_hdr_CRC16 proc near ; CODE XREF: Read_Header+2C7 ~- _* g8 M; L, k& y' D/ W
2000:793D 50                        push  ax- ^( x  y! a7 l* F8 M& u6 z
2000:793E 53                        push  bx
9 L3 H- v; l, L9 Z2000:793F 51                        push  cx
$ C# K1 t4 W; b  u1 B4 x9 ]2000:7940 52                        push  dx
7 p1 B5 \. M4 @! D! y+ U& X2000:7941 0F B6 0E 1C 57            movzx cx, byte ptr ds:571Ch' I3 E6 d% a5 O0 J
2000:7946 06                        push  es
+ k* |: @# e9 W2 @2000:7947 56                        push  si1 `2 @& J( W" w. f* n
2000:7948 8B 1E 02 01               mov   bx, ds:102h2 S; S+ `+ e1 Y" N$ U- a
2000:794C BE 00 00                  mov   si, 06 d9 T/ o7 T. N  u; i8 c+ J
2000:794F                         next_byte:                  ; CODE XREF: Calc_LZH_hdr_CRC16+19
. Q" T% W: p* [/ n! R5 E3 \# h2000:794F E8 79 01                  call  Fetch_Byte
8 ?" ^% }: o  s. W& G2000:7952 88 04                     mov   [si], al% D  F# A7 v9 y! |/ a4 X9 w9 n
2000:7954 43                        inc   bx  \! ]5 z$ D2 R- o# C2 j
2000:7955 46                        inc   si' H4 k* b3 i- e: z
2000:7956 E2 F7                     loop  next_byte2 K, k% m) u# g" `
2000:7958 8B C3                     mov   ax, bx
: F0 o& F2 |0 f" O6 h2000:795A 2B 06 02 01               sub   ax, ds:102h, ~* u3 d' {; K* J1 d. C8 Y
2000:795E 89 1E 02 01               mov   ds:102h, bx$ }. x0 l* U8 a
2000:7962 5E                        pop   si
' t! `6 M- |: z$ p- I6 o2000:7963 07                        pop   es
% ^7 v9 J6 W1 }( D6 r2000:7964 A2 1C 57                  mov   ds:571Ch, al
" {) J8 ^2 x8 J8 Y1 g' L2000:7967 8B C8                     mov   cx, ax/ l. T0 `$ z" q/ Z* d- {+ m9 P
2000:7969 01 06 14 03               add   ds:314h, ax
$ {. s: q6 n+ w& B/ s6 S2000:796D 41                        inc   cx0 F" O& q- d# m" ?6 O( o! l
2000:796E BB 00 00                  mov   bx, 04 K5 Q7 C6 \- a$ S- @' R9 C
2000:7971                         next_CRC_byte:              ; CODE XREF: Calc_LZH_hdr_CRC16+5E
# N& U' a1 D& J5 E2 o/ i+ K4 ]" M9 T2000:7971 0F B6 07                  movzx ax, byte ptr [bx]
" b- |- c3 r; |7 z+ z2000:7974 49                        dec   cx7 I# Y- D% l+ [  e& |3 d
2000:7975 E3 26                     jcxz  short exit2 C& \; C# J: ^7 g( i
2000:7977 50                        push  ax
, U7 }" \$ `/ W6 H% K1 t! F+ u2000:7978 53                        push  bx
. v# C: ~' c6 H( z! n/ R' C+ t2000:7979 56                        push  si2 _! m( k; r; F% \
2000:797A 8B F0                     mov   si, ax
/ H. U9 I- O& U2000:797C A1 0C 03                  mov   ax, ds:30Ch
! a2 A# k. U8 _! x/ Q# g) x2000:797F 33 C6                     xor   ax, si
4 \" e+ S4 C) S5 B2000:7981 25 FF 00                  and   ax, 0FFh
2 u6 W* G: G: S% L* Z8 U1 p2000:7984 8B F0                     mov   si, ax1 D8 {) @- D+ A0 K2 h8 |, v
2000:7986 D1 E6                     shl   si, 1  i& s, Y# Z; H( t$ m# X5 Z+ a# B
2000:7988 8B 9C 0C 01               mov   bx, [si+10Ch]9 V% ~4 S5 A2 N4 `( [9 j
2000:798C A1 0C 03                  mov   ax, ds:30Ch
. ]# l* J6 Y* V4 j5 \' ~* j2000:798F C1 E8 08                  shr   ax, 81 e7 K, y9 r6 y* O
2000:7992 33 C3                     xor   ax, bx, {) R) w3 \& Y6 b) `- A# p7 {' M
2000:7994 A3 0C 03                  mov   ds:30Ch, ax9 ^9 d  W4 e9 {8 {( ~  q( f
2000:7997 5E                        pop   si
3 _2 ]/ F4 n  x/ w' i3 f0 A2000:7998 5B                        pop   bx
5 `0 r5 h5 Y* t) G. W7 U; |2000:7999 58                        pop   ax  S# E8 l7 {. I4 R
2000:799A 43                        inc   bx
/ i  K1 u# v7 k0 D' b6 h2000:799B EB D4                     jmp   short next_CRC_byte. s& e# P: n! ]8 ?# i; \: f, K
2000:799D                         ; ---------------------------------------------------------------------------* }2 g4 E3 A6 y% j  n& e& @
2000:799D                         exit:                       ; CODE XREF: Calc_LZH_hdr_CRC16+387 o0 W# @# W4 b$ k7 ^' [& s" I
2000:799D 5A                        pop   dx
- L" C. R  N# m4 m2 Q# Y2 L8 R2000:799E 59                        pop   cx, \) K8 R2 u) m3 v, ?
2000:799F 5B                        pop   bx
4 I+ d& v" Q5 b' F  i2000:79A0 58                        pop   ax
- W. Y8 n  I+ s7 k5 t6 H: R; J6 J8 |2000:79A1 C3                        retn; }4 |' \+ Q& s9 Z' [1 I) }* D
2000:79A1                         Calc_LZH_hdr_CRC16 endp7 Q' Y% X( @6 @" U
________________________________________6 m, D. s% L6 L. p' A' p; T' W3 h

% v7 E/ U6 G5 s  l) i: _2000:79A2                         CalcHdrSum proc near        ; CODE XREF: Read_Header+2F
$ u# }. F$ y' Z8 i6 a. \2000:79A2 53                        push  bx1 y3 O' L( f! I. `. ?: y: ^
2000:79A3 51                        push  cx4 x8 Q, d  w  S2 B. ]
2000:79A4 52                        push  dx
& d3 K$ c9 h- K+ g2000:79A5 B8 00 00                  mov   ax, 0
! q1 ]2 u( T2 ]4 n* B, n0 G# }2000:79A8 0F B6 0E 1C 57            movzx cx, byte ptr ds:571Ch0 @% v. S" d- n+ r2 z% c( t4 n
2000:79AD                         loc_2000_79AD:              ; CODE XREF: CalcHdrSum+19 j
. I4 O/ l2 U5 i, O" Q+ B2000:79AD 0F B6 1E 1C 57            movzx bx, byte ptr ds:571Ch
1 ?6 c4 r" M3 C$ x6 Y2000:79B2 2B D9                     sub   bx, cx- T: g/ o6 o6 i
2000:79B4 0F B6 97 00 00            movzx dx, byte ptr [bx+0]0 u3 c1 `& }7 W5 N5 E0 t( X
2000:79B9 03 C2                     add   ax, dx4 ?9 m. K  F8 s0 K; I/ f( X( Q( E: h
2000:79BB E2 F0                     loop  loc_2000_79AD# l# X8 {8 G( x! R7 x
2000:79BD 5A                        pop   dx
: o# L5 [# D3 w( L2000:79BE 59                        pop   cx  {! R5 U5 _; b; ~) T+ X
2000:79BF 5B                        pop   bx
$ |+ W8 ?& l& ^6 l5 j% s- D; o5 b0 [4 C2000:79C0 25 FF 00                  and   ax, 0FFh& {  D+ }1 Y& g! l) B' E
2000:79C3 C3                        retn+ T& L7 l, a9 ~5 @, U
2000:79C3                         CalcHdrSum endp
6 A4 |' a' g1 B, [! i________________________________________
+ c( X6 _" ?/ O" [1 A- V4 h$ f" K1 O# k2 v0 _! l
2000:79C4                         --- GetFromHeader ---4 L) e# E) T" z5 Z, B, ^$ z9 u: F
2000:79C4                         in: bx = byte_index of the "component" to read
2 D* v: }3 o/ J) \  b& N9 [2000:79C4                              cx = length of "component" to read" k3 S) W& J# x" `$ K5 u0 ]4 f
2000:79C4
/ s" h/ u2 E: g: S2000:79C4                         out: eax = dword_read( W0 g/ Z# w5 ^( W
2000:79C4                         ; --------------- S U B R O U T I N E ---------------------------------------
# X2 H6 Q0 `0 j# G. s2000:79C4                         GetFromHeader proc near     ; XREF: Read_Header+406 W* r5 p; R( E4 q9 ]* [
2000:79C4                                                     ; Read_Header+4D ...+ v9 U4 {' u9 U8 B/ }
2000:79C4 53                        push  bx8 E+ ~1 o* P) S- ^4 V. Q
2000:79C5 66 52                     push  edx
1 e5 q& S: M$ C+ s# ?2000:79C7 56                        push  si' T, z4 v6 P& B
2000:79C8 66 33 C0                  xor   eax, eax* B8 C+ g( C9 K1 f4 {
2000:79CB 4B                        dec   bx) F" q* \- c; E% n" q
2000:79CC 41                        inc   cx
0 D* O, C0 z3 A- y  A* k0 V2000:79CD                         next_byte:                  ; CODE XREF: GetFromHeader+1D! l- V$ }0 e+ }+ c6 k3 y6 [$ H
2000:79CD 49                        dec   cx: m0 }6 v4 a, {$ k
2000:79CE E3 13                     jcxz  short exit
, s5 t0 n, n5 n% X( h2000:79D0 66 C1 E0 08               shl   eax, 8
3 f4 u  o$ V+ r1 }, ?- N2000:79D4 8B F3                     mov   si, bx
1 Y4 Z0 ~: v* o$ H5 R2000:79D6 03 F1                     add   si, cx
, I! {3 T3 f- b2000:79D8 66 0F B6 94 00 00         movzx edx, byte ptr [si+0]2 c, M0 L: {" }! a, a7 w
2000:79DE 66 03 C2                  add   eax, edx
% I' @1 e, k0 {. r2 K2000:79E1 EB EA                     jmp   short next_byte
9 J% E, m4 K& Q* I6 ^/ O. X/ J2000:79E3                         ; ---------------------------------------------------------------------------# @/ ^7 f6 i1 U% F, Z& g
2000:79E3                         exit:                       ; CODE XREF: GetFromHeader+A' b! n8 l8 d7 b3 v1 M" ~! U
2000:79E3 5E                        pop   si
% {' K6 w2 \  b7 y( w$ k6 M/ [. y" h2000:79E4 66 5A                     pop   edx: X  {2 @# K% ~2 |& [/ n
2000:79E6 5B                        pop   bx5 Q- |& U& I9 d
2000:79E7 C3                        retn
7 H! B3 Z0 Q  K2000:79E7                         GetFromHeader endp% f0 h/ n. y# T7 }2 F
看完这些彻底的线索,我们成功的构建映射了bios解压部分:5 J. U+ P8 ?5 ~, g3 x0 @
Starting address of decompressed BIOS component in RAM   Compressed Size  Decompressed Size  Decompression State (by Bootblock code)  Component description: i! r- C/ I  o; q
4100:0000h  3A85h  57C0h  Decompressed to RAM beginning at address in column one.  awardext.rom, this is a "helper module" for original.tmp
' ], {" m4 E1 W1 P) o' J) B3 h4001:0000h  5CDCh  A000h  Not decompressed yet  cpucode.bin, this is the CPU microcode% w5 Q" P$ L: k
4003:0000h  DFAh  21A6h  Not decompressed yet  acpitbl.bin, this is the ACPI table
8 R. V& @) ?3 u! Y5 D& k. j2 N4002:0000h  35Ah  2D3Ch  Not decompressed yet  iwillbmp.bmp, this is the EPA logo8 S' v' _  V& g/ t* I# p
4027:0000h  A38h  FECh  Not decompressed yet  nnoprom.bin, explanation N/A/ J2 q0 \/ y7 R
4007:0000h  1493h  2280h  Not decompressed yet  antivir.bin, this is BIOS antivirus code
  c! a5 |1 _3 D  \4028:0000h  F63Ah  14380h  Not decompressed yet  ROSUPD.bin, seems to be custom Logo display procedure
: k$ |1 [; _' t1 ^  a' x5000:0000h  15509h  20000h  Decompressed to RAM beginning at address in column one.  original.tmp, the system BIOS
7 x* r6 _( l7 e  j3 F注意:绿色覆盖的解压地址被另外的方法处理:' ]& {. O: f5 v' F  X! p
A.  上面解释的部分不是真正的被解压区域。只是某种真正解压区域的占有区域,稍后由original.tmp处理。结论是:在bootblock中只有original.tmp和awardext.rom被Decompress_System_Bios解压缩。如果你想改变这个,那么试着计算被解压代码的大小总和,他不会合适的!
5 k* L: d' K2 h/ rB.  所有的这些被解压段地址部分被Decompression_Ngine procedure变换到4000h,就像你看到的在例程里面地址2000:7842h。
& t5 _6 \7 @1 O$ ~$ q' l* VC.  “(被解压)开始地址。。。”中的40xxh 实际上是一个ID,工作如下:40(高字节)是ID,标示它是一个扩展bios,将要在稍后的original.tmp执行时被解压缩。Xx是一个id,在original.tmp用到,标示要被解压缩的部分。这些在下面的original.tmp中会详细解释。/ x# k6 e. z* }8 ]1 C
D.  所有的这些部分都要在original.tmp执行时被解压缩。解压结果被放在地址4000:0000h,但是不会在同一时刻。有一些(也许所有的)部分也要从那个地址重新定向,在另外的部分在那个地址被解压缩后保留他们的内容。这些在下面的original.tmp中会详细解释。
( k" F( _0 Q1 q" o3 B+ h  X- y- Y7.1.6.7. Shadow the BIOS code ' n. a0 n( `$ u8 f5 {
7.Shadow bios代码。假设解压例程成功的完成了,上面的例程接着拷贝被解压得system bios(original.tmp),从RAM中的5000:0000h - 6000:FFFFh到E_0000h - F_FFFFh。完成如下:
$ P4 x) g* C! [* L) y1)重新编程北桥shadow RAM控制寄存器,使能只写到地址E_0000h - F_FFFFh,促进写操作这个地址范围到DRAM(没有到bios rom芯片)。
# w' X" Y" u; V( t) x5 q# Q2)进行一个字符串拷贝操作,拷贝被解压了的system bios(original.tmp),从5000:0000h - 6000:FFFFh到E_0000h - F_FFFFh。+ O( h9 o- j( i" J0 w
3)重新编程北桥shadow RAM控制寄存器,使能只读到地址E_0000h - F_FFFFh ,促进读操作这个地址范围到DRAM(没有到bios rom芯片)。这个也是对system bios 代码写保护* |' ?" I! q( l+ e4 k5 B" P: D
7.1.6.8. Enable the microprocessor cache then jump into the decompressed system BIOS
1 [1 C* T, \6 n- r$ }" Q; C9 I  8.使能微处理高速缓存,然后跳转到压缩的system bios。这一步是普通bootblock代码执行路径的最后一步。使能处理器高速缓存后,代就会跳转到RAM地址F000:F80Dh中的写保护的system bios(original.tmp),如上面看到的代码。这个跳转的目的地址好像在不同的award bios中都一样。
$ A1 W4 l  G! o* q  现在我要呈现在跳转到解压缩的original.tmp之前,压缩的和解压的bios部分的内存地图。这个很重要,因为这会在等会的分析解压缩了的original.tmp方便我们。现在我们不得不注意,所有的代码都在RAM中之行,在没有代码在bios rom芯片中执行了。; F' q( b8 _/ O4 z
Address Range in RAM  Decompression State (by Bootblock code)  Description
+ A/ D/ i: O7 B+ m% F0000:6000h - 0000:6xxxh  N/A  This area contains the header of the extension component (component other than original.tmp and awardext.rom) fetched from the compressed BIOS at 8000:0000h - 9000:FFFFh (previously BIOS component at FFFC_0000h - FFFD_FFFFh in the BIOS chip). Note that this is fetched here by part of the bootblock in segment 2000h.
+ a/ ^& R( k5 H* W" e( G1000:0000h - 2000:5531h  Compressed  This area contains the compressed original.tmp. It's part of the copy of the last 128KB of the BIOS (previously BIOS component at E000:0000h - F000:FFFFh in the BIOS chip). This code is shadowed here by the bootblock in BIOS ROM chip.
  e; o; X2 F# w+ h2000:5532h - 2000:5FFFh  Pure Binary (non-executable)  This area contains only padding bytes.  S$ f/ R2 z+ h) _
2000:6000h - 2000:FFFFh  Pure binary (executable)  This area contains the bootblock code. It's part of the copy of the last 128KB of the BIOS (previously BIOS component at E000:0000h - F000:FFFFh in the BIOS ROM chip). This code is shadowed here by the bootblock in BIOS ROM chip. This is where our code currently executing (the "copy" of bootblock in segment 2000h).
/ a7 ]0 s  Q. O4 j4100:0000h - 4100:57C0h  Decompressed  This area contains the decompressed awardext.rom. Note that the decompression process is accomplished by part of the bootblock code in segment 2000h.
- I1 c9 _% S* j, v5000:0000h - 6000:FFFFh  Decompressed  This area contains the decompressed original.tmp. Note that the decompression process is accomplished by part of the bootblock code in segment 2000h.
& R8 X/ _% \" q8000:0000h - 9000:FFFFh  Compressed  This area contains the copy of the first/lower 128KB of the BIOS (previously BIOS component at FFFC_0000h - FFFD_0000h in the BIOS chip). This code is copied here by the bootblock code in segment 2000h.
; h/ H0 a! ]; f, GE000:0000h - F000:FFFFh  Decompressed  This area contains copy of the decompressed original.tmp, which is copied here by the bootblock code in segment 2000h.
. W+ n( J# |$ s2 M- ]# s# T1 S& j& B* ~! z; S, Z* Y. Q( H  M' E: I
  最后要注意:这里解释的booblock只涉及到了normal Bootblock code execution path ,意思是没有解释一旦original.tmp崩溃时的bootblock POST。有时间的话,我将要涉及到。所有的bootblock如上,我们将要开始研究original.tmp。* |' m3 n" g- m1 Z9 v
7.2. System BIOS a.k.a Original.tmp) V5 e# G; o3 l8 z. {( h
  我们刚进行了上面的bootblock,我要高亮晦涩的代码执行路径。所以,现在,你正在看我的bios的解压了的original.tmp的反汇编代码。. ~& f6 S+ l) p' N0 B
7.2.1. Entry point from "Bootblock in RAM"
4 n! @5 l( K# VAddress    Hex                       Mnemonic1 Q  ?8 u4 \; k& B$ P
F000:F80D                            This code is jumped into by the bootblock code
% ~/ t) u. k  L7 fF000:F80D                            if everything went OK9 t& w, ?* R1 Q! X& ~) A3 d( L6 ?
F000:F80D E9 02 F6                        jmp sysbios_entry_point ;
$ x! t( w; Q6 x1 L这里是在重新定位和写保护system bios后,bootblock跳转的地方。
  {& q5 i( \3 W7.2.2. The awardext.rom and Extension BIOS Components (lower 128KB bios-code) Relocation Routine
; `8 e6 O% o& P" e/ i0 z% TAddress    Assembly Code
1 a6 s7 T1 }) }0 q+ ]F000:EE12 sysbios_entry_point:    ; CODE XREF: F000:F80D  h% y, n6 T% N
F000:EE12      mov ax, 0
8 N' F2 S6 }' DF000:EE15      mov ss, ax         ; ss = 0000h
* s% m/ v: A4 i# NF000:EE17      mov sp, 1000h      ; setup stack at 0:1000h
* X* {3 L( A& A0 ZF000:EE1A      call setup_stack   ; Call Procedure9 M! O/ V0 B& S
F000:EE1D      call init_DRAM_shadowRW ; Call Procedure
  u! J! G- F) y, ?: M3 h; tF000:EE20      mov si, 5000h      ; ds=5000h (look at copy_mem_word)
0 Z- w' p1 y' G; d/ Q4 KF000:EE23      mov di, 0E000h     ; es=E000h (look at copy_mem_word)
( G3 }! S' u' P- A2 |( l. p& ZF000:EE26      mov cx, 8000h      ; copy 64KByte
- Z& z) H" S, [9 _& fF000:EE29      call copy_mem_word ; copy E000h segment routine, i.e." N9 W# [; W/ Z
F000:EE29                         ; copy 64Kbyte from 5000:0h to E000:0h
  N! b, Z0 F$ u/ i) |F000:EE2C      call j_init_DRAM_shadowR ; Call Procedure
& Z' f/ I: K3 E) yF000:EE2F      mov si, 4100h      ; ds = XGroup segment decompressed, i.e.
9 t3 b5 Z3 ~( \0 FF000:EE2F                         ; at this point 4100h  p# {% c" B# b2 ^2 _  ?, f
F000:EE32      mov di, 6000h      ; es = new XGroup segment0 @0 V; X8 O# K
F000:EE35      mov cx, 8000h      ; copy 64KByte
; E% E$ s) L) ^, dF000:EE38      call copy_mem_word ; copy XGroup segment , i.e.
+ u  E5 u$ p& D- ~! ^F000:EE38                         ; 64Kbyte from 4100:0h to 6000:0h6 E( z: E9 I) I& \$ T) R: z' T
F000:EE3B      call Enter_UnrealMode ; jump below in UnrealMode. u' k' D3 P! J6 S
F000:EE3E Begin_in_UnrealMode4 Y) }: ^' K) }/ L2 g9 \
F000:EE3E      mov ax, ds6 L/ C' S9 E! p  W# N" x
F000:EE40      mov es, ax         ; es = ds (3rd entry in GDT)
; ~) l- D8 j' F' nF000:EE40                         ; base_addr=0000 0000h;limit 4GB
( ~) x3 p3 o( F7 uF000:EE42      assume es:nothing4 E: d+ k5 S$ }) Y0 _: d- m
F000:EE42      mov esi, 80000h    ; mov esi,(POST_Cmprssed_Temp_Seg shl 4)" j! z! v% s3 x" v8 F% T* i6 ]
F000:EE42                         ; relocate lower 128KB bios code
& N) v3 Y2 \! N! B! eF000:EE48      mov edi, 160000h6 U3 {  R$ J0 w5 h
F000:EE4E      mov ecx, 8000h; }! S; F7 P$ m
F000:EE54      cld                ; Clear Direction Flag! s2 V. K$ \5 U" G" U& c
F000:EE55      rep movs dword ptr es:[edi], dword ptr [esi] ; move % z5 e2 Q1 L8 y3 |$ R6 i
F000:EE55                         ; 128k data to 160000h (phy addr)
$ d# @/ |! [4 U2 T8 k: Q' S$ yF000:EE59      call Leave_UnrealMode ; Call Procedure
( T; S% A2 g/ s, B, v2 O$ z: DF000:EE59 End_in_UnrealMode4 g0 }; S8 x, |0 r/ j
F000:EE5C      mov byte ptr [bp+214h], 0 ; mov byte ptr
* k! E% w/ K; w/ kF000:EE5C                         ; POST_SPEED[bp],Normal_Boot
$ t  V; R6 y  Y% s# o, t. B, TF000:EE61      mov si, 626Bh      ; offset 626Bh (E000h POST tests)/ ^4 E' z8 `6 @+ L* R
F000:EE64      push 0E000h        ; segment E000h6 ^  \3 v4 p, [! a& p% K
F000:EE67      push si            ; next instruction offset (626Bh). w* }' k& z- H6 |( ~3 l5 }7 E
F000:EE68      retf               ; jmp to E000:626Bh
5 h8 |: \2 k6 P________________________________________
# X9 W9 X4 K+ b% {/ i+ H5 e- p. L  X- L
F000:7440 Enter_UnrealMode proc near   ; CODE XREF: F000:EE3B
2 p/ w5 M3 F+ _6 ^/ W, UF000:7440      mov ax, cs
8 y% U: n8 Z7 a1 b, [F000:7442      mov ds, ax         ; ds = cs
2 A8 j7 d1 D6 \1 y; J* n7 XF000:7444      assume ds:F000
' z( p3 s1 H! z+ A, EF000:7444      lgdt qword ptr GDTR_F000_5504 ; Load Global Descriptor Table Register
2 E; H. w/ G+ U( G& P" DF000:7449      mov eax, cr0
. S$ e- y$ U3 s: ?. SF000:744C      or al, 1           ; Logical Inclusive OR2 P& e. B" Z8 m- |) T- P
F000:744E      mov cr0, eax: G% {% n: X* D# _) Q/ C+ @5 r8 ]) g
F000:7451      mov ax, 10h
7 }; o. O7 L4 l+ J5 Y. x* G" vF000:7454      mov ds, ax         ; ds = 10h (3rd entry in GDT)
  T, D) W( b: ?  _9 EF000:7456      assume ds:nothing9 Z) U7 s3 i, U, @+ R
F000:7456      mov ss, ax         ; ss = 10h (3rd entry in GDT)2 l+ g0 K0 `2 p7 ]! d& N: b2 a
F000:7458      assume ss:nothing& _& p7 c" x- q
F000:7458      retn               ; Return Near from Procedure! A, {" c6 E1 r2 Q. b" d" I
F000:7458 Enter_UnrealMode endp3 r6 w6 K  H1 w+ V' n9 J
________________________________________
% F" @( t1 |) L1 Y9 ]7 G) z
( |) E" u4 ]* F7 h2 e, f6 aF000:5504 GDTR_F000_5504 dw 30h  ; DATA XREF: Enter_PMode+4& g( v  h7 i2 m; x, P( W
F000:5504                         ; GDT limit (6 valid desc)' C* f5 @" f8 P0 n+ Y! b
F000:5506      dd 0F550Ah         ; GDT phy addr (below)" c, ^5 g' s: d" h
F000:550A      dq 0               ; null desc0 }( l6 p0 y1 t# n+ W* u% R
F000:5512      dq 9F0F0000FFFFh   ; code desc (08h)4 H3 [6 e: A  B% A$ n/ _7 |/ l3 n
F000:5512                         ; base_addr=F0000h;seg_limit=64KB;code,execute/ReadOnly* R5 z3 V/ {& y" H. I/ T
F000:5512                         ; conforming,accessed;granularity=1Byte;16-bit segment;* f; ]1 ?% |2 o: X
F000:5512                         ; segment present,code,DPL=0
. ], C$ b! E6 n& M0 qF000:551A      dq 8F93000000FFFFh ; data desc (10h)
& n7 \" {5 i$ dF000:551A                         ; base_addr=0000 0000h;seg_limit=4GB;data,R/W,accessed;
. V" T5 [+ J, l/ C6 h& ZF000:551A                         ; granularity=4KB;16-bit segment; segment present,
  _3 @& x. R  XF000:551A                         ; data,DPL=0  @1 i- O- `( q5 B, [7 V: m
F000:5522      dq 0FF0093FF0000FFFFh ; data desc 18h
1 Z! _! t4 @6 B: ^* [' Y% {F000:5522                         ; base_addr=FFFF0000h;seg_limit=64KB;data,R/W,accessed;$ G2 M" @9 T4 P0 V2 }4 W5 S
F000:5522                         ; 16-bit segment,granularity = 1 byte;: s# H& D! `' V
F000:5522                         ; segment present, data, DPL=0.; Z* U8 @1 D/ D9 b! c( X
F000:552A      dq 0FF0093FF8000FFFFh ; data desc 20h
6 D6 z* n2 y" d& CF000:552A                         ; base_addr=FFFF8000h;seg_limit=64KB;data,R/W,accessed;
0 [( v! V7 ^6 j& MF000:552A                         ; 16-bit segment,granularity = 1 byte;
2 G$ I. z& o( U' ^# s" ^F000:552A                         ; segment present, data, DPL=0.
, b# F' d$ c" L- O) oF000:5532      dq 930F0000FFFFh   ; data desc 28h8 q; @! D4 L. e" B
F000:5532                         ; base_addr=F0000h;seg_limit=64KB;data,R/W,accessed;
& K& y$ J! y# ]! ?5 k4 e3 WF000:5532                         ; 16-bit segment,granularity = 1 byte;: n/ D4 H8 L$ R5 I! p# Q# R
F000:5532                         ; segment present, data, DPL=0.1 p! w  }3 A2 ^* w; ?7 v$ E
________________________________________$ p5 K/ e; C# p% P: G# r0 ]
注意:上面的代码执行以后,这个内存地图就再改变了一次。但是这个时候,只对于压缩BIOS扩展,比如低128KB的bios代码和解压缩了的awardext.rom,在上面bootblock解释到的内存地图部分的被覆盖了。
- r! e5 C! F2 z, Y" d' lNew Address Range in RAM  Decompression State  Description- g  c% D: U% Z, D( h
6000:0000h - 6000:57C0h  Decompressed  This is the relocated awardext.rom. N: b" B% m0 b. z: |. H
160000h - 17FFFFh  Compressed  This is the relocated compressed "BIOS extension", including the compressed awardext.rom. (i.e. this is the copy of FFFC0000h - FFFDFFFF in the BIOS rom chip. * S& {/ t0 }8 B6 U' z3 @7 m

0 q8 w5 T$ W$ H" N. }4 O7.2.3. Call to the POST routine a.k.a "POST jump table execution"
# @3 d& K9 q2 J) g7 {Address    Assembly Code
5 \; e- X2 m9 N4 Z, dE000:626B The last of the these POST routines starts the EISA/ISA9 v! S% g, s) {5 W* e6 o& X: z
E000:626B section of POST and thus this call should never return.
/ v& c  J' ^" k7 ?E000:626B If it does, we issue a POST code and halt.
# {% Y2 R5 Q5 S0 O% p# wE000:626B
1 n  a6 n2 W9 |) S% IE000:626B This routine called from F000:EE68h3 \/ c( ~; {- B9 p- ~
E000:626B
1 g" s9 I6 T+ C+ HE000:626B sysbios_entry_point_contd a.k.a NORMAL_POST_TESTS  z$ l- f; z1 v, Z6 s% @1 R
E000:626B      mov cx, 3          ; mov cx,STD_POST_CODE. W/ N4 {" ^0 t( p* t. L# L( z
E000:626E      mov di, 61C2h      ; mov di,offset STD_POST_TESTS
" w  l) Y! Y( \8 ?4 T- b- sE000:6271      call RAM_POST_tests ; this won't return in normal condition
1 A( |' C9 f" K' JE000:6274      jmp short Halt_System ; Jump
4 c5 p( J) [" d- s% ?________________________________________! [$ [* v5 f! K$ ?* a+ T

) v; p3 A; J; P3 lE000:6276 ; --------------- S U B R O U T I N E ---------------------------------------% ]0 {" v6 Z7 |6 ~: }; R
E000:6276
$ A) C7 |+ ?- A  M) n! Z  A! sE000:6276 RAM_POST_tests proc near ; CODE XREF: last_E000_POST+D/ U( M7 H) C" j/ m! N; x% Q
E000:6276                         ; last_E000_POST+18 ...
; I+ s( E% H! {E000:6276      mov al, cl         ; cl = 3
0 R% m' F7 `8 w8 L2 h8 Q! v) ]9 oE000:6278      out 80h, al        ; manufacture's diagnostic checkpoint9 b' _: h$ j8 e0 k
E000:627A      push 0F000h/ l* [" n( A1 T3 K
E000:627D      pop fs             ; fs = F000h+ b0 R2 x; X8 p, R. f8 K% K
E000:627F ) z4 o( f# n+ ^
E000:627F ;This is the beginning of the call into E000 segment
, K% p9 R% _# G3 [E000:627F ;POST function table7 m! k9 a9 O& g1 o: D) o
E000:627F      assume fs:F000
$ k$ w; H* s. I8 XE000:627F      mov ax, cs:[di]    ; in the beginning :3 r; }" i, T/ E, H! O7 q
E000:627F                         ; di = 61C2h ; ax = cs:[di] = 154Eh2 _4 b4 t% H! I2 t1 Q2 a
E000:627F                         ; called from E000:2489 w/ di=61FCh (dummy)* t! K% u5 g, v. j7 ?
E000:6282      inc di             ; Increment by 1; Q' P4 x" ^% [4 S* V
E000:6283      inc di             ; di = di + 2
0 [0 `8 e. z, X1 RE000:6284      or ax, ax          ; Logical Inclusive OR
* a" B& s; X! |* H  G  y; CE000:6286      jz RAM_post_return ; RAM Post Error! m7 x! u4 D6 P. K8 K
E000:6288      push di            ; save di6 q6 F  h. F! P0 D  R! d
E000:6289      push cx            ; save cx) w3 y4 X3 p" L+ `( `
E000:628A      call ax            ; call 154Eh (relative call addr)
1 w- w6 B  o6 D( NE000:628A                         ; ,one of this call
9 w& n2 j5 ?! _4 n! J; VE000:628A                         ; won't return in normal condition
8 I4 s$ S  R0 I- ~; m  qE000:628C      pop cx             ; restore all" i# j# ]# z3 M! L1 m
E000:628D      pop di
4 a% Y2 B: W# ^, X+ oE000:628E      jb RAM_post_return ; Jump if Below (CF=1)
" R( L2 Z5 O2 B9 ^( X4 @( oE000:6290      inc cx             ; Increment by 16 n* B" P: P' g, @- Z
E000:6291      jmp short RAM_POST_tests ; Jump
) m* U3 O% g. T4 [- Q# t' g' iE000:6293 ; ---------------------------------------------------------------------------: R$ F7 A7 u1 w. n$ p
E000:6293 ! X# b7 f* n1 L: N; O3 Y. C! ?
E000:6293 RAM_post_return:        ; CODE XREF: RAM_POST_tests+10' c) F8 m! ], L5 d
E000:6293                         ; RAM_POST_tests+18
) T6 M/ ^1 ?( wE000:6293      retn               ; Return Near from Procedure# ~$ B: H$ \8 D" U; c: I4 H, K
E000:6293 RAM_POST_tests endp
/ O) o) G  O6 t$ a. z) u________________________________________3 B/ j9 Y# |" \: F. X  v6 P$ b

7 f4 _0 Y" Y/ YE000:61C2 E0_POST_TESTS_TABLE:
' J+ ]# t; T/ f& ]( ME000:61C2      dw 154Eh           ; Restore boot flag
2 [- T7 M; ]4 C  J, j4 sE000:61C4      dw 156Fh           ; Chk_Mem_Refrsh_Toggle. _( f" B. W' R- c- }9 Y! K
E000:61C6      dw 1571h           ; keyboard (and its controller) POST3 l7 C' w, G( y% g# F
E000:61C8      dw 16D2h           ; chksum ROM, check EEPROM
3 h7 H/ y* b" `: B4 `E000:61C8                         ; on error generate spkr tone7 {  \* b+ k" G  T: Z( Q' V  P
E000:61CA      dw 1745h           ; Check CMOS circuitry
) \! E. h0 }. Y+ k9 T) _7 o# BE000:61CC      dw 178Ah           ; "chipset defaults" initialization
1 y4 w- u7 G' l" i' kE000:61CE      dw 1798h           ; init CPU cache (both Cyrix and Intel), @; M8 f- v/ V5 S; X) s3 {
E000:61D0      dw 17B8h           ; init interrupt vector, also initialize 2 l* ]" ?8 O/ s/ ^
E000:61D0                         ; "signatures" used for Ext_BIOS components - }6 k7 f/ t( Q. y  t4 M
E000:61D0                         ; decompression5 K/ y2 _; o  ?0 e
E000:61D2      dw 194Bh           ; Init_mainboard_equipment & CPU microcode3 L' k0 X  G2 v/ ]) x! }1 n; M' o
E000:61D2                         ; chk ISA CMOS chksum ?: B9 [, y# a) d+ T- r! ]
E000:61D4      dw 1ABCh           ; Check checksum. Initialize keyboard controller( {6 V) c& J, @5 _
E000:61D4                         ; and set up all of the 40: area data.
$ `7 Z) G3 ~6 U4 RE000:61D6      dw 1B08h           ; Relocate extended BIOS code" R* s5 S. E' m* h
E000:61D6                         ; init CPU MTRR, PCI REGs(Video BIOS ?)
( L: c& j, R7 d! X9 G8 jE000:61D8      dw 1DC8h           ; Video_Init (including EPA proc)' \' o8 j8 Z4 P- Y- I
E000:61DA      dw 2342h
' s& o1 J6 v# V8 [4 ZE000:61DC      dw 234Eh
3 S6 ~  g8 x; T# p% DE000:61DE      dw 2353h           ; dummy# E, ~7 {8 p* I( A$ n' ~4 o4 ?: }2 }
E000:61E0      dw 2355h           ; dummy
8 s/ [, d( o# ~7 uE000:61E2      dw 2357h           ; dummy. E7 j( U" |. b2 v( z
E000:61E4      dw 2359h           ; init Programmable Timer (PIT)
! d& m" O" \) i% d5 RE000:61E6      dw 23A5h           ; init PIC_1 (programmable Interrupt Ctlr)
8 s4 v+ i7 }( t( z& YE000:61E8      dw 23B6h           ; same as above ?0 a, \' O1 E, g5 C  V! _- x
E000:61EA      dw 23F9h           ; dummy) [2 J5 M& z. t5 W6 Y
E000:61EC      dw 23FBh           ; init PIC_2; j" Y8 y7 t9 L. n1 G* ^
E000:61EE      dw 2478h           ; dummy3 ~; w- H4 @* [1 U$ I% H; @
E000:61F0      dw 247Ah           ; dummy9 r) }4 c. V8 f  s
E000:61F2      dw 247Ah
, F8 ^1 v. f( H& LE000:61F4      dw 247Ah) B$ ]2 S/ ~  b$ s' l- _1 W- q( ]  i
E000:61F6      dw 247Ah" {* C' A9 H0 ^6 t# C4 v
E000:61F8      dw 247Ch           ; this will call RAM_POST_tests again , q; F9 K# b# b" D$ _0 X
E000:61F8                         ; for values below(a.k.a ISA POST)7 o4 Z& o* \, f0 r2 J
E000:61FA      dw 0
4 A7 O/ `- b3 m- P+ C$ y% |' fE000:61FA END_E0_POST_TESTS_TABLE% c& a; B: B, y! H* e7 N0 Z- g! m, o
________________________________________" t, B0 U: S" l- \( u
. H% q6 z- n" o: S' v- w4 U3 b
E000:247C last_E000_POST proc near: E7 [% C) ]# p7 ]8 D7 X1 H- u; L
E000:247C      cli                ; Clear Interrupt Flag
8 w* H* L( M, O/ q4 j- J( k& K; _E000:247D      mov word ptr [bp+156h], 0
( ^! v# D$ N6 B- W3 X3 w2 i/ FE000:2483      mov cx, 30h ; '0'
6 x# M- P' l* @2 P0 SE000:2486      mov di, 61FCh      ; this addr contains 0000h
4 u6 m2 z4 ^! E- o: k5 OE000:2489 & a3 ?# }% [* ]4 U
E000:2489 repeat_RAM_POST_tests:  ; CODE XREF: last_E000_POST+10
  r6 n( }  E, QE000:2489      call RAM_POST_tests ; this call immediately return
, {$ i& X( N; x7 |& U4 r5 E* TE000:2489                         ; since cs:[di]=0000h
: u) g3 q+ |, w* H8 UE000:248C      jb repeat_RAM_POST_tests ; jmp if CF=1; not taken
# H! H: K+ ~: x' `$ B4 L, T# eE000:248E      mov cx, 30h ; '0'
5 P/ C- @2 C# I; I) l5 \E000:2491      mov di, 61FEh      ; cs:[di] contains 249Ch8 K0 L( b& p  `- {9 g; A
E000:2494
/ K- q$ Y- n0 NE000:2494 repeat_RAM_POST_tests_2: ; CODE XREF: last_E000_POST+1B
2 v9 l1 K- J* S; K7 Y3 d/ s5 Q: w% }E000:2494      call RAM_POST_tests ; this call should nvr return if2 F% J4 ~0 h' w& D9 }: h
E000:2494                         ; everything is ok
7 \0 k  z. C7 v/ x$ u8 L+ ]E000:2497      jb repeat_RAM_POST_tests_2 ; Jump if Below (CF=1)
. P6 r& b4 i7 |3 {1 PE000:2499      jmp Halt_System    ;
: D! G/ {, q* jE000:2499 last_E000_POST endp
: |; t" Z8 F5 u1 T4 a________________________________________; a# i0 j3 x  C7 c6 [' c. w2 o8 a1 _
2 g$ D) P" w# J* T' `' E( F, y) V
E000:61FC ISA_POST_TESTS" k! \; y; Z. n* r. N2 Y
E000:61FC      dw 0; W" S/ |! y' }3 z* ^
E000:61FE      dw 249Ch2 O& r4 M$ E( a( \
E000:6200      dw 26AFh
% A! E8 f4 V0 h7 S) g% j$ @! V8 K& iE000:6202      dw 29DAh& K4 g) b+ F4 B% d
E000:6204      dw 2A54h           ; dummy
0 z1 S0 }7 W5 }) f/ w* pE000:6206      dw 2A54h- P1 k$ a9 |0 z) G8 r7 F
E000:6208      dw 2A54h
6 P! v( l, _5 g; q7 FE000:620A      dw 2A54h
5 Z; |/ k8 m8 d9 u0 y( Y! [E000:620C      dw 2A54h9 v8 D& N# g2 X' b3 C/ A& q
E000:620E      dw 2A54h  k# V/ C. J& J; J
E000:6210      dw 2A56h           ; dummy
; _" c% j7 b( [+ u: x/ ~# iE000:6212      dw 2A56h
, t8 W# W  o2 \4 R' ^$ f" jE000:6214      dw 2A56h+ C+ x% P% C5 H! G) e6 H
E000:6216      dw 2A58h
. [, B# z$ Y- }; Y; W* h# u3 i( }E000:6218      dw 2A64h
4 |6 R" ?4 W* ]2 r: z( [E000:621A      dw 2B38h
" j$ [, p6 U, g5 r, I2 dE000:621C      dw 2B5Eh           ; dummy8 s0 q' A- Z& T, c& R
E000:621E      dw 2B60h           ; dummy
$ b0 C* c# I+ Q) Q4 Z0 u, sE000:6220      dw 2B62h
0 Q2 q+ {: a  _* oE000:6222      dw 2BC8h           ; HD init ?" d4 _" z, }8 F$ ?2 O% Z" }' [
E000:6224      dw 2BF0h           ; game io port init ?% g- o( W. m) p! A! u. V9 r0 ]4 q
E000:6226      dw 2BF5h           ; dummy
: b; \% a1 M- ?E000:6228      dw 2BF7h           ; FPU error interrupt related( E; q+ J/ q3 V( ^2 I! D  z7 y
E000:622A      dw 2C53h           ; dummy& m( {$ Q" C2 k: o, b3 I
E000:622C      dw 2C55h% V$ k5 M  X, H) r" h( x0 A6 a
E000:622E      dw 2C61h           ; dummy
" h+ f% Q6 I( c1 l' g8 Q% S6 PE000:6230      dw 2C61h: i& l. l9 H2 c: K) X/ f, V
E000:6232      dw 2C61h2 ]% R9 F; n6 }, O8 `: Q2 T7 G
E000:6234      dw 2C61h
9 Q: c8 |. T) G1 cE000:6236      dw 2C61h0 S2 n$ X- c$ G
E000:6238      dw 2C61h
5 v6 R7 j+ [+ v# o* yE000:623A      dw 2CA6h
6 i6 a! Y$ l% A0 r9 B3 f1 V4 O3 W# `E000:623C      dw 6294h           ; set cursor charcteristic
1 n1 f$ J  l% ^( _* _$ C) EE000:623E      dw 62EAh
1 E  w4 c6 O9 m6 \6 mE000:6240      dw 6329h( [9 z: X# X5 ?, v6 A( o$ q" w
E000:6242      dw 6384h
( s: W# J( C9 i% u! ], OE000:6244      dw 64D6h           ; dummy" W8 E( d( v  e
E000:6246      dw 64D6h
2 ]  z$ _8 a! }: yE000:6248      dw 64D6h
$ T$ w3 L" y" y3 XE000:624A      dw 64D6h
3 w3 x* S0 {: V& @( \/ yE000:624C      dw 64D6h
" n$ t+ c! U' }8 D3 P0 O! w1 t& O% CE000:624E      dw 64D6h
0 _- b- Y4 e3 {  X3 j  ^- d1 [E000:6250      dw 64D6h% z8 C0 G- h4 O) [3 J. a
E000:6252      dw 64D6h
& N8 o, z  ?5 ]: C. Q: BE000:6254      dw 64D6h0 l2 H) T9 Q- h$ S$ N: O
E000:6256      dw 64D6h
6 o$ h% y& S: P% U2 IE000:6258      dw 64D6h
% I9 U( ?; M0 eE000:625A      dw 64D6h0 P0 p2 B0 Z7 @% R
E000:625C      dw 64D6h. x2 _: b2 r. n7 ^) p  {
E000:625E      dw 64D8h           ; bootstrap# B4 q4 H5 M& _8 L% h- b! P
E000:6260      dw 66A1h5 ^7 c! o7 y6 E7 [( g& e1 ~' G
E000:6262      dw 673Ch3 `0 W( {4 J7 |/ a; e, ~$ V
E000:6264      dw 6841h           ; issues int 19h (bootstrap)
2 O, s% z6 ^, vE000:6266      dw 0& C  {3 M: K2 |' r
E000:6266 END_ISA_POST_TESTS
& k% M6 y( p8 N9 Q" j5 ?: u3 ?( l+ N/ \, I0 s8 k
注意:6 |" y# B. ]0 [
这个“POST jump table”例程在他们遇到一些执行错误的时候会设置Carry Flay(CF=1)。在POST例程返回,这个Carry Flag就要被测试,如果它被设置,然后这个“RAM_POST_TESTS”就会立刻返回,这样就会使系统崩溃,系统扬声器就会发出声音。:)
回复

使用道具 举报

 楼主| 发表于 2007-11-16 13:30:13 | 显示全部楼层
7.2.4. The "segment vector" Routines
- K+ k: m$ u) s/ W6 E% y) u  下面只是一个它的用法例子。它有很多地方用得到。有一对这样的“段向量”。一些就要从段E000h跳转到F000h,一些从段F000h跳到E000h,一些从E000h到6000h(重新定位的解压了的awardext.rom),一些从F000h到6000h(重新定位的解压了的awardext.rom)。) {4 i0 D1 x; ~! |8 x
a.  First variant: jump from segment E000h to F000h ' f4 w* L) L& c: u
b.  Address    Assembly Code+ A: P/ T$ R5 i, @
________________________________________
- H' u9 n4 d: w& M# E5 C% {5 `; F+ y
E000:1553 Restore_Warm_Boot_Flag proc near ; CODE XREF: POST_1S3 q3 o7 `/ @* g+ P2 v
.........! }7 L( v# R( u& f
E000:155A   call  F_Vect_Read_CMOS_Byte! Z; C3 l2 O& U7 }% F
.........1 R2 ~5 X' V  @3 x3 s: k- ?
E000:156E Restore_Warm_Boot_Flag endp+ ^! I* P1 ?7 z
________________________________________
  o6 {/ h2 Z0 f' r( p% q2 I$ {( w
3 p+ I5 B+ s" {# n& n* jAddress    Machine Code          Assembly Code+ ?) v$ G9 F" n0 Q; k8 O: i
E000:6CA2 F_Vect_Read_CMOS_Byte proc near ; CODE XREF: Restore_Warm_Boot_Flag+7 p
0 @9 N* X! {' o9 U$ [# KE000:6CA2                             ; 000E1747 p ...
9 _0 i5 q! n0 B2 Y4 ME000:6CA2   push  0E000h1 p- j: B1 X! f! h, @
E000:6CA5   push  6CB3h+ Q$ _: l8 L9 M
E000:6CA8   push  0EC31h
- M5 P& S" z3 eE000:6CAB   push  0E4FDh              ; Read_CMOS_Byte) z& k! h! O2 h) x
E000:6CAE   jmp   far ptr F000_Vector* q# e: ~* f! r4 n6 r
E000:6CB3 ; ---------------------------------------------------------------------------
0 v  d  u; ^6 W) O! ?* \/ eE000:6CB3   retn
/ T) t% D& {( q1 W+ B6 \5 jE000:6CB3 F_Vect_Read_CMOS_Byte endp
* |! g5 M7 T' o0 Q- {% k9 U________________________________________
& O$ R9 j. T; y/ R& y
6 j7 Q# m  l" g; DF000:EC30 F000_Vector:                ; CODE XREF: 000E1781 J 000E17AA J ...
$ X" C0 I1 a% ~* ^% |. e2 q( PF000:EC30   retn1 s) e% z. ?7 `4 g" L1 y; t
F000:EC31 ; ---------------------------------------------------------------------------9 G( f: I: l. X  Z8 v& t
F000:EC31   retf. q4 `, [/ q1 _: i
________________________________________9 N) b3 n3 l+ K2 U4 S2 U

4 N& x/ N- J( j! [0 kF000:E4FD Read_CMOS_Byte proc near- c- V  H+ I& D( Z0 d5 B0 |
F000:E4FD   xchg  bx, bx
0 J. ?3 M& \3 Q8 ]F000:E4FF   nop2 a8 z$ E" G& o6 G; r6 n
F000:E500   out   70h, al             ; CMOS Memory:+ C# k4 {0 j2 y- D/ y  {7 [
F000:E500                             ; used by real-time clock
0 j8 _' [$ W4 K! R/ eF000:E502   jcxz  short $+2$ c  U! Z3 ^. ~6 k3 c
F000:E504   jcxz  short $+2. E# i9 U* r- Z4 E3 o" m
F000:E506   xchg  bx, bx
1 L: d' D. x/ {( P& jF000:E508   in    al, 71h             ; CMOS Memory
% K. }  X/ X( Y4 VF000:E50A   jcxz  short $+2
! b' N% e" Y  Z  g' ?( ]/ EF000:E50C   jcxz  short $+2  r  }5 o9 d8 R
F000:E50E   retn  F% P1 ~0 v6 u. H* X: k
F000:E50E Read_CMOS_Byte endp+ T; _* z6 D7 Q. }) c
________________________________________$ |. K$ T) c3 g2 A- ^
5 y5 F! F" h; C
c.  Second variant: jump from segment E000h to 6000h 7 Q$ c5 {$ L8 u# U8 f# B
d.  Address    Machine Code          Assembly Code
# v2 V1 I! S0 o5 X- `* x: x% R& H________________________________________
6 \! x4 N+ g0 d% o9 {9 k5 i, y; y, N1 e6 B
.........& s. Z& D8 g! l2 N: h. D$ Y
E000:1737   push  cs
& x! r0 a) M# q0 }E000:1738   push  1743h               ; ret addr below+ A' Z% g7 s% e9 C- h: f
E000:173B   push  1829h               ; func addr in XGROUP ROM
6 t$ v& f1 ?# z2 K; ~5 \) g( R- kE000:173E   jmp   far ptr loc_6000_2: H! B6 W" n) Z4 E( m7 l& K, n7 f
E000:1743 ; ---------------------------------------------------------------------------; b$ I3 b" T; r
E000:1743   clc2 Z; y+ I4 i% l3 N
E000:1744   retn+ @9 G$ V8 q5 u* ~* b+ v, z! w" Y
.........
+ _8 K2 J$ g+ ?1 P; P5 E9 @. G________________________________________
* s& I, a9 X/ p& P3 `  `3 N: T: I5 m
6000:0000 locret_6000_0:              ; CODE XREF: 00060017 j/ r8 Y" O7 t* G, h7 T; |
6000:0000   retn                      ; jump to target procedure4 p0 r7 u1 ]: t- }
6000:0001 ; ---------------------------------------------------------------------------
% E. F2 T! H+ R+ c6 V1 a  k6000:0001   retf                      ; back to caller
4 g, n1 N3 s+ F. d- q9 y# o________________________________________6 k. B4 M# _4 Y2 G% o

+ L9 `$ n& i' `+ W7 x, F8 @6000:0002 loc_6000_2:                 ; push return addr for retn
# l/ H6 d) B$ F, f6 [6000:0002   push  1                   ; (addr_of retf above)1 j1 T: p0 f. E0 ~; d
6000:0005   push  ax
+ C: [0 [$ @. M: S( {. t6000:0006   pushf+ v. n) s% a5 s# e
6000:0007   cli* Z9 }1 h3 j1 b/ W2 [* Y1 v8 _
6000:0008   xchg  bp, sp
) l. P% o+ j# T7 j9 _7 M6000:000A   mov   ax, [bp+4]          ; mov ax,1 ; look at 1st inst above! h7 i- D) ]4 W
6000:000D   xchg  ax, [bp+6]          ; xchg ax,word_pushed_by_org_tmp  x* j8 ?1 g! I4 J" K7 U2 z8 S
6000:0010   mov   [bp+4], ax          ; [sp+4] = word_pushed_by_org_tmp
8 F; t, t& o8 g' |' b9 }; b8 ^! B6000:0013   xchg  bp, sp              ; modify sp& ?7 {+ `9 r; Z2 \
6000:0015   popf
& ?4 s5 ~5 w0 l! z1 J5 `6000:0016   pop   ax; y% l$ q5 o: H  D+ v
6000:0017   jmp   short locret_6000_0 ; jump into word_pushed_by_original.tmp
( O- F+ I) p# j. q6 o' ~________________________________________  Y) b6 e2 w" [

6 r; l; c; M1 h+ o! h6000:1829      cli                    ; Clear Interrupt Flag
6 i8 y7 |6 {' V6 p8 f.........- r* s7 w# D  `, l, F% b* I
6000:18B3      retn                   ; Return Near from Procedure+ s# q% ^1 K' }1 j* d( W5 D
________________________________________6 y/ W" M6 X7 Z& o, v1 d
7 g. c1 m$ z6 z# j; z- M* @
e.  Third variant: jump from segment 6000h to F000h 4 E5 l+ P2 g3 ~
f.  Address    Assembly Code  i1 W. G+ x+ g/ c5 C4 Q& W% J* e
________________________________________
7 s0 h( q; E* ?* J7 N( S! @1 b  |& S" l( A; C( I$ K' k  w2 `1 R
6000:4F60 reinit_chipset proc far
% Z/ Z- q) {' j6000:4F60      push ds
. q( D1 h4 N4 {6000:4F61      mov ax, 0F000h
* d' T  y$ \+ O4 q2 `  [" I9 r6000:4F64      mov ds, ax             ; ds = F000h" w; `  j7 O2 `  b. p
6000:4F66      assume ds:nothing: y* P/ I) R) @; l* D. N9 k/ W
6000:4F66      mov bx, 0E38h          ; ptr to PCI reg vals (ds:bx = F000:E38h)
2 |& d) B* I4 h) r6000:4F69
; a5 }) E) {( F0 s2 ~8 a6 v6000:4F69 next_PCI_reg:               ; CODE XREF: reinit_chipset+3D+ u! x. m: ?1 Z- ^
6000:4F69      cmp bx, 0EF5h          ; are we finished ?
0 m+ a5 `2 n+ e/ S5 K6000:4F6D      jz exit_PCI_init       ; if yes, then exit
$ i1 Q7 d' L  ]4 y. S8 s- f, ~" \6000:4F6F      mov cx, [bx+1]         ; cx = PCI addr to read
8 y2 y" p( |0 D* q7 e: a9 J: e; @6000:4F72      call setup_read_write_PCI ; on ret, ax = F70Bh, di = F725h8 }, o- @+ s# [& R
6000:4F75      push cs8 o& K3 Y4 ]" U6 ~4 r
6000:4F76      push 4F7Fh+ H% P, G! B. I0 u) |# ^
6000:4F79      push ax                ; goto F000:F70B (Read_PCI_Byte)* O7 ~$ D  P* L; L& ~
6000:4F7A      jmp far ptr 0E000h:6188h ; goto_seg_F000. F" e! ?$ L  {+ v+ c
6000:4F7F ; ---------------------------------------------------------------------------% b) t' a) @4 ~8 f: G/ l
6000:4F7F      mov dx, [bx+3]         ; reverse-and mask
8 m0 i" z, e9 x$ z5 e' A, Z( F.........) ?6 A5 |8 h2 H7 v- X
________________________________________* N, u0 O$ R6 f; n! c2 D
7 j8 A# {8 C$ r) o9 z; o
E000:6188                   goto_F000_seg:          ; CODE XREF: HD_init_?+3BD8 p* b* m  j! A7 w) h# e- D: i
E000:6188                                           ; HD_init_?+578 ...
) y2 _# E1 F' r2 [; `: q9 ~: gE000:6188 68 31 EC               push 0EC31h6 g6 }4 c/ T/ g% t* U
E000:618B 50                     push ax
  x# A) U, t7 XE000:618C 9C                     pushf              ; Push Flags Register onto the Stack
0 o' p2 [3 e7 L# `" d. K- m; i  RE000:618D FA                     cli                ; Clear Interrupt Flag) H2 ?; W  R" D/ Z% B
E000:618E 87 EC                  xchg bp, sp        ; Exchange Register/Memory with Register, i6 v4 {' y3 q& H7 A) L
E000:6190 8B 46 04               mov ax, [bp+4]     ; mov ax, EC31h+ b& u; N/ v8 [+ J" m6 a6 Y" ~# ^& G
E000:6193 87 46 06               xchg ax, [bp+6]    ; xchg ret addr and EC31h% D  x9 |& M5 Y' f( v( N/ j
E000:6196 89 46 04               mov [bp+4], ax     ; mov [sp+4],[sp+6]9 r" w7 W5 w" i8 o$ A. L
E000:6199 87 EC                  xchg bp, sp        ; Exchange Register/Memory with Register. m& T6 ]* n! C* ]* U
E000:619B 9D                     popf               ; Pop Stack into Flags Register
* }) T& q) E1 _& ?8 y9 p, `E000:619C 58                     pop ax3 Y4 D1 s# f* r0 ~: V1 P( N
E000:619D EA 30 EC 00 F0         jmp far ptr F000_func_vector ; Jump
3 @' O0 C9 [/ Z$ ]# p' F________________________________________4 u7 K3 r4 r9 E4 X
0 |0 Q  T* \2 i. }) @
F000:EC30                   F000_func_vector:       ; CODE XREF: chk_cmos_circuit+3C
; p" a& W) ~. s; I7 ^& d/ AF000:EC30 C3                     retn               ; jump to target function
9 i3 P# C- U7 Z8 G+ aF000:EC31                   ; -------------------------------------------------------------------7 X/ t: e' A$ w: @; M9 B; K, i
F000:EC31 CB                     retf               ; return to calling segmentffset (6000:4F7F)# e" V, @7 u: H* ]7 y( U% H- z( \/ m$ n
________________________________________( j) i) p5 v$ R$ I- \7 L5 G; s. c; V

: {+ ]: ?" ?- g  H' }F000:F70B read_PCI_byte proc near ; CODE XREF: enable_ROM_write?+4
8 S2 @! c9 }: e; J9 T: S2 `9 r# A9 `.........% {' k5 h, |$ v" Y* Z
F000:F724      retn               ; Return Near to F000:EC31h4 L& c% [/ c/ |0 P- o5 ^  a" ^' |
F000:F724 read_PCI_byte endp
. I( ~: j: a0 G( I8 I, n( [* }4 g' p
7.2.5. "chksum_ROM" Procedure
) t0 g$ _: B# T: S  这个例程是“E0_POST_TESTS”的一部分,“E0_POST_TESTS”是由POST例程通过使用“POST jump table”来调用的。这个例程没有立刻的返回。但是,一个调用到“Check_F_Next”的调用将会完成这个“near return”,这个近返回需要继续进行下一个“POST 进程”的执行。+ m/ S# |2 R$ x# y
________________________________________7 I0 {( x  I$ l- \- j& \
E000:16D2                   chksum_ROM proc near
& h( B" E* b: F3 r, a- l.......... D% E" N! ~  e& Q  P# l% b5 \
E000:16FF 74 1E                  jz Check_F_Next    ; yes. This jump will return this routine , p& C9 A  C- q
E000:16FF                                           ; to where it's called- n) C4 n5 o" E; w: \9 A; U1 _
.........
, A# K: |, \, J; TE000:171D EB E6                  jmp short spkr_endless_loop ; Jump
3 f  Q2 f2 U8 B* ^E000:171D                   chksum_ROM endp; s* C# X  P6 X# o' t
________________________________________+ H( F4 O% x6 e, w7 h( V
E000:171F                   Check_F_Next proc near  ; CODE XREF: chksum_ROM+2D% {9 `, |9 ~# q  ]8 u0 j* l
.........
& [, K. r, c3 H7 c8 x7 I  K$ yE000:1743 F8                     clc                ; signal successful execution; \" S0 Y! r4 D2 C
E000:1744 C3                     retn               ; retn to RAM_POST_TESTS, proceed to next POST proc
; p- o( S, I" C- LE000:1744                   Check_F_Next endp ; sp = -6) L! E4 Z  ]9 p( V6 R
________________________________________, i, Y1 f2 q2 ^8 P9 n  |" {
7.2.6. Original.tmp Decompression Routine for The "Extension_BIOS Components"
4 y, }- t$ O5 u- }, x# m2 r这是一个在最开始的时候最会混淆的地方。但是,通过理解它,我们实际上的没有更多的需要对“bios 代码执行路径”担心的。我怀疑我们这里要解释的相同的技术适用于绝大部分的award bios。这个例程基本的run-down解释如下:' i1 A" I' K% t1 b; a( S2 M& _5 v  b
a.  Decompress_System_BIOS 历程被“主bootblock执行路径”(在bootblock代码在地址段2000h执行期间)调用,保存了必需的对在RAM预先确定区域有用的标志,下面展示:" s7 k2 P/ R) _. V0 F
________________________________________4 H% Y( A8 X5 G2 M) ^
2000:E512 Decompress_System_BIOS proc near ; CODE XREF: 0002E3DC
6 d/ A; ^, N! N& U! B0 f% _2000:E512 E8 EB DA                  call  Copy_C_seg_n_D_seg  ; copy lower 128 KByte bios code from ROM (at FFFC_0000h -
+ }, w6 c, O/ L! v7 u4 q, J2000:E512                                                     ; FFFD_0000h) to RAM (at 8000:0000h-9000:FFFFh)( x3 E- G% e4 q0 w& ?9 x5 B
2000:E515 32 E4                     xor   ah, ah
5 l2 p6 P- J0 b+ f2 o4 t- |2000:E517 33 C9                     xor   cx, cx  n' c/ a- X% N# E* h8 M3 e
2000:E519 BB 00 80                  mov   bx, 8000h. V* V  O" d8 j1 ^- }0 r
2000:E51C 8E DB                     mov   ds, bx              ; ds = 8000h, contains compressed9 x, K* u" @/ P$ A7 i. c$ s" F2 ]  D, V
2000:E51C                                                     ; lower 128KB bios components (awdext,etc.)
% r+ R3 j% ~  F0 |, D3 x- Z2000:E51E                           assume es:nothing, ds:nothing
5 f6 @6 |( q! |+ f/ m) \- Y2000:E51E 33 F6                     xor   si, si
* z3 j" i: v9 S% r# }2000:E520                         next_Cseg_Dseg_byte:        ; CODE XREF: Decompress_System_BIOS+116 X7 Z! H- F! l, x+ b# M
2000:E520                                                     ; Decompress_System_BIOS+1F7 o, N7 u1 v0 \8 {4 B- ^8 J' @
2000:E520 AC                        lodsb
* }2 x/ y5 {6 ?/ x2 \2000:E521 02 E0                     add   ah, al              ; calc 8-bit chksum of C_seg n D_seg
% J* Z, {" y& x+ j9 C7 ]: ]* g2000:E523 E2 FB                     loop  next_Cseg_Dseg_byte
1 F9 ?: V' i  X2000:E525 8C DB                     mov   bx, ds+ U* L7 o4 d$ Z5 K
2000:E527 80 FF 90                  cmp   bh, 90h ; '?'       ; are we in seg 9000h?
0 n8 [' ]" w! Y* J+ F7 o" ]/ I! K2000:E52A 73 07                     jnb   short done) {7 O1 R0 [5 B7 J
2000:E52C 80 C7 10                  add   bh, 10h             ; move to next higher segment
8 D% l0 {/ n1 [* Z- L& r0 Q- `/ i2000:E52F 8E DB                     mov   ds, bx' W: ^2 ~# U7 k) _8 K  R2 o# D* `
2000:E531                           assume ds:nothing
- h( z! x, r( @4 ]  d0 N4 w2 I6 v2000:E531 EB ED                     jmp   short next_Cseg_Dseg_byte
1 K; r! c6 D1 z7 g3 w) a, Z* H0 }2000:E533                         ; ---------------------------------------------------------------------------
! W6 A2 V  e$ x. a2000:E533                         done:                       ; CODE XREF: Decompress_System_BIOS+18
% p% A9 c) e  x  K& t, }) t) G2000:E533 BB 00 10                  mov   bx, 1000h" d9 Y- j. ?* f$ s
2000:E536 8E DB                     mov   ds, bx              ; ds = start_addr_of E_seg n F_seg in RAM& p+ |* B  ~8 _& l
2000:E536                                                     ; (compressed original.tmp + bootblock)+ e. ~2 l( P+ t
2000:E538                           assume ds:_1000h( _# a  y- w$ y+ e; \3 y
2000:E538 33 F6                     xor   si, si
# Q7 _* k+ ]( @6 R- s0 s# h; Z2000:E53A FC                        cld! H$ g. ]/ H  n: p1 S0 g5 m8 u
2000:E53B                         next_Eseg_Fseg_byte:        ; CODE XREF: Decompress_System_BIOS+2C) Z: v5 X6 Z" ^) |; ]0 O) N; ~' ?
2000:E53B                                                     ; Decompress_System_BIOS+3B
& ]( S8 e& P0 ~) x9 G2000:E53B AC                        lodsb/ k8 [) u% ?/ n( K
2000:E53C 02 E0                     add   ah, al              ; calc 8 bit chksum, cont'd from chksum above' ^3 U5 X0 ]/ J! d! W
2000:E53E E2 FB                     loop  next_Eseg_Fseg_byte
7 G! R, x* t8 M  y2000:E540 80 FF 20                  cmp   bh, 20h ; ' '       ; are we in seg 2000h?1 N9 Y) C0 }3 R6 j% ?
2000:E543 73 0A                     jnb   short chksum_done
  B8 `: p6 ^/ j2 t2000:E545 80 C7 10                  add   bh, 10h             ; move to next higher segment
8 k! W* O0 S3 y" N; Z2000:E548 8E DB                     mov   ds, bx; N3 V( {2 T9 P% ^& G9 F% N
2000:E54A                           assume ds:_2000h
9 Z" ?* h6 {( d2000:E54A B9 FE 7F                  mov   cx, 7FFEh           ; amount of byte in last seg (F_seg in RAM) to calc' F! L- c3 ~/ Y$ ~$ M+ b/ E
2000:E54D EB EC                     jmp   short next_Eseg_Fseg_byte
5 w( R+ `/ k# D* ^2000:E54F                         ; ---------------------------------------------------------------------------
, V. W) E+ ^5 `2000:E54F                         chksum_done:                ; CODE XREF: Decompress_System_BIOS+31 j8 L- r! q0 j. x& w2 ~
2000:E54F 3A 24                     cmp   ah, [si]            ; cmp calc-ed chksum and chksum pointed to by [si].
4 W! `% m: i& v6 E7 ]* a2000:E54F                                                     ; this is the chksum for the bios binary
( c$ E' e+ h# C* L2000:E54F                                                     ; from 00000h to 37FFDh (C000:0h - F000:7FFDh)% U1 P6 ^- F2 e' z8 d0 B
2000:E551 0F 85 8C FE               jnz   _sysbios_chksum_error ; jmp back and continue to bootblock error handling routine
/ U8 @3 c: p$ L1 D" v% p- i5 y5 \2000:E555   mov   bx, 0
! B. C2 o0 }& X# Q7 U2000:E558   mov   es, bx
, v7 D- _8 f- e+ Y2000:E55A   assume es:nothing
" x2 [' s6 N- z- R# D- B2000:E55A   mov   es:word_0_7004, 0FFFFh ; save signature to be used by original.tmp# D7 o, p+ L4 T7 ]
2000:E55A                                ; (POST_8S) for decompression6 Q) a: R) q9 ~
2000:E561   xor   al, al
) N2 J/ v5 L9 B* n. r2000:E563
  H& _0 R8 b; o9 p" ?; W( n2000:E563 ; System_BIOS Decompression started here
/ B5 N( w; |1 e$ d( g/ ]2000:E563   mov   bx, 1000h
% e8 \6 ]+ t6 x8 |0 ]2000:E566   mov   es, bx              ; es = src_seg
; g) q* g7 ?3 L- N% c. P2 H2000:E568   assume es:_1000h" a9 q2 S3 T, d& j
2000:E568   xor   bx, bx              ; bx = src_offset6 I2 |9 M7 F# F9 \
2000:E56A   call  Decompress          ; on ret, CF=1 if error occured
+ R" V* C0 D1 i6 y. j! Y+ @2000:E56D 72 13                     jb    short sysbios_decomp_error
& }9 }/ X- N" L% h5 m$ L  `! x6 f, }2000:E56F 66 F7 C1 00 00 FF FF      test  ecx, 0FFFF0000h     ; compressed component size more than 64KB?! W; U# l. U% V1 i
2000:E576 74 0A                     jz    short sysbios_decomp_error ; jmp if compressed component size <= 64KB. r2 b0 V* }8 f% A& ?
2000:E578 BB 00 20                  mov   bx, 2000h
) t0 d# x: n% e" s2000:E57B 8E C3                     mov   es, bx              ; proceed2next cmprssd componnt (in next segment)
- B) {: v* u; N2000:E57D                           assume es:_2000h# G" v0 |9 [- R
2000:E57D BB 01 00                  mov   bx, 1               ; bx = index to be added to previous src_offset in cx" I( y# F% [! x0 z+ K+ G& Y
2000:E580 EB 1B                     jmp   short repeat_decompress ; decompress remaining component (1st pass jmp taken)* d' s" e' x: f( Z" R6 S, w9 Z
2000:E582                         ; ---------------------------------------------------------------------------
) ~) x% f/ d7 O2000:E582                         sysbios_decomp_error:       ; CODE XREF: Decompress_System_BIOS+5B
' {: ]0 o& K0 \3 j$ I2000:E582                                                     ; Decompress_System_BIOS+64
% D9 h* y' V) ]: ~- j+ V0 v2000:E582 D0 D0                     rcl   al, 1
4 [# Q  N1 D. v, ]( ^2000:E584 BB 00 20                  mov   bx, 2000h& t" J1 {: a3 a
2000:E587 8E C3                     mov   es, bx
- V0 Y8 S- ?" x* j2000:E589 33 DB                     xor   bx, bx
& e7 Z# A# P( b3 C! \+ Y, J! ]2000:E58B E8 2B 00                  call  Decompress# ]8 E2 t: q5 E! c% {
2000:E58E D0 D0                     rcl   al, 1" f: J7 Z" |8 \. `  q' T6 \2 J
2000:E590 3C 03                     cmp   al, 3( e: S8 ~( X' L3 |
2000:E592 75 05                     jnz   short decompress_successfull
* G" c5 N, D; s' h# E" p, @6 L7 ^2 G2000:E594 B8 00 10                  mov   ax, 1000h
2 |, ?! I# v4 p% h2000:E597 F9                        stc  H$ Y7 ^" ~$ G+ m5 Y8 f
2000:E598 C3                        retn
. o6 s8 ^0 V) x' [2000:E599                         ; ---------------------------------------------------------------------------, h  K$ ~" I: w, f0 T
2000:E599                         decompress_successfull:     ; CODE XREF: Decompress_System_BIOS+804 i; I; A3 ^8 Z( B- z! C) @. U7 Z
2000:E599 0A C0                     or    al, al
6 c9 }6 t$ j; X5 i: s8 y/ o2000:E59B 75 10                     jnz   short sys_bios_dcomprss_done) P+ s( o9 t9 f( b$ T
2000:E59D                         repeat_decompress:          ; CODE XREF: Decompress_System_BIOS+6E
+ o& p/ a. g: Z/ t  n2000:E59D                                                     ; Decompress_System_BIOS+99+ |1 M1 x7 m( Q: d0 X
2000:E59D 03 D9                     add   bx, cx              ; bx = point to next compressed component
" z  h0 U' F  [7 B5 e2 s2000:E59F E8 17 00                  call  Decompress3 L, u7 G- a- }2 Z* X. N
2000:E5A2 72 09                     jb    short sys_bios_dcomprss_done ; 1st pass jmp taken
  O$ C- W2 ^8 d2000:E5A4 66 F7 C1 00 00 FF FF      test  ecx, 0FFFF0000h  c1 x6 U$ u8 \2 E" Z4 b' H
2000:E5AB 74 F0                     jz    short repeat_decompress
3 C7 m! l( P# X9 A7 \2000:E5AD                         sys_bios_dcomprss_done:     ; CODE XREF: Decompress_System_BIOS+89
" J6 f, t# C; i/ _2 R7 [, }( c2000:E5AD                                                     ; Decompress_System_BIOS+90
' S6 ~- N; t; F, n- ?- c+ R& f2000:E5AD E8 AB DA                  call  Decmprss_Sysbios_Extension+ }$ R' i5 u: s
2000:E5B0 0F 84 2D FE               jz    _sysbios_chksum_error
% D# o, b% W0 j, V( Y6 U; r" K2000:E5B4 B8 00 50                  mov   ax, 5000h           ; set success flag& d& y0 x( V/ u1 T9 G  Q
2000:E5B7 F8                        clc
$ X, u' d- {0 ^' K  `! W8 j2000:E5B8 C3                        retn; `5 Y& J1 y( v$ J
2000:E5B8 Decompress_System_BIOS endp
8 X% c3 i! b+ ~4 r) D8 O, o6 V________________________________________
0 j2 {5 v1 V( b4 Gb.  Decmprss_Sysbios_Extension 要保存段8000h或者9000h作为解压了的bios部分扩展的源段。这个是在RAM(seg 2000h)中的bootblock执行期间完成的,如下展示:
9 A- f( g1 P: ?; I________________________________________
9 H2 |8 Q2 i7 o9 E7 {2000:C05B                         -- Decmprss_Sysbios_Extension --0 j) w* q9 [# n& u5 Z+ C
2000:C05B                         in: es = src_seg9 _6 t2 a# U& ~! H* |( K
2000:C05B                             bx = src_offset5 i5 n/ h$ k- ?: w8 e
2000:C05B+ j7 @8 k. a# O/ y
2000:C05B                         out: ZF = 1 --> error occured  a  y4 N6 u: X' m: K6 b: Q
2000:C05B                              ZF = 0 --> execution succeeded
' M) e) v- y7 @' i$ f2000:C05B                         ; --------------- S U B R O U T I N E ---------------------------------------
) J' G' [8 o4 S) T: ]* U/ W+ _2000:C05B                         Decmprss_Sysbios_Extension proc near
% Z/ U1 W2 L2 W& G2000:C05B                                                     ; CODE XREF: Decompress_System_BIOS:sys_bios_dcomprss_done p
) P- W6 Z4 c: ^3 R9 k; k7 L9 z2000:C05B BB 00 80                  mov   bx, 8000h           ; es = seg_addr of C_seg n D_seg copy in RAM
$ o) f& ]2 a/ A) K2 \! Z. R9 l2000:C05B                                                     ; this seg_addr will be saved to RAM (0000:60XXh)
. ^( i0 G) G2 u+ B' K3 T" Y2000:C05B                                                     ; for extension component other than awdext.rom/awdeyt.rom: ?; j$ D0 v3 R+ A2 e; p
2000:C05E 8E C3                     mov   es, bx+ Z, r; Z$ ]1 m" _
2000:C060                           assume es:nothing
7 S: Q. b, U" @+ m2000:C060 33 DB                     xor   bx, bx              ; reset src_offset_addr9 F, t2 P  @' S6 W( ~+ w2 F
2000:C062 66 33 C9                  xor   ecx, ecx            ; reset compressed src size2 x+ G' j& b. A0 q0 y  M
2000:C065 51                        push  cx8 o/ ^/ t3 b/ |4 N5 J6 E
2000:C066                         repeat_decomprss:           ; CODE XREF: Decmprss_Sysbios_Extension+30 j1 e7 E$ w3 \0 a) ^* `
2000:C066 03 D9                     add   bx, cx6 Q4 `; d7 A1 Z* a2 }! t
2000:C068 72 09                     jb    short move_to_next_seg
+ P; ^$ o  Y$ s2 `( S8 x2000:C06A 66 F7 C1 00 00 FF FF      test  ecx, 0FFFF0000h     ; is size more than 64KB?
4 J7 |# G6 G7 R6 m( h, q. o9 W2000:C071 74 0A                     jz    short size_less_than_64KB
3 q; S4 Q7 s6 `+ l2000:C073                         move_to_next_seg:           ; CODE XREF: Decmprss_Sysbios_Extension+D j0 l) M# b! d( Q( [" o8 H
2000:C073 8C C1                     mov   cx, es
$ i- g7 R  k( z% E/ A" L& ^2000:C075 81 C1 00 10               add   cx, 1000h
- j# s- e: q, L0 o3 H$ k2000:C079 8E C1                     mov   es, cx
9 O' {7 `& u0 K, R5 _* z2 Y' Z+ e- |2000:C07B                           assume es:nothing% _4 d$ p2 X2 r1 `! e, i
2000:C07B EB 1A                     jmp   short reset_byte_counter* F4 e8 d7 Y. s% E7 D9 v! s
2000:C07D                         ; ---------------------------------------------------------------------------
# F) _: @2 e' z1 }  ~5 z4 j8 {2000:C07D                         size_less_than_64KB:        ; CODE XREF: Decmprss_Sysbios_Extension+16 j: n) |& Q( K6 ?" f0 c
2000:C07D 26 80 7F 12 41            cmp   byte ptr es:[bx+12h], 41h ; 'A' ; is awardext.rom?0 g* N3 G) E  t- g4 ?: f# `
2000:C082 75 04                     jnz   short not_awdext& X' v( D" m& ~9 G) s. ]
2000:C084 58                        pop   ax
3 _" m, p2 ?* F1 h8 n3 i/ B2000:C085 0C 01                     or    al, 1
. R3 n2 W' D" I- D' Q2000:C087 50                        push  ax- P. \" a; l7 m6 ]
2000:C088                         not_awdext:                 ; CODE XREF: Decmprss_Sysbios_Extension+27 j
1 K9 e! G5 `( {6 k( Y' F) Z2000:C088 E8 2E 25                  call  Decompress
! y2 s  D) I; m# q/ }2000:C08B 73 D9                     jnb   short repeat_decomprss
9 H5 P# P: f4 s2000:C08D 8C C3                     mov   bx, es
/ H4 {+ \" A- @, f( W2000:C08F 81 C3 00 10               add   bx, 1000h
) n' ]% a! q4 m$ q+ g# [2000:C093 8E C3                     mov   es, bx6 `% u$ E3 O, s9 N
2000:C095                           assume es:nothing4 h* C2 T# L8 h* j( k6 S* P
2000:C095 33 DB                     xor   bx, bx
/ s$ w( p+ {, }' P5 r2000:C097                         reset_byte_counter:         ; CODE XREF: Decmprss_Sysbios_Extension+20 j) u" Q( c, Z3 v  ^5 H
2000:C097 33 C9                     xor   cx, cx7 I3 v( D% k3 y& s4 w
2000:C099                         repeat_dcomprss2:           ; CODE XREF: Decmprss_Sysbios_Extension+4E j
; V' A  B4 N5 D' H  G6 o5 F6 U+ a2000:C099 03 D9                     add   bx, cx  F& n9 J" R; x5 ]
2000:C09B 26 80 7F 12 41            cmp   byte ptr es:[bx+12h], 41h ; 'A'
$ n& C: w. A4 b6 c# q2000:C0A0 75 04                     jnz   short not_awdext2
2 I0 i' s, @5 b: k/ t2000:C0A2 58                        pop   ax
0 v' ]1 R- K5 f3 G9 y6 p: b8 [* C2000:C0A3 0C 01                     or    al, 1               ; set successful flag0 W3 R5 R, x( u' J. K1 o; F
2000:C0A5 50                        push  ax8 M7 P8 v: [( B" B( {, Q
2000:C0A6                         not_awdext2:                ; CODE XREF: Decmprss_Sysbios_Extension+45 j& r' x+ O2 D1 O6 L
2000:C0A6 E8 10 25                  call  Decompress
0 k+ v( d- m  q2000:C0A9 73 EE                     jnb   short repeat_dcomprss23 ^+ i! K, G* A
2000:C0AB 58                        pop   ax) }( F& R8 C* T8 i0 |% ~6 H3 F
2000:C0AC 0A C0                     or    al, al              ; al=0 indicate an error occured: q: d4 q! r6 C* u; V
2000:C0AC                                                     ; (awdext_rom doesn't exist)1 j# P1 d( o# A$ p7 }1 h8 J
2000:C0AE C3                        retn
) T3 W7 x, m0 h8 n/ b. J- h, s( U2000:C0AE                         Decmprss_Sysbios_Extension endp' G0 ?- E& @# ?8 Z0 m- x
________________________________________
, c1 U$ V  P0 Y/ y8 b& zc.  Decompression_Ngine 例程被解压缩例程在RAM(在seg 2000h)中的bootblock改变头部时调用,它按需要改变头部,保存结果到RAM中重新定义区域,如下:9 }+ a: [$ V; z! K4 B0 |" U
________________________________________0 g+ \0 r0 ~0 G9 y( q
2000:7789 --- Decomprssion_Ngine ---
- O- C4 d7 H9 B6 \2000:7789 in: dx = scratch-pad_segment_for_decompression
( I4 m! l) a+ @2 K2 A* h2000:7789      es = (compressed_segment_addr>>0xC) [hi_word of src phy addr]
% [! D5 j$ k9 e$ q6 n2000:7789      bx = compressed_offset_addr/ k; X- E) f. J4 m
2000:7789
6 p$ y6 H/ ]  x/ Y1 j2000:7789 out: ecx = overall_compressed_component_length
; v# y7 H) k  k4 w/ B8 v2000:7789       edx = original_file_size( w# @8 v& ?3 X8 u, \  ^
2000:7789 ; --------------- S U B R O U T I N E ---------------------------------------
0 L+ E, x; O0 v2000:7789 Decompression_Ngine proc near
2 y0 e7 ~4 K; `.........! V/ |! {) q$ V
2000:77FF   push  gs9 y2 G5 W4 b2 ?8 ^6 z$ m0 n
2000:7801   mov   di, 0
( P" w& }4 o& e4 T& W2000:7804   mov   gs, di! Y6 r8 @& g: b0 M# d
2000:7806   assume gs:nothing
: D# T) C2 q& {/ q  d2000:7806   mov   di, 6000h
0 J3 r( _4 j9 d1 |( o! l2000:7809   mov   word ptr gs:[di], 7789h    ; save Decompression_Ngine offset ' a9 b+ r: K1 B
2000:780E
; B- U* H( a, D* Q) Z- R( Y5 _2000:780E ;check LZH header
5 G$ ~( M4 V7 X5 K0 {2 f; e2 R2000:780E   add   bx, 12h             ; LZH-header decomp_seg_addr_hi_byte index
) f/ O; b7 r/ @2000:7811   call  Fetch_Byte
: e' b' J; x1 x0 f9 t  q2000:7814   sub   bx, 12h             ; restore bx to point to first byte
! J0 J0 A. I8 l0 t2000:7817   cmp   al, 40h ; '@'       ; is extension component?
" Y% @' s$ Y3 a2000:7817                             ; at 1st: al equ 50h (original.tmp)# x& L$ }% T; u, V, k6 P
2000:7817                             ; at 2nd: al equ 41h (awardext.rom); M  R. B$ u  c6 f0 `' u4 `
2000:7819   jnz   short not_extension_component ; 1st-pass jmp taken
  E7 l; `% r$ J9 F! `2000:781B   add   bx, 11h6 T" }0 b: o( H6 ^/ Z2 v9 m2 M8 C
2000:781E   call  Fetch_Byte          ; fetch "dest_seg_addr" lo_byte3 a' t1 J7 Y/ f/ [5 v, B! @
2000:7821   sub   bx, 11h             ; restore bx to point to first byte9 k# A2 W  W8 F. w- G7 w, _
2000:7824   or    al, al              ; if extension component, jmp taken
( Z; M1 M7 k; g) {- I$ C- T2000:7826   jnz   short extension_component
" _, c& m1 W, s7 P' z5 ~: A$ Q2000:7828   cmp   dword ptr gs:[di+4], 0 ; cmp dword [0000:6004]:0! U* |( Z+ n- i
2000:7828                         ; 1st pass from original.tmp, [0000:6004]=FFFFh
3 z5 L' q8 n5 W4 @% y4 M0 o2000:7828                         ; (programmed by POST_8S in original.tmp prior to calling this engine)6 T% M! p+ Y7 w2 N! b9 t6 H
2000:782E   jnz   short not_extension_component / k  O; v9 H# s8 `
2000:7830 extension_component:        ; CODE XREF: Decompression_Ngine+9D" b( a0 ^* q' [+ d7 O/ ]
2000:7830   movzx dx, al              ; dl = "dest_seg_addr" lo_byte- R" I% ]3 \  \
2000:7833   inc   bx                  ; bx = LZH_hdr_chksum byte index: |: a  A! ]6 T& ^7 G1 x
2000:7834   call  Fetch_Byte( _9 a0 ?2 K2 x0 k. C
2000:7837   sub   al, dl              ; LZH_hdr_chksum = LZH_hdr_chksum - "dest_seg_addr"_lo_byte
5 q* J! p% |- `( x2000:7839   call  Patch_Byte          ; store new checksum
* T' E- s% x. z6 c8 p/ C, G6 X2000:783C   dec   bx                  ; restore bx
4 T1 U( y' Y+ X( e$ g2000:783D   xor   al, al              ; al = 00h
( _6 v" p* A7 L* E3 P$ Y2000:783F   add   bx, 11h             ; bx = "dest_seg_addr"_lo_byte index( r# g0 i1 N/ w7 K& R0 H
2000:7842   call  Patch_Byte          ; patch "dest_seg_addr"_lo_byte to 00h4 [. ]0 m& o  G0 q. M
2000:7845   sub   bx, 11h
6 {/ V: k; t/ p7 }2000:7848   inc   dx                  ; dx = "dest_seg_addr"_lo_byte + 16 U& |- [& C" V; `
2000:7849   shl   dx, 2               ; dx = 4*("dest_seg_addr"_lo_byte + 1)
! b% x8 N. \, [% i2000:784C   add   di, dx              ; di = 6000h + dx  -- look above!; e2 r+ u8 D' \, |7 ~& \' h" \4 p/ C9 u
2000:784E   mov   gs:[di], bx         ; 0000:[di] = compressed_offset_addr
% b- ~0 A2 H4 S5 o2000:7851   mov   cx, es
1 F" ?- U# K/ _& d2000:7853   mov   gs:[di+2], cx       ; 0000:[di+2] = compressed_seg_addr>>0xC (hi_word of src phy addr)3 }0 u; d0 ^  b( P  k
2000:7857   call  Fetch_Byte          ; al = LZH_hdr_len4 X- I' U6 }( T8 F$ L9 h
2000:785A   movzx ecx, al             ; ecx = LZH_hdr_len
4 A0 L. D2 @  k: x9 a+ L; W2000:785E   add   bx, 7' _/ o) S( P9 r% B
2000:7861   call  Fetch_Dword         ; eax = compressed_file_size
5 T1 W) G: P+ K# p% w7 h2000:7864   sub   bx, 7
6 F9 s/ _) j) r' F2000:7867   add   ecx, eax            ; ecx = LZH_header_len + compressed_file_size% y6 N  ~6 `; ?/ a
2000:786A   add   ecx, 3              ; ecx = total_compressed_component_size& k, s" `6 D# t7 }' J0 G. w
2000:786E   pop   gs4 ^3 @0 ]) T6 B
2000:7870   assume gs:nothing6 j" @: H, r/ {% p5 ]. u
2000:7870   jmp   exit
" E! {/ V& i* i% M0 P' O2000:7873 ; ---------------------------------------------------------------------------7 N3 N: b5 A& ?6 ~( t
2000:7873 not_extension_component:    ; CODE XREF: Decompression_Ngine+90" c' m1 }5 f; X1 q! C
2000:7873                             ; Decompression_Ngine+A5
6 n# q  N+ V/ L, [6 S  B2000:7873   pop   gs, n4 i4 M$ \$ d1 b% Y$ Q
2000:7875   call  Make_CRC16_Table1 d% ~3 K, X% X# Y' r
2000:7878   call  Read_Header         ; fetch header component to scratchpad_seg, on error CF=1
+ X% V( C- B! Y0 B# {9 V* f2000:787B   jb    exit                ; ret with error code set
  K. l) c% r; J6 _9 e- ~' z% p2000:787F   mov   ax, ds:108h         ; mov   ax, decomprss_seg_addr3 k1 ^% Y9 j% v3 r: j9 |3 \
2000:7882   mov   ds:104h, ax         ; mov   nu_decomprss_seg_addr, ax
( @: n: G, x$ H* x3 S2000:7885   mov   ax, ds:10Ah         ; mov   ax, decomprss_offst_addr
( D& }7 x6 E, l2000:7888   mov   ds:106h, ax         ; mov   nu_decomprss_offst_addr, ax
$ p5 S; G; a% h5 ^+ }2000:788B   mov   ecx, ds:310h        ; ecx = compressed_component_size; `7 s5 Z* H: N3 f% |! R+ j4 x, K
2000:7890   xor   eax, eax4 C* w$ y' A0 Q5 w. x1 z' m
2000:7893   mov   al, ds:571Ch        ; al = LZH_hdr_len
2 o5 l) {$ Z& E/ M1 w8 b2000:7896   add   ecx, eax            ; ecx = compressed_cmpnnt_size + LZH_hdr_len
" g7 n2 B1 Z# v: S2000:7899   add   ecx, 3              ; ecx = compressed_cmpnnt_size + LZH_hdr_len +& m& P$ Q" _. z6 S" q
2000:7899                             ;       sizeof(EOF_byte) + sizeof(LZH_hdr_len_byte) +7 G) k4 G* T3 }! G
2000:7899                             ;       sizeof(LZH_hdr_8bit_chk_sum)7 l! I5 z6 y* d- u0 `3 g
2000:7899                             ; i.e. ecx = overall_component_len
. q1 ~0 k% U4 T# F# B0 Q$ e+ R% y2000:789D   mov   edx, ds:314h        ; mov   edx, original_file_size
) Q" r( k1 Z  f2000:78A2   push  edx
; z9 `# d& s! d- ~6 ?2 V3 `: B2000:78A4   push  ecx; _' E5 \/ ]0 A7 h! I
2000:78A6   push  bx
, I: k; f  }* Y1 L4 @; x, t- o  ~2000:78A7   add   bx, 5               ; point to LZH ID byte
* h9 A' E$ R" ]/ t; J2000:78AA   call  Fetch_Byte& S+ X; G2 i( f1 N; r! y/ s7 K
2000:78AD   pop   bx$ U7 d- i; D0 T" q
2000:78AE   cmp   al, '0'             ; is '-lh0-'?6 U4 ^& H# s( W3 W6 E# P( }
2000:78B0   jnz   short decompress_part
0 \1 A' m1 v9 w1 C  v2 R3 h2000:78B2   push  ds: C2 E! I8 @+ O0 q6 E; w# o% j
2000:78B3   push  si
1 ~  K$ x6 h5 g" c/ p2000:78B4   push  bx  Z7 _( I" g7 o3 v6 ~
2000:78B5   mov   di, ds:10Ah
% w( T8 |) I$ B/ O' q2000:78B9   movzx ax, byte ptr ds:571Ch
1 S9 V0 s9 D3 p2 h! g' N) o0 \2000:78BE   add   ax, 2" M/ }! P7 K4 E3 N0 E( y$ y
2000:78C1   add   bx, ax4 l9 l& z- }. M/ C
2000:78C3   mov   cx, ds:310h
: }( W# g; r  m2000:78C7   mov   ax, ds:108h- u* l8 `  F1 b- @( B, w/ E0 g
2000:78CA   mov   es, ax
, n# U: N% |+ I% f% t# f2000:78CC   add   cx, 3! y& p1 Z8 L3 n$ c7 B$ b/ ~- S
2000:78CF   shr   cx, 2& u1 u7 y- x2 F  Y
2000:78D2 next_dword:                 ; CODE XREF: Decompression_Ngine+151 j' z9 f; K5 B( D% x( w* @: V( Y
2000:78D2   call  Fetch_Dword
2 W' K4 j8 _. H; O: i$ [5 q2000:78D5   add   bx, 4
+ m% |% i+ g- J- v2 Q2000:78D8   stosd2 Z: r2 }8 F  s' f
2000:78DA   loop  next_dword+ u8 s$ u1 u4 }* }8 q! l
2000:78DC   pop   bx
) s$ c6 c' D+ m2000:78DD   pop   si& b1 o  b% n5 v
2000:78DE   pop   ds
8 ]$ z6 T( ]4 |, W& b! W/ I1 e2000:78DF   jmp   short LZH_hdr_OK
( f# j4 v" z9 q3 v, |/ q  o2000:78E1 ; ---------------------------------------------------------------------------5 r( ]/ T8 o5 |) |4 @5 m
2000:78E1 decompress_part:            ; CODE XREF: Decompression_Ngine+1277 E4 D" L0 p4 M5 E+ C& U, r
2000:78E1   push  word ptr ds:104h    ; save destination seg addr
% T/ G/ q% j9 r8 m+ x9 ]2000:78E5   push  word ptr ds:106h    ; save destination offset addr/ H0 |" V  ?6 {8 {
2000:78E9   push  large [dword ptr ds:314h]
- i2 c4 g! h* h, m! ~2000:78EE   call  Lzh_Expand          ; Lzh_Expand capable of handling compressed3 F" m7 V2 g1 l% D
2000:78EE                             ; component bigger than 64KB (1 segment): X. ]* |& x7 {7 f; a0 N# N
2000:78F1   pop   dword ptr ds:314h! z( H$ h) O% T( ]/ j. |
2000:78F6   pop   word ptr ds:106h
, X: \$ D8 z" p! X. _2000:78FA   pop   word ptr ds:104h
/ s5 j, ^# z; ^- Q- v; y2000:78FE LZH_hdr_OK:                 ; CODE XREF: Decompression_Ngine+156
' s- f- i" z9 [- E% @2000:78FE   call  Zero_Init           ; zero init 32KB of scratchpad_seg
: t( C$ S3 N. M  h! n: I5 i4 M  b2000:7901   pop   ecx
& T+ R. S7 J4 Z- L% k# e2000:7903   pop   edx6 ^# N% `5 W8 ^5 m4 H2 Q; G1 R
2000:7905   clc5 g8 ~$ _9 `+ W( p! F: x! r
2000:7906 exit:                       ; CODE XREF: Decompression_Ngine+E7
/ u$ ?, Z5 ^( _3 k1 Q+ c1 X2000:7906                             ; Decompression_Ngine+F2' s, V. S% Y' [) l  ^
2000:7906   pop   es/ X+ `- H& L  j5 J; N
2000:7907   pop   bx
  `! ?( f. [" j9 }6 e$ M! t2000:7908   pop   eax
) g: `2 G) }# u# x5 _$ J' Y2000:790A   retn1 {0 {6 D: p( F" v. O
2000:790A Decompression_Ngine endp/ Y" O# _$ H- A( P1 J5 c
________________________________________4 S8 \( r' T* o  F' m' v' u: B
这个用红线标记的一行写入“signatures”到内存。比如,nnoprom.bin部分用id:4027h定义。这个例程中,nnoprom.bin的索引就要被保存。这个索引的计算方法如下(也是上面代码所看到的算法):$ g0 g3 h( K8 O8 s* J2 l
index = 4*(lo_byte(ID) + 1) 8 j( X& i+ G; [
这个所引用来计算地址来保存信息或者签名。再nnoprom.bin里,索引是A0h(从[4*(27h+1)])。所以,保存了信息的这个地址开始与60A0h。就像你上面看到的,第一个保存的信息是有压缩的“Extension_BIOS components”这个部分的偏移地址。它被保存在地址60A0h(for nnoprom.bin)。然后,临时“压缩/解压段地址”保存在60A2h(for nnoprom.bin)。对所有的“扩展bios部分”,这个临时的“压缩/解压段地址”经常是4000h,就像你上面看到的代码那样(这个临时的被解压段的值修改成了4000h,在被保存到RAM之前)。这个相同的进程就为其他的所有“扩展bios部分”执行完成了。
回复

使用道具 举报

 楼主| 发表于 2007-11-16 13:30:36 | 显示全部楼层
d.  下一步,original.tmp(post执行期间)中的POST_8S负责准备为解压缩必须的签名,如下面你所看到的:
1 J# H* n8 ]7 t4 G  v1 A4 w________________________________________; s0 B) P# }) z5 X8 O
E000:17B8                         POST_8S proc near- U# E7 H- D. t2 F" ?
.........+ O0 ^- Z  B% ]1 ]+ i, Y8 z
E000:183F BE 00 00                  mov   si, 0* Z# k6 r# K% O
E000:1842 8E DE                     mov   ds, si2 w, I4 b$ w0 ]- l' G
E000:1844                           assume ds:nothing  i; m# X1 O+ d
E000:1844 BE 00 70                  mov   si, 7000h
) f5 S/ M$ ~& P  s2 H) O! u7 jE000:1847 8B 44 04                  mov   ax, [si+4]          ; ax = FFFFh (0000:7004h filled before by Decompress_System_BIOS
$ d$ }4 ?1 r! i0 O1 ^1 ^E000:1847                                                     ; during bootblock_in_RAM execution)- [" g  }8 q  }
E000:184A BF 00 00                  mov   di, 0
+ Z' x  M! J- t" lE000:184D 8E C7                     mov   es, di
0 e8 J& D: w1 z5 N4 z  x# U/ x6 C! B2 SE000:184F                           assume es:nothing
. X: O  l$ Q* A8 B4 UE000:184F BF 00 60                  mov   di, 6000h
. i( h& S6 U! f3 u" kE000:1852 26 89 45 04               mov   es:[di+4], ax       ; [0000:6004] = FFFFh --> signature to do LZH decompression+ u( E8 f: e/ e6 X6 m( N: d
E000:1852                                                     ; for extension components6 k6 M8 N6 D* J& L9 R
E000:1856 3D FF FF                  cmp   ax, 0FFFFh
/ p4 j* v- d6 `' X9 d+ N9 J, H& LE000:1859 74 10                     jz    short signature_ok . B$ ]8 k0 w9 V; K: q! L0 {0 b
E000:185B 8B 04                     mov   ax, [si]
! S: N4 B& X; h% VE000:185D 26 89 45 04               mov   es:[di+4], ax2 N' q/ V5 V: t; d- \, ]4 u* ~* q% K
E000:1861 8B 44 02                  mov   ax, [si+2]
% L2 T5 s+ y7 H* p6 u7 i" Q5 _E000:1864 C1 E8 0C                  shr   ax, 0Ch: [7 Y/ o$ B( j6 v1 }
E000:1867 26 89 45 06               mov   es:[di+6], ax0 N# o+ t9 J/ |# l
E000:186B                         signature_ok:               ; CODE XREF: POST_8S+A1* U9 e  i( U. O2 v5 H- E5 [
E000:186B E8 A2 6C                  call  _init_Pwr_Mgmt_ctlr3 P* L$ u7 ^/ B! {3 o/ H! _: s
E000:186E F8                        clc
1 L% {  z4 f' ^4 N7 d+ ^E000:186F C3                        retn
4 z8 k9 _+ [' N9 G* C- \! \: wE000:186F                         POST_8S endp
. ?( I  C2 _) I3 [________________________________________
" l' h; n7 ~$ M( A) Z8 y9 ue.  下一步,例程init_nnoprom_rosupd(这只是一个例子,其他部分可能会不同)解压缩nnoprom.bin和rosupd.bin,如下面代码:
7 n; n1 l9 S9 _+ t/ K________________________________________
$ U9 M( A" r4 a: sE000:71C1                         init_nnoprom_rosupd proc near ; CODE XREF: POST_11S6 k5 U1 `, I7 l0 F/ [8 x
........." g  L. h* ?! z- d  s
E000:71CF BF A0 00                  mov   di, 0A0h ; 'a'      ; nnoprom.bin index
9 Y% x/ \* M* f, t& KE000:71CF                                                     ; nnoprom.bin-->4027h; A0h = 4h*(lo_byte(4027h)+1h)
; l3 @- @, A, i) [8 Q9 P) mE000:71D2 E8 74 FC                  call  near ptr decompress_BIOS_component ; decompress NNOPROM.BIN
- p5 r3 ^* v1 i* h) a* ]E000:71D5 0F 82 ED 00               jb    decompression_error/ h- T- S1 U, V2 o* k
E000:71D9 68 00 40                  push  4000h  C- y; e* u' X8 F3 r
E000:71DC 1F                        pop   ds                  ; ds = 4000h; decompression result seg" ?) h& q2 [* s
E000:71DD                           assume ds:nothing
# h. n" c9 G$ u5 T1 O; Z# ]: uE000:71DD 33 F6                     xor   si, si) o  c! x4 o8 P9 e% F
E000:71DF 68 00 70                  push  7000h
) g- ~; y  F  z5 l) l' Z6 L: OE000:71E2 07                        pop   es                  ; es = 7000h
* N0 ?0 F" I+ e! q+ l9 b& @* aE000:71E3                           assume es:nothing5 {/ \; _7 h/ [4 u6 o' j. T
E000:71E3 33 FF                     xor   di, di
7 ]2 l. m$ b* i& N+ yE000:71E5 B9 00 40                  mov   cx, 4000h
2 W# ]; N1 h) q% j/ N0 X' TE000:71E8 FC                        cld1 V* @  }2 h, p1 c9 m( ~) M" A
E000:71E9 F3 66 A5                  rep movsd                 ; copy nnoprom decompression result from
: s* I5 D' Q9 e' l! S8 ~% fE000:71E9                                                     ; seg 4000h to seg 7000h
# ~) V+ O( ?* g( g" ~5 R3 ~E000:71EC BF 03 00                  mov   di, 3
" Q! I5 S9 j& q3 `% CE000:71EF 66 26 81 3D 24 4E 4E 4F   cmp   dword ptr es:[di], 'ONN$' ; match (decompressed) nnoprom.bin signature  p. o; w+ v  I1 m# h
E000:71F7 0F 85 CB 00               jnz   decompression_error3 x' b' F; M# ]8 f2 i5 _1 c. @
E000:71FB 68 F8 9F                  push  9FF8h/ P! ]7 O# n+ C# V- Y+ E. L
E000:71FE 07                        pop   es                  ; es = 9FF8h
1 G9 p, S) J2 J% e& Z" H: t4 vE000:71FF                           assume es:nothing
: }5 o6 p' N' F; F. b, r' LE000:71FF 33 FF                     xor   di, di0 W5 x: N' }* s; u& n
E000:7201 B9 68 00                  mov   cx, 68h ; 'h'6 M. C1 I6 M' _3 H5 D+ h# M. [
E000:7204 32 C0                     xor   al, al$ l) t8 R5 O  t/ b. ?" P
E000:7206 F3 AA                     rep stosb
9 O1 k* ?  a, cE000:7208 BF A4 00                  mov   di, 0A4h ; 'a'      ; ROSUPD.bin index
3 N% I( K$ `4 mE000:720B E8 3B FC                  call  near ptr decompress_BIOS_component ; decompress ROSUPD.bin
* g" G2 R5 H+ B' bE000:720E 0F 82 B4 00               jb    decompression_error% k# M) l$ C+ j5 Q! }8 [1 c: r. Z
E000:7212 1E                        push  ds1 @) F4 C' |1 L4 y. ?* N& Y
E000:7213 06                        push  es
$ ]- k# {' H; x% q6 X- TE000:7214 0F A0                     push  fs) F* x- \1 t8 Y5 s
E000:7216 0F A8                     push  gs
: _- [6 ]! \0 iE000:7218 9A DD 5F 00 F0            call  ds_es_fs_gs_flat_4GB. X8 P  W) L) t" s4 ^4 N
E000:721D 66 33 F6                  xor   esi, esi
5 ]: A8 @9 I& i& t0 BE000:7220 8E DE                     mov   ds, si
* }. ~. J3 M( BE000:7222                           assume ds:nothing9 c& m& V1 j, |7 _* Q/ ~
E000:7222 8E C6                     mov   es, si
6 n) ~- L, A( [E000:7224                           assume es:nothing
7 K: J% E. F% I* G1 M5 gE000:7224 68 00 40                  push  4000h
  P2 p6 Y8 O9 s) W; n/ @% @! DE000:7227 5E                        pop   si
2 o0 R9 U9 E, P' jE000:7228 66 C1 E6 04               shl   esi, 4              ; esi = 4_0000h (decompressed ROSUPD.bin)
- R/ f' y2 T- w( }% A' iE000:722C 66 BF 00 00 10 00         mov   edi, 100000h
% A% E! w) m) o; T  _0 h$ wE000:7232 66 8B CB                  mov   ecx, ebx
+ ?! E8 O8 W# ^; _: b8 K1 o0 UE000:7235 66 C1 E9 02               shr   ecx, 2. |& Z0 e: \" }& y( g
E000:7239 FC                        cld
2 s  M7 i$ [; B& e+ r& b  XE000:723A F3 67 66 26 A5            rep movs dword ptr es:[edi], dword ptr es:[esi] ; copy decmprssd ROSUPD.BIN to 1MB1 t! i" o8 E5 U# ~" K
E000:723F 0F A9                     pop   gs
7 O! J1 h" h5 C  ~1 `$ kE000:7241 0F A1                     pop   fs1 P# {4 d: ]+ J# T7 l* k
E000:7243 07                        pop   es2 C% [! @) C2 C+ f$ F5 G
E000:7244                           assume es:nothing+ `5 R! c0 `/ K
E000:7244 1F                        pop   ds) ~! ]; E$ k- B( I' i2 @
E000:7245                           assume ds:nothing
/ i  @% u: k( I  V7 n  aE000:7245 68 F8 9F                  push  9FF8h
+ w% Q" K, A8 q+ L' ?% {( m7 wE000:7248 07                        pop   es5 |3 }7 D  o$ H9 U. i2 f
E000:7249                           assume es:nothing; }) n1 Y$ U. K" n; C4 ^9 m
E000:7249 66 26 C7 06 00 00 00 00+  mov   dword ptr es:0, 100000h
" K) r9 D: m1 c4 q2 ]  hE000:7253 66 26 C7 06 04 00 00 00+  mov   dword ptr es:4, 40000h+ ?' J( ]9 x: w4 x3 R3 a/ V1 X
E000:725D 66 33 C0                  xor   eax, eax
4 X+ Z' ^$ O/ a/ w$ z5 n% @E000:7260 B8 00 E0                  mov   ax, 0E000h2 ^  H$ l1 |- H* J' C- W
E000:7263 66 C1 E0 04               shl   eax, 4! S0 _7 A" }# ^% Q- {  w
E000:7267 66 05 56 71 00 00         add   eax, 7156h
9 t) T* O" A/ L! y: eE000:726D 66 26 A3 08 00            mov   es:8, eax2 M( p$ A2 R0 t: [9 p: i
E000:7272 B8 07 00                  mov   ax, 70 R. m" P  R( B. m8 _8 L
E000:7275 26 A3 0C 00               mov   es:0Ch, ax/ {6 z, S1 F" F3 Q( U8 B
E000:7279 B8 00 70                  mov   ax, 7000h( |# o, s4 }  Q+ T8 s2 m! b
E000:727C 26 A3 0E 00               mov   es:0Eh, ax
7 O2 r; M( i* G) Z% J& W# j3 eE000:7280 66 33 C0                  xor   eax, eax: T5 G& ~; V* x$ f9 z$ j5 N
E000:7283 B8 00 E0                  mov   ax, 0E000h
) n# _/ I8 X6 W: g7 e. U% rE000:7286 66 C1 E0 04               shl   eax, 4
  R! A9 b- b- q  b% I) xE000:728A 66 05 AA 71 00 00         add   eax, 71AAh
& `  h6 ~. k- L% o; {, b. {8 x6 H$ aE000:7290 66 26 A3 10 00            mov   es:10h, eax
3 X1 ]& s% T! m8 i2 x5 |1 g4 F5 y6 _E000:7295 66 BE 80 FF 09 00         mov   esi, 9FF80h' V1 Q0 K5 ?7 g
E000:729B 66 81 C6 00 00 00 00      add   esi, 0
: k$ V1 S$ W. pE000:72A2 B0 36                     mov   al, 36h ; '6'
: F2 c4 T) O7 @7 eE000:72A4 0E                        push  cs
6 Q3 f/ j. s8 ]# v! a. J6 |9 ~E000:72A5 68 B0 72                  push  72B0h
) Q1 x; H+ k& S+ S1 w, I! cE000:72A8 68 FD E4                  push  0E4FDh              ; read CMOS byte
4 A& s* M; s- O1 M: O- I8 fE000:72AB EA 88 61 00 E0            jmp   far ptr Fseg_vector
1 V4 m4 V. x  h" z) |  m& NE000:72B0                         ; ---------------------------------------------------------------------------
: j7 O9 \7 d6 ^E000:72B0 8A D8                     mov   bl, al* c- ^" ?" w+ I0 v7 X) d
E000:72B2 B8 00 00                  mov   ax, 0
& x7 `9 P% {9 f2 r$ |E000:72B5 E8 41 FE                  call  near ptr call_nnoprom_at_7000h ; execute decompressed nnoprom.bin
  P) l% y+ @3 R. \E000:72B8 9C                        pushf
$ Y  K& t. Q" L* `! sE000:72B9 9D                        popf
! I1 F, |, I% v+ E* vE000:72BA 72 0A                     jb    short decompression_error
. S8 u! W; O1 D$ `: EE000:72BC B8 00 00                  mov   ax, 0' P7 k. ^9 Y7 C8 }, q7 v* P
E000:72BF 8E D8                     mov   ds, ax
8 u% g8 L0 x$ J$ ~; W( g4 BE000:72C1                           assume ds:nothing
6 Z4 \3 W7 y) W; I7 ]* _, X6 _E000:72C1 80 0E B7 04 03            or    ds:byte_0_4B7, 3' M: z" p9 P# z  C  @) T9 O& V
E000:72C6                         decompression_error:        ; CODE XREF: init_nnoprom_rosupd+14- [3 r+ L' }3 {- z6 o/ L7 ^0 P+ U
E000:72C6                                                     ; init_nnoprom_rosupd+36 ...5 N' F; m( x" ~# z! m+ n( D6 s
E000:72C6 66 61                     popad2 B2 ^! x6 N) p, \5 t  s
E000:72C8 07                        pop   es+ B  J8 ~; f. S
E000:72C9                           assume es:nothing
0 t8 {" Z; x. A% `* Y8 rE000:72C9 1F                        pop   ds
4 p% z& w8 C) ?9 h" G& E- KE000:72CA                           assume ds:nothing" n7 b) l/ o1 j  t/ s6 K+ X0 T8 A. Z
E000:72CA C3                        retn' z% H+ D* T6 |. O! B  V
E000:72CA                         init_nnoprom_rosupd endp ; sp =  2- L! u5 I: F- J. u3 l
________________________________________0 p, @% T; m* U8 N8 R& |- G
E000:6E49                         -- decompress_BIOS_component --
. D9 p" b, V; ?* t* \" j3 K' K$ IE000:6E49                         in: di = index to compressed component (as written at 0000:6XXXh)" Y, ]: J% S5 `1 [2 p6 M- j) [
E000:6E49                         ; --------------- S U B R O U T I N E ---------------------------------------
, L+ [' X+ H6 BE000:6E49                         decompress_BIOS_component proc far
' V- q) D8 H5 [8 \E000:6E49                                                     ; CODE XREF: EPA_Procedure+43
8 h7 N$ ~& Y8 e. s) xE000:6E49                                                     ; EPA_Procedure+5E ...
+ `+ E# g8 x. R. n( KE000:6E49 1E                        push  ds# J- @8 U8 R9 d6 C) J
E000:6E4A 06                        push  es+ f; ?, I& h2 v* m9 U! f% L
E000:6E4B 55                        push  bp
& z: O$ \: p7 z# z, ~E000:6E4C 57                        push  di  n" J$ l& {4 [( l0 Q# e( o1 E) H
E000:6E4D 56                        push  si
" i$ l5 |  E! f6 V: T. ]( }E000:6E4E 81 E7 FF 3F               and   di, 3FFFh           ; clear di's MSB9 R/ d5 m( n' R+ z4 K
E000:6E52 FA                        cli6 v8 Z7 k" e. y* E# E
E000:6E53 B0 FF                     mov   al, 0FFh            ; enable cache0 W4 L6 g- R3 P3 ?5 \
E000:6E55 E8 14 FE                  call  F0_init_cpu_cache
* H, p( A  |6 K0 _  \E000:6E58 68 00 E0                  push  0E000h
7 t+ ]# w* D- }; }E000:6E5B 68 69 6E                  push  6E69h, c* l) \# y# j# F9 K5 ]5 N
E000:6E5E 68 31 EC                  push  0EC31h
* `0 ~1 s  [; }E000:6E61 68 D4 E3                  push  0E3D4h              ; mod_A20_access_mode5 U7 c2 P, m6 m. Q# f7 Z6 S3 K
E000:6E64 EA 30 EC 00 F0            jmp   far ptr F000_Vector
4 ^* |1 F! Z/ fE000:6E69                         ; ---------------------------------------------------------------------------
$ l8 J5 ?$ r$ N  U. t4 |$ KE000:6E69 E8 2F 7D                  call  ds_ss_Enter_Voodoo_Mode$ |# }* d5 q- f
E000:6E6C 8C D8                     mov   ax, ds0 Q# f- c1 D/ \
E000:6E6E 8E C0                     mov   es, ax              ; es = voodoo mode, base at 0000_0000h
5 t0 m' w  ~# j. z- QE000:6E70                           assume es:nothing
/ p% Q+ \. u8 \E000:6E70 E8 45 7D                  call  ss_Leave_Voodoo_mode
! H2 p+ z. [5 J" M' hE000:6E73 5A                        pop   dx                  ; dx = si
' r: i& a9 a" RE000:6E74 58                        pop   ax                  ; ax = di --> compressed component index
: o# J2 A# h7 b) r4 d4 yE000:6E75 26 66 8B 9D 00 60         mov   ebx, es:[di+6000h]  ; ebx = compressed component physical addr ((seg>>0xC)+offset)% E5 S5 b; e' Y7 P
E000:6E7B 66 0B DB                  or    ebx, ebx            ; is compressd component exist?4 U. p* H1 D! {+ @; e) c5 X; }
E000:6E7E 0F 84 2E 01               jz    no_cmprssd_component
8 [& g; ^; v7 {( z* E7 Z8 c  C8 s5 }E000:6E82 83 FB FF                  cmp   bx, 0FFFFh9 T# @( ^* F9 u
E000:6E85 0F 84 27 01               jz    no_cmprssd_component
7 {9 X* {$ Z* q& A( c6 N1 P! yE000:6E89 F6 C4 40                  test  ah, 40h
, P. o9 w, z* ^( FE000:6E8C 74 04                     jz    short exec_decompress ; for nnoprom.bin, jmp taken$ d6 S8 |- p0 L& V; s
E000:6E8E F8                        clc, ~  i2 B* L5 r$ [. I- X
E000:6E8F E9 1F 01                  jmp   decomprss_BIOS_componnt_ret
, Y$ a# L2 N9 k0 F2 TE000:6E92                         ; ---------------------------------------------------------------------------+ D' H- e+ J3 h7 e. t
E000:6E92                         exec_decompress:            ; CODE XREF: decompress_BIOS_component+43; h2 Q& d6 b$ Z6 {  h9 c
E000:6E92 26 8B 3E 00 60            mov   di, es:6000h        ; di = Decompression_Ngine offset addr/ ^8 n4 K+ {( Q* s
E000:6E97 67 66 8B 35 00 00 16 00   mov   esi, ds:160000h     ; mov esi,[awardext.rom 4Byte hdr]. \# s3 i/ p0 k$ H+ P' i
E000:6E9F 66 F7 D6                  not   esi
1 T9 d2 S( O5 J. B3 LE000:6EA2 67 66 89 35 00 00 08 00   mov   ds:80000h, esi      ; modify ds:80000h value; restored below
8 r6 g" f& \& ]E000:6EAA 66 81 FB 00 00 10 00      cmp   ebx, 100000h        ; compressed_component_phy_addr > 1MB ?
, g. D, t# b0 \5 J6 S) BE000:6EB1 72 57                     jb    short above_1MB     ; for nnoprom.bin, jmp _not_ taken4 D! T% V6 V% p5 C' ], x
E000:6EB3 57                        push  di                  ; save Decompression_Ngine offset
  M& H2 b% J% Y2 H& P+ TE000:6EB4 66 BE 00 00 09 00         mov   esi, 90000h5 i0 @: w  F* V6 c- C0 ^  L
E000:6EBA 66 BF 00 00 14 00         mov   edi, 140000h
4 ?  h% u  w. d1 V9 i' sE000:6EC0 66 B9 00 40 00 00         mov   ecx, 4000h          ; copy one segment8 e8 O; Z. V  C* e
E000:6EC6 FC                        cld
% K. o$ k: [8 ^& IE000:6EC7 67 F3 66 A5               rep movs dword ptr es:[edi], dword ptr [esi]4 X  L8 H, Z% q
E000:6ECB 66 BE 00 00 16 00         mov   esi, 160000h
: U) Z6 g( f& h, w  J; YE000:6ED1 66 BF 00 00 08 00         mov   edi, 80000h
+ p& c2 k; |; |E000:6ED7 66 B9 00 80 00 00         mov   ecx, 8000h          ; 2 segment (128KB)7 _- r& w, Z, H* k( d
E000:6EDD FC                        cld+ }0 d  n8 h* G) x1 y3 D! K6 T- x
E000:6EDE 67 F3 66 A5               rep movs dword ptr es:[edi], dword ptr [esi] ; copy 2 segment (128KB) from 16_0000h to 8_0000h9 j/ }8 D% u& U0 q( L$ g
E000:6EDE                                                     ; for decompression purposes9 j- g, \4 N1 s
E000:6EE2 5F                        pop   di
" e9 D6 a( a9 e* ^- W# OE000:6EE3 66 C1 CB 10               ror   ebx, 10h
" o9 n) P% O7 G, n1 |E000:6EE7 8E C3                     mov   es, bx              ; es = HI_WORD(phy addr of compressed component)2 G, [( P/ v, C: l
E000:6EE9 66 C1 CB 10               ror   ebx, 10h            ; restore ebx+ ^+ U$ Q+ n# e2 {" H( v- n4 v
E000:6EED 26 8B 4F 11               mov   cx, es:[bx+11h]     ; cx = decompression segment address.
$ z8 W+ J: M( U) C7 FE000:6EED                                                     ; The component will be decompressed into this segment address
! m2 H9 w! ]1 F0 {- AE000:6EF1 51                        push  cx                  ; push decompression segment addr
  o! K5 O$ a$ t, U2 C# ^5 i7 z6 o. OE000:6EF2 26 FF 37                  push  word ptr es:[bx]    ; push (LZH hdr len and LZH hdr chksum)! c/ U; R8 Z# A2 U2 a
E000:6EF5 F6 C4 80                  test  ah, 80h
! x- ~* Q, W( J( {; mE000:6EF8 74 36                     jz    short decompress    ; all extension BIOS component-->jmp taken$ X+ v% D! o+ x. G9 P9 T9 F) v
E000:6EFA 26 89 57 11               mov   es:[bx+11h], dx
* m) v+ V/ |  `' a, y) zE000:6EFE 02 CD                     add   cl, ch
3 s3 ]/ h( n! J; ?5 n7 o# {+ tE000:6F00 02 D6                     add   dl, dh& ]  x7 b& w  u3 h+ N
E000:6F02 2A CE                     sub   cl, dh& q6 {! f  D7 K
E000:6F04 26 28 4F 01               sub   es:[bx+1], cl! h. R$ t: G8 ^* n  f6 P
E000:6F08 EB 26                     jmp   short decompress
, R, d) n, w6 I+ {; mE000:6F0A                         ; ---------------------------------------------------------------------------
) H& g& E* }$ N+ T5 y9 cE000:6F0A                         above_1MB:                  ; CODE XREF: decompress_BIOS_component+68: u1 }5 o: @# I+ B) K
E000:6F0A 66 81 C3 00 00 0E 00      add   ebx, 0E0000h
1 b3 w+ c5 S/ E- E; ME000:6F11 26 67 8B 4B 11            mov   cx, es:[ebx+11h]    ; cx = target segment addr (the component will be
0 v# T" n4 f1 s" T# d) }E000:6F11                                                     ; decompressed into this segmnt). H" P1 ^) b$ p' j- R# b5 F3 d4 ^
E000:6F16 51                        push  cx
! c9 t' B. C! x( P; @0 a6 z0 Y) GE000:6F17 26 67 FF 33               push  word ptr es:[ebx]# ]4 G, g$ u& {8 C
E000:6F1B F6 C4 80                  test  ah, 80h3 P' d7 G, Q$ b5 A+ @
E000:6F1E 74 10                     jz    short decompress
5 Z9 o4 Y4 [! PE000:6F20 26 67 89 53 11            mov   es:[ebx+11h], dx* J/ H" A0 p# |$ m- c
E000:6F25 02 CD                     add   cl, ch
" p) i  I- l9 u1 o; ZE000:6F27 02 D6                     add   dl, dh: ^) u( o: X' u
E000:6F29 2A CE                     sub   cl, dh
3 M$ N! L" o4 w: c" KE000:6F2B 26 67 28 4B 01            sub   es:[ebx+1], cl
9 U6 e/ k( Z2 k0 N' M! JE000:6F30                         decompress:                 ; CODE XREF: decompress_BIOS_component+AF
( q5 D3 e0 K9 w3 o' @% [. DE000:6F30                                                     ; decompress_BIOS_component+BF ...4 L/ ?/ b. y' e. X0 L
E000:6F30 66 C1 CB 10               ror   ebx, 10h
9 K0 ?( A2 x9 t: d  TE000:6F34 8E C3                     mov   es, bx              ; es = phy_addr>>0xC (hi_word of phy addr)
4 g2 O% \& B6 u& @6 e7 a1 Q- h# HE000:6F36 66 C1 CB 10               ror   ebx, 10h            ; bx = compressed component offset& J8 H3 }7 X* M3 ~
E000:6F3A 0E                        push  cs
! l) A, }% t, u2 u" [9 y/ V8 u# N: u4 mE000:6F3B 68 49 6F                  push  6F49h               ; ret addr below) w3 ]# \  S3 A9 p5 j) [0 u
E000:6F3E 68 FF DF                  push  0DFFFh5 r. g# B0 V) i- h3 x
E000:6F41 BA 00 30                  mov   dx, 3000h           ; scratch_pad_seg4 C6 w, f' c# U4 ^0 [+ I
E000:6F44 68 00 20                  push  2000h+ e% |# D; f) ^: n1 k( m
E000:6F47 57                        push  di                  ; call Decompression_Ngine* ^5 ~! y6 u- _
E000:6F48 CB                        retf                       
8 X! e: j+ o0 g* u* \E000:6F49                         ; ---------------------------------------------------------------------------
' s5 M6 a  S6 r* ^$ J2 xE000:6F49 68 00 E0                  push  0E000h
! E  P/ \- w5 L% t0 k$ aE000:6F4C 68 5A 6F                  push  6F5Ah
' Z* J9 ^$ ~8 U/ t5 S6 m- D' YE000:6F4F 68 31 EC                  push  0EC31h
( d0 }6 `' a2 |; |( N# ^E000:6F52 68 D4 E3                  push  0E3D4h              ; disable_A20...
2 y# J- |  t! n+ d$ C9 I* O/ z) JE000:6F55 EA 30 EC 00 F0            jmp   far ptr F000_Vector! r1 V: r' }$ K7 V
E000:6F5A                         ; ---------------------------------------------------------------------------
) \( x3 N( C. I" YE000:6F5A E8 3E 7C                  call  ds_ss_Enter_Voodoo_Mode) p! Z  F! J2 |% R# W$ ~- ~
E000:6F5D 8C D8                     mov   ax, ds
+ E, s( _5 L" G- q" C: rE000:6F5F 8E C0                     mov   es, ax              ; es --> voodoo mode, base at 0000_0000h: K4 T$ [# V2 \# ~! f& {: ?
E000:6F61 E8 54 7C                  call  ss_Leave_Voodoo_mode3 u2 |4 H& a$ {. K9 k0 {
E000:6F64 67 66 A1 00 00 08 00      mov   eax, ds:80000h, X/ x3 y4 [# b: i2 u
E000:6F6B 67 66 3B 05 00 00 16 00   cmp   eax, ds:160000h
: ^' C* s+ |8 [6 O) v" y: |E000:6F73 75 18                     jnz   short restore_header$ `' T" Z( O; t- Z% u- G2 ]4 s! \
E000:6F75 66 C1 CB 10               ror   ebx, 10h0 w* x' @+ G% o+ X5 U! x  Q6 V
E000:6F79 8E C3                     mov   es, bx$ H5 o  n& O% t5 R7 R
E000:6F7B 66 C1 CB 10               ror   ebx, 10h
( E- A+ N! Y: k2 N+ uE000:6F7F 26 8F 07                  pop   word ptr es:[bx]8 Y0 `9 F1 ?  X  V
E000:6F82 26 8F 47 11               pop   word ptr es:[bx+11h], J2 ?9 r8 x6 U3 K
E000:6F86 26 66 8B 5F 0B            mov   ebx, es:[bx+0Bh]) D* z1 a" w1 d! F: p4 q* j
E000:6F8B EB 0F                     jmp   short disable_A20
1 b- @" W/ P8 Y8 d5 SE000:6F8D                         ; ---------------------------------------------------------------------------3 V2 e1 @& y2 q
E000:6F8D                         restore_header:             ; CODE XREF: decompress_BIOS_component+12A
9 t+ [: o3 `: M" ME000:6F8D 26 67 8F 03               pop   word ptr es:[ebx]1 X( r0 ?; ]" D6 V$ _" F  ^. W4 c
E000:6F91 26 67 8F 43 11            pop   word ptr es:[ebx+11h]5 }# N/ V8 F; D! i- w( m, r9 R
E000:6F96 26 67 66 8B 5B 0B         mov   ebx, es:[ebx+0Bh]
2 Z' J2 N* S# d0 L) m. xE000:6F9C                         disable_A20:                ; CODE XREF: decompress_BIOS_component+142) _+ x  V% M. ~( P4 l
E000:6F9C 68 00 E0                  push  0E000h4 k" I/ S6 j5 ~# @
E000:6F9F 68 AD 6F                  push  6FADh
- E- _) V  k" y+ j3 GE000:6FA2 68 31 EC                  push  0EC31h+ X5 S8 B! V1 K5 `8 v! y
E000:6FA5 68 24 E4                  push  0E424h              ; disable gate A20
; L7 z$ j+ y$ F" s0 W9 iE000:6FA8 EA 30 EC 00 F0            jmp   far ptr F000_Vector
) n' {1 W& W8 P8 h3 c$ l9 w8 nE000:6FAD                         ; ---------------------------------------------------------------------------# r1 `1 S6 x. u+ T7 _+ M2 @) r9 y
E000:6FAD F8                        clc
% A8 U% `& ?7 T- x: ^E000:6FAE EB 01                     jmp   short decomprss_BIOS_componnt_ret+ L& S/ R. |: e0 l& Z; {- {
E000:6FB0                         ; ---------------------------------------------------------------------------
4 s; T6 S- J! }/ |4 wE000:6FB0                         no_cmprssd_component:       ; CODE XREF: decompress_BIOS_component+35
+ u: @0 r) h  U8 d- fE000:6FB0                                                     ; decompress_BIOS_component+3C
1 a- f- G/ E2 i" k; GE000:6FB0 F9                        stc/ G0 q/ [0 B% f
E000:6FB1                         decomprss_BIOS_componnt_ret:% A+ O( D6 H* s
E000:6FB1                                                     ; CODE XREF: decompress_BIOS_component+468 Y0 t% m2 `5 y; m$ P4 p" f: n. |" W$ L
E000:6FB1                                                     ; decompress_BIOS_component+165
/ b- U( e6 b: a3 C8 hE000:6FB1 9C                        pushf. |4 U$ z; Y. Q1 f6 T/ p7 Y. f
E000:6FB2 66 53                     push  ebx3 z$ K  s9 S4 V8 b& v3 z
E000:6FB4 68 00 E0                  push  0E000h% |3 d! u" t+ y) S( q: n+ O8 ~2 l
E000:6FB7 68 C5 6F                  push  6FC5h
" w2 b) q& [0 t0 e- N% g, UE000:6FBA 68 31 EC                  push  0EC31h
% l3 c- J* b8 L: B- i% p3 R; tE000:6FBD 68 D4 E3                  push  0E3D4h              ; enable gate A20
# f' [( ?8 ]4 p: h( _. W8 qE000:6FC0 EA 30 EC 00 F0            jmp   far ptr F000_Vector4 L9 a! g. f* F6 G6 y% ]
E000:6FC5                         ; ---------------------------------------------------------------------------( ]* N2 k" Z+ m( s4 u
E000:6FC5 E8 D3 7B                  call  ds_ss_Enter_Voodoo_Mode8 {- {; _! v2 [9 F7 Z/ I) Z0 Z
E000:6FC8 8C D8                     mov   ax, ds
. i. O) t) {! H; K, N" @/ b! lE000:6FCA 8E C0                     mov   es, ax, p4 E/ {( N6 C9 X/ y- S% w# T: a4 w3 F
E000:6FCC E8 E9 7B                  call  ss_Leave_Voodoo_mode
7 X/ S$ l4 X: D& f# VE000:6FCF 67 66 A1 00 00 08 00      mov   eax, ds:80000h
3 X* ?; z3 x% Q2 F* V8 ME000:6FD6 67 66 3B 05 00 00 16 00   cmp   eax, ds:160000h0 u3 N( v4 b  A7 h( d
E000:6FDE 75 2B                     jnz   short exit
6 ^, x/ d0 f9 r1 ?( E# \E000:6FE0 66 BF 00 00 08 00         mov   edi, 80000h9 `& g( L1 ^% J: E. e+ L: A
E000:6FE6 66 B9 00 40 00 00         mov   ecx, 4000h
9 O8 Q8 y% U" m) A: WE000:6FEC 66 33 C0                  xor   eax, eax
4 x8 Y* _( m3 h( V  GE000:6FEF FC                        cld6 Q1 H5 w+ f: g8 U1 v
E000:6FF0 67 F3 66 AB               rep stos dword ptr es:[edi]3 l- }, K& G$ X2 W* ^3 }. c1 u
E000:6FF4 66 BE 00 00 14 00         mov   esi, 140000h
$ U8 |8 N; i2 r5 pE000:6FFA 66 BF 00 00 09 00         mov   edi, 90000h3 K* X* A0 H, H. t7 P6 h+ v
E000:7000 66 B9 00 40 00 00         mov   ecx, 4000h
/ y: h0 b7 T# s- C- R% V4 s: ]7 fE000:7006 FC                        cld
+ E7 u- E% c; |0 E! aE000:7007 67 F3 66 A5               rep movs dword ptr es:[edi], dword ptr [esi]
  a# E0 n9 k: R# ZE000:700B                         exit:                       ; CODE XREF: decompress_BIOS_component+195* C8 L  ?9 E+ J# c- _
E000:700B 68 00 E0                  push  0E000h
9 q+ O4 W+ s7 M9 ~/ o, pE000:700E 68 1C 70                  push  701Ch, C4 s6 ^) e0 s: p4 \# H
E000:7011 68 31 EC                  push  0EC31h4 d$ s8 E1 Q# k9 d
E000:7014 68 24 E4                  push  0E424h              ; turn off Gate A20" R: h. a$ ?( `
E000:7017 EA 30 EC 00 F0            jmp   far ptr F000_Vector) U7 x9 d- K0 C" a
E000:701C                         ; ---------------------------------------------------------------------------
, n1 x+ T, K) C2 i7 Q' bE000:701C 66 5B                     pop   ebx
+ ?4 I4 r* j  h; iE000:701E B0 00                     mov   al, 0               ; disable CPU cache
: ]9 U" x5 ~' p  D( eE000:7020 E8 49 FC                  call  F0_init_cpu_cache
8 @5 j0 L8 \- cE000:7023 9D                        popf; C) N! C0 H) |
E000:7024 5D                        pop   bp
. l$ c1 i5 d. {6 v* c3 q$ l4 Y0 c, SE000:7025 07                        pop   es
7 W- C; k% c- E1 }. n- E* H1 S% kE000:7026 1F                        pop   ds
: K/ @  t) `+ TE000:7027 C3                        retn
* X" t- D+ {: _0 }0 l/ NE000:7027                         decompress_BIOS_component endp ; sp = -18h1 k8 E; v. \4 O8 N
其他部分的解压和处理与nnoprom.bin和rosupd.bin相似,如上。 $ j6 m- C& ~8 E2 c% Y# V! m
通过上面的解释,我们只需要跟随“POST jump table execution”来知道在哪个环境下哪个“执行路径”被bios得到。做完了这个方法,我们就能够做我们喜欢做的hack award bios。不管怎样,我不准备在这里停止,下面的章节,我要给你呈现一些扩展部分的处理方法,他们很让我感兴趣。, N1 K: \7 z7 v3 Q, i
7.2.7. Microcode Update Routine1 w" T8 t  v5 S2 v
微代码升级历程从POST_9S调用,如下所示:
# y/ i. h  c* N________________________________________8 b' t9 }5 [  z  O! [& X4 R
E000:3BBE                         init_microcode proc near    ; CODE XREF: POST_9S+52
6 x0 E" t3 ^) ^2 h! F0 uE000:3BBE E8 4E 38                  call  is_intel_CPU
$ n2 S" c% n0 e2 yE000:3BC1 75 5F                     jnz   short exit
; M5 Z% t+ g5 m1 LE000:3BC3 66 B8 01 00 00 00         mov   eax, 1
6 {  ?$ R* S# v4 p" C5 _E000:3BC9 0F A2                     cpuid
0 q, A5 D8 y4 j( RE000:3BCB BB 00 20                  mov   bx, 2000h
, D) v+ B6 U# P$ d7 mE000:3BCE 8E DB                     mov   ds, bx
* ]9 @% c2 ?+ O7 ]; cE000:3BD0                           assume ds:_2000h1 v2 l3 h- o( @  p; b. P, G5 H
E000:3BD0 BB 00 90                  mov   bx, 9000h- N) R0 H7 W! ^5 v* }, u7 U
E000:3BD3 3B 47 0C                  cmp   ax, [bx+0Ch]5 d7 I6 O2 X7 x6 t3 b6 v& E# R' M+ o) `
E000:3BD6 75 05                     jnz   short decompress_microcode
  H( x8 J$ G- V+ X; t& J9 Y( b3 a! I9 wE000:3BD8 E8 48 00                  call  get_cpu_microcode_ver
. z- b& C1 n+ G- LE000:3BDB 74 2C                     jz    short update_microcode3 ?! G. @/ k& Q+ E: E
E000:3BDD                         decompress_microcode:       ; CODE XREF: init_microcode+18" \0 g3 |/ A2 B4 Z+ H
E000:3BDD 66 50                     push  eax
% ?) v1 t1 I1 |4 _! M6 wE000:3BDF BF 08 00                  mov   di, 8               ; compressed microcode index (4*(lo_byte(4001h)+1))* p) {2 N- W- z  s; e0 n+ ]' s" z
E000:3BE2 E8 64 32                  call  near ptr decompress_BIOS_component# v" Q! B5 y. u% ]3 U( T
E000:3BE5 66 58                     pop   eax
( D- y5 D5 ]' b) Q( j4 ]& d5 e, B* zE000:3BE7 72 39                     jb    short exit; K! B! t2 j, r6 W4 c! |3 v
E000:3BE9 66 C1 EB 0B               shr   ebx, 0Bh
7 j, }* k3 ?( |/ J$ C! eE000:3BED 66 8B CB                  mov   ecx, ebx
" ~- p& O' Z' y6 T% JE000:3BF0 BB 00 40                  mov   bx, 4000h
2 S( U) H, {1 y4 ~3 {' t8 z$ uE000:3BF3 8E DB                     mov   ds, bx              ; point to seg 4000h (microcode decompression rsult)8 e0 Y/ M3 P! c4 y* c9 P
E000:3BF5                           assume ds:nothing, u, g2 u0 ~2 g, ?1 Y' m
E000:3BF5 33 DB                     xor   bx, bx              ; init bx
! C$ `6 W9 a* EE000:3BF7                         next_microcode:             ; CODE XREF: init_microcode+47
6 C, w) F" _6 _& K+ F4 SE000:3BF7 3B 47 0C                  cmp   ax, [bx+0Ch]
! S, K& [. A! e6 A9 I" ]2 s+ wE000:3BFA 75 05                     jnz   short microcode_not_match4 v( Y# ?$ H) T' }# G8 _
E000:3BFC E8 24 00                  call  get_cpu_microcode_ver
  t3 K9 h% M6 l4 Y! N7 r$ uE000:3BFF 74 08                     jz    short update_microcode
. A1 z$ b" t$ X* N2 EE000:3C01                         microcode_not_match:        ; CODE XREF: init_microcode+3C
' h+ i  x# O6 S3 S* \! X3 GE000:3C01 81 C3 00 08               add   bx, 800h            ; length of one microcode
% t, y/ D! y% u, v/ j( ]6 B; S* {E000:3C05 E2 F0                     loop  next_microcode; ~. i% c8 M4 a! X$ w! X+ x
E000:3C07 EB 19                     jmp   short exit
- H+ K/ A9 v; ?: N2 `0 {E000:3C09                         ; ---------------------------------------------------------------------------
% x/ C! @. j4 }( B0 S. vE000:3C09                         update_microcode:           ; CODE XREF: init_microcode+1D
4 ]( X  c9 F6 O* ~& \! g; GE000:3C09                                                     ; init_microcode+41
) z- c5 I) e0 vE000:3C09 66 B9 79 00 00 00         mov   ecx, 79h ; 'y'
( P6 i4 r$ V4 k  p9 A# g1 vE000:3C0F 66 33 C0                  xor   eax, eax
7 _  D( z& m4 x" O# C- a" mE000:3C12 66 33 D2                  xor   edx, edx            ; microcode update sign$ e; k' n% {: x8 [% j
E000:3C15 8C D8                     mov   ax, ds
* t0 n. X/ E/ E0 P; YE000:3C17 66 C1 E0 04               shl   eax, 42 y( E: ]% ]! ~, j
E000:3C1B 83 C3 30                  add   bx, 30h ; '0'4 u9 P( Y1 L2 Z' }1 x3 D
E000:3C1E 8B C3                     mov   ax, bx              ; eax = linear addr of the microcode
+ R) B, M# n1 M. k8 [+ B% cE000:3C20 0F 30                     wrmsr                     ; start microcode update0 Z5 Z+ D% h  ?- [: [
E000:3C22                         exit:                       ; CODE XREF: init_microcode+3
$ E: n+ u" @4 q: XE000:3C22                                                     ; init_microcode+29 ...
! k% s* e7 O2 y' ^7 i) rE000:3C22 C3                        retn
. D  A; N* {3 n( P5 KE000:3C22                         init_microcode endp
! m5 m7 j( K* G  n+ z! m. j# y8. 激昂展望9 D) x. e7 L' c, k2 F
Hey, if you've read this article this far, you must be curious (^__^). Let's take a break a bit. I want to say some facts that are ridiculous. Well, at least to me. BIOS code is meant to be "twisted" so that code digger like us will find a hard time to figure it out. But, yeah here we are, understanding the big picture. Code digger rules my man! Nothing more dangerous than curiousity. , z# u9 o, U! ]
It's funny to see that the core LZH decompression routine that is used by award bioses (at least v4.51 that's dissected here) is just a complete "copy and paste" from Haruhiko Okumura's LZH code that anyone can find in the web. It's just the language that's different, Okumura's is in C while award's is in x86 assembly, the subroutines were exactly the same! + _$ G' L  h' Z
Another fact is, Phoenix code is very similar to award's code. I don't know who is "stealing" who, or perhaps there' s another source where both of them steal from (^__^). Oh no... I guess they are just doing reverse engineering like me with their tons of money. Unfortunately I don't have those tons of money he..he..he.. " w! Q' Y/ l. T  _4 ~+ k8 Q$ V
Well, let me stop ranting and continue my work on AMI BIOS. I guess we all waiting for it, right? It'll take sometime coz I'm very busy. If anyone of you who read this article have done it and had something to say or want to share your work with the world, I really keen to know. Why don't we join forces, right? my mail address is in the end of this article. I know some of us have done it.. we just haven't been in contact or perhaps it's better if we find our own way. Time will tell (-__-)
" M/ X0 m$ M% s; ]( EGreetz go to: Kris Kaspersky, Petr Soucek, Polaris, Havok, Zero, Mike Tedder a.k.a bpoint, apple_rom, Ilfak Guilfanov and many others who share their knowledge with the world.
- e) r) |5 S5 F* o7 B9. 结束语
8 m6 d7 U  Z' q* dWhat I've explained above possibly far too premature to be ended here. But, I consider this article finished here as the Beta 5 version. If you follow this article from beginning to end, you'll be able to understand the "BIG Picture" of how the Award BIOS works. I think all of the issue dissected here is enough to do any type of modification you wish to do with award bios. If you find any mistake(s) within this article or have any suggestion, please contact me [email]mamanzip@yahoo.com[/email]. Goodluck with your BIOS reverse engineering journey, I hope you enjoy it as much as I do (^__^) .
回复

使用道具 举报

发表于 2008-5-19 20:44:46 | 显示全部楼层
Nothing more dangerous than curiousity.
回复

使用道具 举报

发表于 2008-5-20 20:51:49 | 显示全部楼层
好东西收藏起来了,明天发到公司好好研究~~~8 h* T: M) v2 \5 P& R$ t8 y

7 j, _( K0 a. @/ Y7 u# P谢谢斑竹~~~~~~~~
回复

使用道具 举报

发表于 2008-6-12 23:15:33 | 显示全部楼层
thank you!
回复

使用道具 举报

发表于 2008-12-23 15:38:33 | 显示全部楼层
讲了点点皮毛?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2024-12-24 01:44 , Processed in 0.086702 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表