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

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

-- 基本的内存检测copy BIOS to RAM

By Lightseed

6/28/2010

1BIOS的主流程

BIOS执行到这里,bootblock任务基本完成。内存初始化好了以后,为了能够安全地把BIOS copy到内存中,还需要做一些安全性的检测呀什么的。让我们来继续往下看吧。

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

1 BIOS主流程

2Copy BIOS之前test基本内存

废话不用多说,让我们来看看反汇编出来的代码吧。

_F000:E3B5 ;Test first 256Kb memory , Send endless beep if DRAM is bad

_F000:E3B5

_F000:E3B5 loc_FE3B5: ; CODE XREF: _F000:E3E7j

_F000:E3B5 mov es, dx

_F000:E3B7 assume es:seg000

_F000:E3B7 cld

_F000:E3B8 mov cx, 2000h

_F000:E3BB xor di, di

_F000:E3BD repe stosd

_F000:E3C0 not eax

_F000:E3C3 mov cx, 2000h

_F000:E3C6 repe stosd

_F000:E3C9 not eax

_F000:E3CC mov cx, 2000h

_F000:E3CF xor di, di

_F000:E3D1 repe scasd

_F000:E3D4 jnz Error_Beep_Out

_F000:E3D6 not eax

_F000:E3D9 mov cx, 2000h

_F000:E3DC repe scasd

_F000:E3DF jnz Error_Beep_Out

_F000:E3E1 add dh, 10h

_F000:E3E4 cmp dh, 40h ; '@'

_F000:E3E7 jnz loc_FE3B5

_F000:E3E9 jmp short Ok_256K

_F000:E3EB ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:E3EB

_F000:E3EB Error_Beep_Out: ; CODE XREF: _F000:E3D4j

_F000:E3EB ; _F000:E3DFj ...

Call Sound_Speaker ;伪代码

;死循环,BIOS让自己死在这里,让beep一直响,因为最基本的内存检测出错了。

Ok_256K: ;到这里的话,说明基本的内存检测已经通过。

_F000:E439 cmp dword ptr [esi+0FFF5h], 'BRM*' ; Saginature of Compress

_F000:E445 jz Have_Find_compress_code

;Move entire BIOS from E0000-FFFFF to 10000-2FFFF

Call move_BIOS_code ;伪代码

_F000:E482 jmp far ptr 2000h:0E487h ; Here BIOS copy itself to RAM

_F000:E482 ; Althrough BIOS will use FAR JMP to run at 2000:0, but code is continuous.

_F000:E482 ; So we can go on disassembling in F0000

从上面的代码中,我们可以看到,BIOS会做一些其他的flag的处理。这没什么难度,看注释就好了。我主要是要说说关于那256KB基本内存的检测。原理很简单,就是向从0开始低端内存开始,往里面写入特殊的值,然后再读出来比对,从而来判断内存是否是存在的。如果不存在,那么在这里就会无限地beepout

3beepout子函数

关于beep的函数,其实在peterblog里面有很详细的阐述了,所以我在这里也就不多赘述。只是把反汇编出来的源码贴出来,让大家看看咱们的BIOS实际上是怎么写这这里的code的。很有参考价值哦。呵呵。。。

_F000:FBB8 Sound_Speaker proc near ; CODE XREF: _F000:E3F0j

_F000:FBB8 mov cx, 533h

_F000:FBBB mov al, 0B6h ; '?

_F000:FBBD ;----------------------------------------------------------------------

_F000:FBBD bit 7,6

_F000:FBBD 00 = Counter 0 select

_F000:FBBD 01 = Counter 1 select

_F000:FBBD 10 = Counter 2 select

_F000:FBBD 11 = Read Back Command

_F000:FBBD bit 5,4

_F000:FBBD 00 = Counter Latch Command

_F000:FBBD 01 = Read/Write Least Significant Byte (LSB)

_F000:FBBD 10 = Read/Write Most Significant Byte (MSB)

_F000:FBBD bit 3-1

_F000:FBBD 000b Mode 0 Out signal on end of count (=0)

_F000:FBBD 001b Mode 1 Hardware retriggerable one-shot

_F000:FBBD x10b Mode 2 Rate generator (divide by n counter)

_F000:FBBD x11b Mode 3 Square wave output

_F000:FBBD 100b Mode 4 Software triggered strobe

_F000:FBBD 101b Mode 5 Hardware triggered strobe

_F000:FBBD 11 = Read/Write LSB then MSB

_F000:FBBD bit 0

_F000:FBBD 0 = Binary countdown is used. The largest possible binary count is 216

_F000:FBBD 1 = Binary coded decimal (BCD) count is used. The largest possible BCD count is 104

