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

来源:互联网 发布:js控制div 删除class 编辑:程序博客网 时间:2024/05/17 04:22

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

-- Memory initial 之前的一些初始化DMA8259

By Lightseed

5/20/2010

1BIOS的主流程

为什么会有bootblock和非bootblock这么一说呢?其实就是因为有没有真正的内存可以用的区别。这个章节里我们一起来看看经过之前那些章节的讨论后,BIOS在初始化memory之前会做的一些动作。(稍微比较琐碎点,看起来比较枯燥。)

1 BIOS主流程

2、确实是Normal后的第一个JMP

从下面的这段code中我们来研究一下,_F000:E1FC这里是的SP指向E200H地址,且我们看看在E200H这里这里存储的数据是E292H,注意了,这里可不是E202H哦。执行retn后,那么CPUIP寄存器就变成了E292H了,那么CPU就会从此处取code来执行。(可不要犯了ROM_CALL的定势思维。)

_F000:E1F8 Not_Resume_From_Sx:                     ; CODE XREF: _F000:E1D3j

_F000:E1F8                                         ; _F000:E1EDj ...

_F000:E1F8                 mov     al, 0C0h ; '?

_F000:E1FA                 out     80h, al         ; manufacture's diagnostic checkpoint

_F000:E1FC                 mov     sp, 0E200h

_F000:E1FF                 retn

_F000:E1FF ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:E200                 dw 0E292h

3CPU Fast stringdetect以及CMOS的初始化

_F000:E292 Go_on_bios:

。。。。。。。。。。。。。

_F000:E29D                 jmp     Fast_string_If_open

_F000:E29D ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:E2A0                 dw 0E2A2h

_F000:E2A2 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:E2A2                 mov     al, 8Bh ; '?   ; CMOS REGISTER 0B: Default is all interrupts(AIE,PIE) turned off,

_F000:E2A2                                         ; date is in BCD format, time is in 24-hour mode, daylight savings

_F000:E2A2                                         ; time is disabled.

_F000:E2A4                 mov     ah, 2

Call     Set_CMOS      ;伪代码

_F000:E2AE                 mov     al, 8Ah ; '?   ; CMOS REGISTER 0A: Default is stage divider at 32.768 kHz, divider

_F000:E2AE                                         ; output at 1.024 Khz, interrupting every 976.562 microseconds

_F000:E2B0                 mov     ah, 26h ; '&'

Call     Set_CMOS      ;伪代码

上面这段code主要做了两件事情,一个是检测CPUfast string是否支持。另外一个是初始化CMOS的基本配置。

3.1 CPUfast string

还是来看我们反汇编出来的code吧。

_F000:E6AB ;------------------------------------------------------------------------------------

_F000:E6AB ;FUNC: Fast_string_If_open

_F000:E6AB ;

_F000:E6AB ;DESC: If CPU support Fast_string then enable it.

_F000:E6AB ;

_F000:E6AB ;IN:       NONE

_F000:E6AB ;OUT:   NONE

_F000:E6AB ;------------------------------------------------------------------------------------

_F000:E6AB

_F000:E6AB ; 圹圹圹圹圹圹圹?S U B R O U T I N E 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹?

_F000:E6AB

_F000:E6AB

_F000:E6AB Fast_string_If_open proc near           ; CODE XREF: _F000:E29Dj

_F000:E6AB                 mov     eax, 0

_F000:E6B1                 cpuid

_F000:E6B3                 cmp     ebx, 'iryC'

_F000:E6BA                 jz      locret_FE6D9

_F000:E6BC                 mov     eax, 1

_F000:E6C2                 cpuid

_F000:E6C4                 cmp     ax, 611h

_F000:E6C7                 jnz     locret_FE6D9

_F000:E6C9                 mov     ecx, 1E0h

_F000:E6CF                 rdmsr

_F000:E6D1                 and     eax, 6

_F000:E6D5                 or      al, 4           ; disable fast string

_F000:E6D7                 wrmsr

_F000:E6D9

_F000:E6D9 locret_FE6D9:                           ; CODE XREF: Fast_string_If_open+Fj

_F000:E6D9                                         ; Fast_string_If_open+1Cj

_F000:E6D9                 retn

