【我所认知的BIOS】->反汇编BIOS之Bootblock(6)

【我所认知的BIOS->反汇编BIOSBootblock(6)

--关于S3Normal reset BIOS的走向

By Lightseed

5/18/2010

一、BIOS的主流程

我们的BIOS主流程如图1所示,上一个章节我们的BIOS执行到了记录CPU type的东东,当时我们就发现其实在Record_CPU_type的前面还有其他函数。那么我们这节就来单独讨论这个问题。这个章节的内容是我们作为BIOS engineer必定要聊熟于心的东西,我想任何一个业内人士应该不会否认这点的。也是BIOS的一个走向的十字路口,搞清楚这章节我想对理解整个X86架构中的power management理解是一个很好的基础。

1 BIOS主流程

二、Normal resetResume from Sx的算法

下面这段代码就是紧接了前面我们反汇编出来的BIOS源码的后半段。虽然这里短短数行,但是却把BIOS完全分成了两个不同的道路。Normal reset就会走平时我们理解的BIOS流程,继续进行后续的其他设备的初始化动作。而Resume from Sx的那条路就是从之前系统保存好的各个状态中逐个把系统的各个设备快速恢复他们的状态,进而BIOS把控制权交个OS,让OS自己也恢复到之前的状态。不过,后者我们暂时不去讨论,那个还牵涉到ACPI的部分,目前我们先说到这里,以后我肯定会和大家share的。(不过得让我把Normal reset这部分的BIOS和大家探讨完了以后哦。做事要有先后嘛~~

_F000:E1CB SuperIO_INIT_Ret:              ; CODE XREF:   _F000:E28Ej

 

Call    Detect_If_Power_failure;伪代码

 

_F000:E1E2 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:E1E5       dw 0E1E7h

_F000:E1E7 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:E1E7       mov    dx, 4005h             ; PM   IO+5 Power Management 1  Control

_F000:E1EA       in     al, dx

_F000:E1EB       cmp    al, 0FFh              ; If   valid?

_F000:E1ED       jz     Not_Resume_From_Sx

_F000:E1EF       and    al, 1Ch               ; Separate the 'Sleep Type' bits [bit 10~12]

_F000:E1EF                                    ; 000b ON: Typically maps to    S0 state.

_F000:E1EF                                    ; 001b Asserts STPCLK#. Puts    processor in Stop-Grant state. Optional   to assert

_F000:E1EF                                    ; CPUSLP# to  put processor in sleep state: Typically  maps to    S1 state.

_F000:E1EF                                    ; 010b Reserved

_F000:E1EF                                    ; 011b Reserved

_F000:E1EF                                    ; 100b Reserved

_F000:E1EF                                    ; 101b Suspend-To-RAM. Assert SLP_S3#: Typically maps to S3 state.

_F000:E1EF                                    ; 110b Suspend-To-Disk. Assert SLP_S3#, and SLP_S4#:   Typically maps to S4 state.

_F000:E1EF                                    ; 111b Soft Off. Assert SLP_S3#, SLP_S4#, and SLP_S5#: Typically maps to S5 state.

_F000:E1F1       cmp    al, 14h

_F000:E1F3       jnz    Not_Resume_From_Sx

_F000:E1F5       jmp    Resume_From_S3        ; 如果是从S3回来,那么就BIOS进入到resume的分支。唤醒沉睡的系统了

_F000:E1F8 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

 

Not_Resume_From_Sx                          ; 正常的BIOS boot

 

我说上面的这些短小的code就已经把大致的算法都说了,也许细心的大家也应该很容易弄明白的了。(哈哈。。。想想,其实BIOS并不是我们以前想的那么神秘对么?看看上面的代码,多简单哦~~相比起其他的大型算法而言,呵呵。。。不过不要高兴的太早哦-_-)容我慢慢道来:

①在这行中,

_F000:E1CE       jmp    Assume_Normal_Reset

用了ROM_CALL的做法,先假设当前的BIOSNormal reset的。里面的函数,我想还是你自己跟一下比较好吧。

②接下来我要详细说一下Detect_If_Power_failure这个函数。这个函数的功能就是从南桥的power management的相关寄存器中取出相应的参数来做对比,check一下是否是系统有完全掉电,power failure。(下面这个函数实在是不想删它,保留着吧,因为这里的操作确实是很有意思。)

_F000:F6BC ;------------------------------------------------------------------------------------------------

_F000:F6BC Function: Detect_If_Power_failure

_F000:F6BC

_F000:F6BC    Before detecting if resume from Sx, to detect if power failed.

_F000:F6BC        If yes, clear the sleep state.

_F000:F6BC        If no, go ahead.

_F000:F6BC ;------------------------------------------------------------------------------------------------

_F000:F6BC

_F000:F6BC Detect_If_Power_failure:                ; CODE XREF: _F000:E1E2j

_F000:F6BC                 shl     esp, 10h

_F000:F6C0                 mov     cx, 0F8A4h      ; ICH6  General PM Configuration 3 Register

_F000:F6C3                 mov     sp, 0F6C9h

_F000:F6C6                 jmp     Get_Pci_Byte

_F000:F6C6 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:F6C9                 dw 0F6CBh

_F000:F6CB ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:F6CB                 test    al, 2           ; Power failure?

_F000:F6CB                                         ; 0 = Indicates that the trickle current has not failed since the last time the bit was cleared. Software

_F000:F6CB                                         ; clears this bit by writing a 1 to it.

_F000:F6CB                                         ; 1 = Indicates that the trickle current (from the main battery or trickle supply) was removed or failed.

_F000:F6CD                 jz      Not_Power_Failure

_F000:F6CF                 mov     dx, 4005h       ; PM IO+5 Power Management 1 Control

_F000:F6D2                 in      al, dx

_F000:F6D3                 and     al, 0E3h

_F000:F6D5                 out     dx, al          ; Clear Sleep state.  turn Sleep Enable off

_F000:F6D6

_F000:F6D6 Not_Power_Failure:                      ; CODE XREF: _F000:F6CDj

_F000:F6D6                 shr     esp, 10h

_F000:F6DA                 retn

_F000:F6DA ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

这个函数比较重要,所以要详细说明一下。_F000:F6C0这行是为了读取ICH6  General PM Configuration 3 Register这个寄存器。_F000:F6CB在后续我有做注释,它是去check这个寄存器中的bit 1,看看是否记录了南桥是否有Power failure的情况。(因为纵然你之前有可能系统是进入了S3,但是当power failure【其实就是完全掉电,电源插头拔掉的意思】的话,那么整个板子上的电都会掉,也就是说记录到内存里面的系统状态信息,就会丢失,那么必须要让BIOSNormal reset那面启动。)如果是power failure的话,那么直接把Power Management 1 Control这个寄存器中记录SX状态的记录全部清掉。

我们来看看General PM Configuration 3 RegisterPower Management 1 Control这两个寄存器的截图。

2General PM Configuration 3 Register寄存器中关于说明power failure的说明。图3Power Management 1 Control中关于sleep type的说明。

 

2

 

3

③第二点中的函数弄清楚了,那么后续的动作就不难懂了。后续的动作,大致就是从Power Management 1 Control寄存器中读取出sleep type,然后判断,如果是确定系统是从Sx醒来的话,那么就进入到Resume_From_S3BIOS分支中去。(那是后话,以后我们再研究。)如过是Normal reset那么就在_F000:E1F8这行中向80 port丢出debug code来,继续往后走了。

三、小结

虽然看上去似乎很简单,但是这里却很重要,所以花了比较多的笔墨来反复和大家说。BIOS中的十字路口我们就讲到这里,希望对大家有所启发。(如果想要了解关于S3的东西,那么我先建议您可以看看ACPIspec,然后再结合ICHdatasheet先好好理解一下原理,这样对后续的讲解比较有帮助。)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值