_F000:FBBD

_F000:FBBD

_F000:FBBD B6H = select Counter 2, R/W MSB, mode 3, binary countdown is used.

_F000:FBBD ;----------------------------------------------------------------------

_F000:FBBD out 43h, al ; Timer Control Word Register

_F000:FBBF mov ax, cx ; CX = Initial value of timer 2

_F000:FBC1 out 0EBh, al

_F000:FBC3 out 42h, al ; Timer 8253-5 (AT: 8254.2).

_F000:FBC5 mov al, ah

_F000:FBC7 out 0EBh, al

_F000:FBC9 out 42h, al ; Timer 8253-5 (AT: 8254.2).

_F000:FBCB in al, 61h ; PC/XT PPI port B bits:

_F000:FBCB ; 0: Tmr 2 gate 退? OR 03H=spkr ON

_F000:FBCB ; 1: Tmr 2 data AND 0fcH=spkr OFF

_F000:FBCB ; 3: 1=read high switches

_F000:FBCB ; 4: 0=enable RAM parity checking

_F000:FBCB ; 5: 0=enable I/O channel check

_F000:FBCB ; 6: 0=hold keyboard clock low

_F000:FBCB ; 7: 0=enable kbrd

_F000:FBCD mov ah, al ; Save the data of 61h

_F000:FBCF or al, 3

_F000:FBD1 out 0EBh, al

_F000:FBD3 out 61h, al ; PC/XT PPI port B bits:

_F000:FBD3 ; 0: Tmr 2 gate 退? OR 03H=spkr ON

_F000:FBD3 ; 1: Tmr 2 data AND 0fcH=spkr OFF

_F000:FBD3 ; 3: 1=read high switches

_F000:FBD3 ; 4: 0=enable RAM parity checking

_F000:FBD3 ; 5: 0=enable I/O channel check

_F000:FBD3 ; 6: 0=hold keyboard clock low

_F000:FBD3 ; 7: 0=enable kbrd

_F000:FBD5

_F000:FBD5 loc_FFBD5: ; CODE XREF: Sound_Speaker+2Cj

_F000:FBD5 mov cx, 5000h ; Delay

_F000:FBD8

_F000:FBD8 loc_FFBD8: ; CODE XREF: Sound_Speaker+28j

_F000:FBD8 out 0EBh, al

_F000:FBDA out 0EBh, al

_F000:FBDC out 0EBh, al

_F000:FBDE out 0EBh, al

_F000:FBE0 loop loc_FFBD8

_F000:FBE2 dec bl

_F000:FBE4 jnz loc_FFBD5

_F000:FBE6 mov al, ah ; Restore the data of 61h

_F000:FBE8 out 61h, al ; PC/XT PPI port B bits:

_F000:FBE8 ; 0: Tmr 2 gate 退? OR 03H=spkr ON

_F000:FBE8 ; 1: Tmr 2 data AND 0fcH=spkr OFF

_F000:FBE8 ; 3: 1=read high switches

_F000:FBE8 ; 4: 0=enable RAM parity checking

_F000:FBE8 ; 5: 0=enable I/O channel check

_F000:FBE8 ; 6: 0=hold keyboard clock low

_F000:FBE8 ; 7: 0=enable kbrd

_F000:FBEA retn

_F000:FBEA Sound_Speaker endp

3BIOScopy

当内存检测完毕,一切准备就绪的时候,award bios就会准备把biosROMcopy到实际的RAM中来。当然在做这些之前还做了其他的动作,比如说操作timer呀什么的,看上面的代码就好,不赘述了。

_F000:E439这行开始,bios先去在F000段搜索是否有压缩的字样(当然肯定是有啦。)找到后,把BIOSROM里面copy出来,分别放到了10000-2FFFFHE000F000分别对应10002000)对应的RAM里面,同时也备份了一份到180000H-19FFFFH里面。然后用一个FAR jmp_F000:E482这行就可以看出来。)彻底让CPURAM里面取指令了。

不过,需要说明的是:虽然bios是被copy到了10002000段里来,也确实用了FAR jmp指令来跳转,但是由于此时BIOS ROM里面的源码和在10002000段里面的源码是一模一样的。所以,我们目前还是可以继续在当前的bin文件里面反汇编的哦。所以我们可以假设目前的BIOS源码就是在2000(对应到了F000)段里了。这里的思维转换一定要转换过来!!因为后面还有难度更大的转换。

4、小结

这个章节里面主要和大家讨论了BIOS把自身从ROM里面copyRAM里面的过程。也说明了,为什么我们还要继续用当前的bin文件来反汇编。