_F000:E6D9 Fast_string_If_open endp

上面函数的大致的意思是,用CPUID来读取CPU的属性,判断是否支持Fast string,如果不支持的话,那么就disabled掉它。(也许有人会问,上面是fast string,您可以在3A里面查到 ^.^。)如图1

 

1

3.2 CMOS的基本配置

多的就不说了,在code我都详细注解了,看不懂的话,再多查查datasheet就知道了。

4DMA8259的初始化

4.1 算法

现在这个小节我们继续讲讲memory之前的另外一些动作,这些动作沿用了之前初始化superio的方法,先列一个tabletable以结构体的形式存在,用指针指向这个table,用一个循环依次逐个地把table里面列的寄存器都初始化。(算法很简单如下)

_F000:E2BF                 mov     si, 0E6DAh      ; data source pointor

_F000:E2C2                 mov     cx, 24h ; '$'   ; loop counter

_F000:E2C5                 cld

_F000:E2C6

_F000:E2C6 loc_FE2C6:                              ; CODE XREF: _F000:E2CFj

_F000:E2C6                 lodsw                   ; Get the port

_F000:E2C7                 mov     dx, ax

_F000:E2C9                 lodsb                   ; Get the value will be stored

_F000:E2CA                 out     dx, al

_F000:E2CB                 jmp     short $+2

_F000:E2CD                 jmp     short $+2

_F000:E2CF                 loop    loc_FE2C6       ; Get the port

算法的话,也就上面这个样子,简单地不能再见到了。BIOS里面,这些都不是难点。难点在于,怎么去理解这个table里面都初始化了些什么,我想这也是大家最care的东西。好吧,那么我们来深入到table里去吧。

4.2 详细初始化内容

table里面的structure如下:

Struc {

             Word  ;存放的是将要填值的port address

             Byte   ;存放的是将要填到port address里面的value

}

_F000:E6DA ;[]-----------------------------------------------------[]

_F000:E6DA one word and one byte are made of a set.

_F000:E6DA The word is port address, the byte is the value will be store

_F000:E6DA ;[]-----------------------------------------------------[]

_F000:E6DA System_INIT_table dw 3B8h               ; 3B8H is the IO for VGA controller, but I can not find out its description. So I don't know its mean

_F000:E6DC                 db    1 ;               ;

_F000:E6DC                                         ;

_F000:E6DD                 dw 61h                  ; NMI Status and Control Register

_F000:E6DF                 db 0FCh ; ?            ; Turn speaker off

_F000:E6DF                                         ;

_F000:E6E0                 dw 8                    ; Channel 0~3 DMA Command Register

_F000:E6E2                 db    4 ;               ; Disable DMA Channel Group

_F000:E6E2                                         ;

_F000:E6E3                 dw 0D0h                 ; Channel 4~7 DMA Command Register

_F000:E6E5                 db    4 ;               ; Disable DMA Channel Group

_F000:E6E5                                         ;

_F000:E6E6                 dw 0F1h                 ; math coprocessor port

_F000:E6E8                 db    0 ;               ; reset it

_F000:E6E8                                         ;

_F000:E6E9                 dw 43h                  ; Choose TIMER 1

_F000:E6EB                 db  54h ; T             ;

_F000:E6EB                                         ;

_F000:E6EC                 dw 41h                  ; Initial it

_F000:E6EE                 db    0 ;               ;

_F000:E6EE                                         ;

_F000:E6EF                 dw 0Dh                  ; About DMA controller, but intel do not release

_F000:E6F1                 db    7 ;               ;

_F000:E6F1                                         ;

_F000:E6F2                 dw 0DAh                 ; About DMA controller, but intel do not release

_F000:E6F4                 db    7 ;               ;

_F000:E6F4                                         ;

_F000:E6F5                 dw 43h

_F000:E6F7                 db  40h ; @             ; Timer 1 latch command

_F000:E6F7                                         ;

_F000:E6F8                 dw 41h

_F000:E6FA                 db  12h ;               ;

_F000:E6FA                                         ;

_F000:E6FB                 dw 8                    ; Channel 0~3 DMA Command Register

_F000:E6FD                 db    0 ;               ; enable it

_F000:E6FD                                         ;

_F000:E6FE                 dw 0D0h                 ; Channel 4~7 DMA Command Register

