【我所认知的BIOS】->反汇编BIOS之Bootblock(4)
--initialize Super IO
By Lightseed
5/13/2010
到目前为止,我们已经看了两个重要的函数了,也是BIOS的必经之路。如下面的代码片段,BT_CPU_Init和Chipset_Reg_Init_Early我们都详细探讨过,那么随着流程下去,就是讨论SuperIO_INIT这个函数了。
到目前为止,我们的BIOS主流程如图1所示,
图1 BIOS主流程
那么今天就和大家详细来看看SuperIO_INIT这个函数都做了什么。BIOS究竟是怎么来初始化我们听的耳朵都起茧了的一个芯片——super IO。
废话就不多说了,让我们来看看code吧,这样一下子就明了了。
_F000:E274 mov ax, cs:[si]
_F000:E277 mov dx, 2Eh ; '.' ; Superio_Config_Port
_F000:E27A out dx, al
_F000:E27B out 0EBh, al
_F000:E27D xchg ah, al
_F000:E27F inc dx
_F000:E280 out dx, al ; out to SIO's configuration register
_F000:E281 add si, 2
_F000:E284 out 0EBh, al ; delay
_F000:E286 loop loc_FE274
这是SuperIO_INIT的主函数。不难发现其实中间的逻辑很简单,与之前初始化chipset的逻辑差不多,只是操作稍微有点点区别。对于上面这个函数,大部分看注释应该就能懂了,我只想单独说明一点。对于初学者而言,可能会问:
_F000:E268 mov al, 87h ; '?
_F000:E26A out dx, al
_F000:E26B nop
_F000:E26C nop
_F000:E26D out dx, al ; Enter SIO configurating mode
为什么上面要有两次的把87H送到DX的port上去。我的回答是,这是由super IO的芯片决定的。在super io的datasheet里面有说明,只有两次向super IO的固定端口写入entry key才能使得该super IO进入到配置模式,从而初始化它的寄存器。在datasheet的第九章有说明。在
http://blog.csdn.net/lightseed/archive/2009/09/02/4512464.aspx
这个章节里也有详细的论述。(再次提醒一下,blog里面的之前的那些文章都是基础,所以比较杂乱一点,但是在我们反汇编BIOS的阶段全部都会用上的。呵呵。。。如果您对反汇编BIOS还是有点兴趣的话,到是可以回头再温习一下我blog里面的其他文章。)
继续追踪,在
_F000:E26E mov si, 0E210h ; Source data pointor
这一行里面,我们可以看到把super io的初始化table的偏移给了SI,后续通过对SI的调整来做的动作。那么我们来看看0E210h这个地方都存了什么样的数据。
_F000:E210 ;---------------------------------------------------
_F000:E210 Global confaguration register initial start
_F000:E210 Low byte is configuration register
_F000:E210 High byte is the value will be configurated
_F000:E210 ;---------------------------------------------------
_F000:E210 Superio_Init_Tbl db 24h ; $ ; Chip(Global)Control Register 24h
_F000:E211 db 0C4h ; ? ; 16 bit Address Qualification
_F000:E211 ; Clock is 48 Mhz
_F000:E211 ; KBC is enabled after hardware reset.
_F000:E211 ;
_F000:E212 db 29h ; ) ; CR 29H
_F000:E213 db 0 ; ; All GPIO multiplexed pin not be selected gpio
_F000:E213 ;
_F000:E214 db 2Ah ; * ; CR 2AH
_F000:E215 db 7Ch ; | ; PIN 124~128 are selected GPIO
_F000:E215 ;
_F000:E216 db 2Bh ; + ; CR 2BH
_F000:E217 db 0C0h ; ? ; PIN 91,92 are selected GPIO
_F000:E217 ;
_F000:E218 db 2Ch ; , ; CR 2CH
_F000:E219 db 3 ; ; winbond Reserved
_F000:E219 ;
_F000:E219 ;
_F000:E21A ;---------------------------------------------------
_F000:E21A Global confaguration register end
_F000:E21A ;---------------------------------------------------
_F000:E21A db 7 ;
_F000:E21B db 0 ; ; Select device 0 FDC
_F000:E21B ;
_F000:E21C db 30h ; 0
_F000:E21D db 1 ; ; set the FDC active
_F000:E21D ;
_F000:E21E db 0F0h ; ?
_F000:E21F db 0Eh ; ; Defualt value is 0EH, BIT 1 FDC DMA Mode is enabled
_F000:E21F ;
_F000:E220 db 7 ;
_F000:E221 db 1 ; ; Select device 1 Parallel Port
_F000:E221 ;
_F000:E222 db 30h ; 0
_F000:E223 db 1 ; ; Set Parallel Port active
_F000:E223 ;
_F000:E224 db 7 ;
_F000:E225 db 5 ; ; Select device 1 KBC
_F000:E225 ;
_F000:E226 db 30h ; 0
_F000:E227 db 1 ; ; set the KBC active
_F000:E227 ;
_F000:E228 db 60h ; `
_F000:E229 db 0 ;
_F000:E22A db 61h ; a
_F000:E22B db 60h ; ` ; The first KBC io base is 60h
_F000:E22B ;
_F000:E22C db 62h ; b
_F000:E22D db 0 ;
_F000:E22E db 63h ; c
_F000:E22F db 64h ; d ; The second KBC io base is 64h
_F000:E22F ;
_F000:E230 db 70h ; p
_F000:E231 db 1 ; ; default valve is 01h
_F000:E231 ;
_F000:E232 db 72h ; r
_F000:E233 db 0Ch ; ; default value is 0ch
_F000:E233 ;
_F000:E234 db 0F0h ; ?
_F000:E235 db 80h ; € ; KBC input clock is 12Mhz
_F000:E235 ; Port 92h is disabled
_F000:E235 ; Gate20 software control
_F000:E235 ; Kbrst software control
_F000:E236 db 7 ;
_F000:E237 db 7 ; ; Select device 7 game port
_F000:E237 ;
_F000:E238 db 30h ; 0
_F000:E239 db 1 ; ; set the game port active
_F000:E239 ;
_F000:E23A db 60h ; `
_F000:E23B db 0 ;
_F000:E23C db 61h ; a
_F000:E23D db 0 ; ; game port io base is 0h
_F000:E23D ;
_F000:E23E db 62h ; b
_F000:E23F db 0 ;
_F000:E240 db 63h ; c
_F000:E241 db 0 ; ; MINI port io base is 0h
_F000:E241 ;
_F000:E242 db 70h ; p
_F000:E243 db 0 ; ;
_F000:E243 ;
_F000:E244 db 7 ;
_F000:E245 db 8 ; ; Select device 8 GPIO Port 2 and Watch Dog Timer
_F000:E245 ;
_F000:E246 db 7 ;
_F000:E247 db 9 ; ; Select device 9 GPIO Port 3
_F000:E247 ;
_F000:E248 db 30h ; 0
_F000:E249 db 1 ; ; set the device active
_F000:E249 ;
_F000:E24A db 60h ; `
_F000:E24B db 8 ;
_F000:E24C db 61h ; a
_F000:E24D db 0 ; ; winbond datasheet do not release
_F000:E24D ;
_F000:E24E db 0F3h ; ?
_F000:E24F db 0 ; ; Suspend LED pin is drived low
_F000:E24F ;
_F000:E250 db 7 ;
_F000:E251 db 0Bh ; ; Select device B hw Monitor
_F000:E251 ;
_F000:E252 db 30h ; 0
_F000:E253 db 1 ; ; set the HW monitor active
_F000:E253 ;
_F000:E254 db 60h ; `
_F000:E255 db 2 ;
_F000:E256 db 61h ; a
_F000:E257 db 90h ; ? ; HW monitor io base address is 902h
_F000:E257 ;
_F000:E258 db 7 ;
_F000:E259 db 0Ah ; ; Select device A ACPI controller
_F000:E259 ;
_F000:E25A db 0E6h ; ?
_F000:E25B db 40h ; @ ; Clear CASEOPEN#(Pin 76)event (HF only)
_F000:E25B ;
_F000:E25C db 0E6h ; ?
_F000:E25D db 0 ;
我觉得对上面的这个table的注释应该是很详细了,如果您在看的过程中还有不明白的,那么我们再深入探讨。
Super IO在整个计算的架构上还是扮演着比较重要的角色。比如KBC经常会在这里出问题,HW monitor的实时读取,GPIO的操作,ACPI controller的中断等等一些问题都是很有研究价值,也很有趣的问题。单纯从BIOS的角度上讲,那么super io的简单的早期的初始化就差不多结束了,让我们继续期待BIOS的下一步动作吧。