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

BIOS启动与内存检测
本文详细解析了BIOS启动过程中的基本内存检测方法及BIOS自我复制到RAM中的实现细节。

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

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

By Lightseed

6/28/2010

1BIOS的主流程

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

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文件来反汇编。

代码部分来自Google的重建IBMPC BIOS项目(https://sites.google.com/site/pcdosretro/ibmpcbios),其中的BIOS镜像(*.rom)可用于各种IBM PC模拟器,可按情况使用。源代码可以用masm编译,站内英文说明文件如下: IBM PC BIOS source code reconstruction This is a reconstruction of the IBM PC, PC XT, PC AT and PC XT 286 BIOS source code using scanning and transcription of the BIOS listings found in the IBM Technical Reference manuals. This historically relevant source code is presented here for software preservation. The following BIOS source code has been reconstructed: IBM PC version 1 04/21/81 IBM PC version 2 10/19/81 IBM PC version 3 10/27/82 IBM PC XT version 1 11/08/82 (also used on the Portable PC) IBM PC XT version 2 01/10/86 IBM PC XT version 3 05/09/86 IBM PC AT version 1 01/10/84 IBM PC AT version 2 06/10/85 IBM PC AT version 3 11/15/85 (used on the PC AT models 319 and 339) IBM PC XT 286 04/21/86 Notes: • All 3 versions of the IBM PC BIOS and the first version of the IBM PC XT BIOS were built using Intel ASM86 on an Intel development system. In each case the BIOS source code is a single large file and the BIOS code is 8KB which resides at F000:E000 • The IBM PC AT version 1 BIOS was built using IBM MASM 1.0 on DOS. This is the first IBM BIOS which uses multiple source files. Since IBM MASM 1.0 did not support the 80286 there is a macro file (IAPX286.MAC) which is used to generate the necessary opcodes. This is also the first BIOS to be split into two parts: the main BIOS code resides at F000:0000 and the compatibility section (ORGS.ASM) resides at F000:E000. An additional file FILL.ASM has been added to define the area between the end of the main BIOS code and the compatibility section to allow the BIOS to be linked properly. It is currently unknown how this was originally handled. • The IBM PC AT version 2 and 3 BIOS and the IBM PC XT 286 BIOS were built using IBM MASM 2.0 on DOS. These are similar to the PC AT version 1 BIOS but there are fewer source files as some files were combined and a bit of cleanup was done. IAPX286.INC is used to generate the protected-mode 80286 opcodes which IBM MASM 2.0 did not support. FILL.ASM serves the same purpose as it does for the PC AT version 1 BIOS though in each case the file is specific to the particular BIOS being built. • The IBM PC XT version 2 and 3 BIOS were built using IBM MASM 2.0 on DOS. The later PC XT BIOS code was restructured to be similar to the PC AT BIOS code so there are multiple source files. Like the PC AT BIOS the code is split into two parts though the compatibility section is in the file POST.ASM. Again the additional file FILL.ASM is used to define the area between the end of the main BIOS code and the compatibility section. • The following code is present in all versions of the PC AT BIOS and the PC XT 286 BIOS but does not appear in the published listings. It is inferred from the public symbols in ORGS.ASM and code disassembly. It is unknown what purpose this code serves. .XLIST ;;- ORG 0FF5AH ORG 01F5AH HRD PROC FAR CALL DISK_SETUP RET HRD ENDP FLOPPY PROC FAR CALL DSKETTE_SETUP RET FLOPPY ENDP SEEKS_1 PROC FAR CALL SEEK RET SEEKS_1 ENDP TUTOR: JMP K16 .LIST • In all cases the 32KB ROM BASIC code which resides at F6000 is not available as its source code was never published. • Versions of MASM later than 4.0 cannot be used to build the IBM BIOS source code since older constructs and macros are used. More information about functionality changes in the IBM PC BIOS code is listed here: IBM PC BIOS version history
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值