_F000:E700                 db    0 ;               ; enable it

_F000:E700                                         ;

_F000:E701                 dw 0Bh                  ; About DMA controller, but intel do not release

_F000:E703                 db  40h ; @             ;

_F000:E703                                         ;

_F000:E704                 dw 0D6h                 ; About DMA controller, but intel do not release

_F000:E706                 db 0C0h ; ?            ;

_F000:E706                                         ;

_F000:E707                 dw 0D6h

_F000:E709                 db  41h ; A             ;

_F000:E709                                         ;

_F000:E70A                 dw 0Bh

_F000:E70C                 db  41h ; A             ;

_F000:E70C                                         ;

_F000:E70D                 dw 0D6h

_F000:E70F                 db  42h ; B             ;

_F000:E70F                                         ;

_F000:E710                 dw 0Bh

_F000:E712                 db  42h ; B             ;

_F000:E712                                         ;

_F000:E713                 dw 0D6h

_F000:E715                 db  43h ; C             ;

_F000:E715                                         ;

_F000:E716                 dw 0Bh

_F000:E718                 db  43h ; C             ;

_F000:E718                                         ;

_F000:E719                 dw 0D2h

_F000:E71B                 db    0 ;               ;

_F000:E71B                                         ;

_F000:E71C                 dw 0D4h

_F000:E71E                 db    0 ;               ;

_F000:E71E                                         ;

_F000:E71F                 dw 20h                  ; Initial Master 8259

_F000:E721                 db  11h ;               ; 级联, 边沿触发, 需要写ICW4

_F000:E721                                         ;

_F000:E722                 dw 21h                  ; Write ICW2

_F000:E724                 db    8 ;               ; 中断类型号8H

_F000:E724                                         ;

_F000:E725                 dw 21h                  ; Write ICW3

_F000:E727                 db    4 ;               ; 主片的IR2引脚接从片

_F000:E727                                         ;

_F000:E728                 dw 21h                  ; Write ICW4

_F000:E72A                 db    1 ;               ; 非特殊完全嵌套,非缓冲,非自动结束,80x86模式

_F000:E72A                                         ;

_F000:E72B                 dw 21h                  ; IMR interrupt mask register

_F000:E72D                 db 0FFh ;               ; mask IRQ0~7

_F000:E72D                                         ;

_F000:E72E                 dw 0A0h                 ; Initial Slave 8259

_F000:E730                 db  11h ;               ; 级联, 边沿触发, 需要写ICW4

_F000:E730                                         ;

_F000:E731                 dw 0A1h                 ; ICW 2

_F000:E733                 db  70h ; p             ; 中断类型号70H

_F000:E733                                         ;

_F000:E734                 dw 0A1h                 ; ICW 3

_F000:E736                 db    2 ;               ; 接主片的IR2引脚

_F000:E736                                         ;

_F000:E737                 dw 0A1h                 ; ICW 4

_F000:E739                 db    1 ;               ; 非特殊完全嵌套,非缓冲,非自动结束,80x86模式

_F000:E739                                         ;

_F000:E73A                 dw 0A1h                 ; IMR interrupt mask register

_F000:E73C                 db 0FFh ;               ; mask IRQ8~15

_F000:E73C                                         ;

_F000:E73D                 dw 43h

_F000:E73F                 db  36h ; 6             ; initial TIMER 0

_F000:E73F                                         ;

_F000:E740                 dw 40h

_F000:E742                 db    0 ;               ;

_F000:E742                                         ;

_F000:E743                 dw 40h

_F000:E745                 db    0 ; 

_F000:E746

关于上面的初始化过程,我想要说明两点:

DMA controller的一些资料intel没有公布,所以我也只能注释到这么多。

8259部分的初始化,在

http://blog.csdn.net/lightseed/archive/2009/06/08/4250623.aspx

这一节里有详细的描述,我们可以对比这BIOS初始化8259的流程看看,两者是完全相同的。会不会有成就感?起码我当时看到这里的时候是很激动的,原来PIC就是这样被初始化的呀。

 

限于篇幅,在内存初始化之前的动作就先告一段落,下一节继续介绍在初始化内存之前,还有些其他的动作。

原创粉丝点击