5ÔÂ20ÈÕµÄISAÄ£¿éÔ´Âë £¡
;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;
; ISAÄ£¿éµÄÖ÷Ì岿·ÖÓÉÔ¶¾°ÂÛ̳µÄXBXCCÌṩ£¬ ;
; TABÌø¹ýÄ£¿é²¿·ÖÓÉÔ¶¾°ÂÛ̳µÄdkpnop Ìṩ£¬ ;
; A20Åжϲ¿·Ö²ÎÕÕ dkpnop µÄPCI Ä£¿é£¬ ;
; SLICÅжÏÐ޸IJ¿·ÖÓɱ¾ÈË - Ô¶¾°ÂÛ̳µÄzhaoliang ±àд£¬ ;
; ²¿·Ö´úÂë²ÎÕÕ dkpnop µÄPCI Ä£¿é¡£ ;
; ÓÉÓÚ±¾ÈËûѧ¹ý»ã±à£¬Èç·¢ÏÖÔ´´úÂëÓдíÎó£¬Ç뼰ʱָÕý £¡ ;
; ¸Ðл XBXCC ºÍ DKPNOP ¸øÁËÎҺܶà°ïÖú¡£ ;
;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;
use16 ; 16-bit by default
ROM_BLOCK = 2 ;block
ROM_SIZE = ROM_BLOCK * 512
SLIC_SIZE = 176h
RSD_PTR1 = 20445352h
RSD_PTR2 = 20525450h
FACP = 050434146h
SLIC = 043494c53h
FACS = 053434146h
XSDT = 054445358h
DSDT = 054445344h
SLICIN = 040000h + SLIC_DB
OEMIN = 040000h + SLIC_DB + 0ah
db 55h
db 0AAh
db ROM_BLOCK
call INIT ; jump to initialization
retf ; jump back to system BIOS
times (0x10-($ mod 0x10)) db 0
INIT:
pushad
push ds
push es
mov ah,1 ; Èç¹ûÉèÖà ah = 0 ,»áÍ£ÔÚ INT 16h ´¦£¬Ö±µ½¼üÅÌÊäÈë²ÅÄܼÌÐø
int 16h
cmp ah,0fh ; TAB = 0fh
je TABKEY ; Èç¹û¿ª»úÒ»Ö±°´×¡ TAB ¼ü£¬¿ÉÒÔÌø¹ýÖ÷³ÌÐòµÄÔËÐУ¬Ò»µ©ËÀ»úʱ¼´¿ÉÖØË¢BIOS
xor ecx,ecx ;ecxÓÃÀ´±£´æÅжÏA20µÄ״̬µÄÊý¾Ý
mov al,1
call setRealMode;enter bigrealmode
push ecx
call main
pop ecx
xor al,al
call setRealMode;leave bigrealmode
TABKEY:
pop es
pop ds
popad
retn ;return to this rom's header
enableA20:
in al,92h
test al,02h ;ÅжÏA20ÊÇ·ñÔÚÖ´ÐиÃÄ£¿éʱ¾ÍÒѾ±»¿ªÆôÁË
jne A20_BE_OPEN ;Èç¹ûÊÇ£¬¾ÍÌøµ½A20_BE_OPEN£¬ÉèÖÃCL=01H¡£
or al,02h
out 92h,al
retn
A20_BE_OPEN:
mov cl,01h
retn
disableA20:
cmp cl,01h
je disableA20_exit ;Èç¹ûA20ÔÚÖ´ÐиÃÄ£¿éʱ¾ÍÒѾ±»¿ªÆôÁË£¬¾Í²»¹Ø±ÕA20ÁË£¬·Àֹϵͳ³ö´í¡£
in al,92h
and al,0fdh
out 92h,al
disableA20_exit:
retn
setRealMode:
push eax
or al,al
je short offA20;
call enableA20
jmp enable4gb;
offA20:
call disableA20
enable4gb:
mov ax,cs
mov es,ax
lea di,[GDTR]
cli
db 26h,0Fh,01h,15h;lgdt es:[di];
mov eax,cr0
or al,1
mov cr0,eax;enter protected mode
jmp next1;clear CPU instruction queue
db 90h
next1:
pop eax
push eax
or al,al
je short to64k
mov ax,DATA4G_INDEX
jmp short enable4gbOK
to64k:
mov ax,DATA64K_INDEX
enable4gbOK:
mov es,ax
mov ds,ax
mov eax,cr0
and al,NOT 1
mov cr0,eax
jmp next2;clear CPU instruction queue
db 90h
next2:
xor ax,ax
mov ds,ax
mov es,ax;ds,es set to 4GB
pop eax
retn
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; Ö÷³ÌÐò¿ªÊ¼
main:
; ¿ªÊ¼Ñ°ÕÒ ¡°RSD PTR ¡±
mov esi, 0FFFD0h ; ´Ó 0FFFD0h ¿ªÊ¼µ¹ÕÒ£¬ÒòΪһ°ã¡°RSD PTR ¡±¶¼ÔÚ FF500h Ö®ºó£¬ÕâÑùÕÒËÙ¶È¿ì
CMP_RSDPTR:
cmp dword [esi], RSD_PTR1 ; Åжϡ°RSD ¡±
jne short NO_RSD
cmp dword [esi+4], RSD_PTR2 ; Åжϡ°PTR ¡±
je OK_RSDPTR ; ÕÒµ½¾Í½áÊø
NO_RSD:
sub esi,010h ; ÒòΪ¡°RSD PTR ¡±¶¼ÔÚ offset0 £¬ËùÒÔ - 10h µ¹ÕÒ
cmp esi,0E0000h ; ËÑË÷½ØÖ¹ÔÚ 0E0000h
jne CMP_RSDPTR ;
jmp MAIN_OUT ; ûÕÒ "RSD PTR " µ½¾ÍÍ˳ö
OK_RSDPTR:
; ÉÏÃæµÃµ½ ESI = "RSD PTR "ÄÚ´æµØÖ·
mov edi,[esi+10h] ; EDI = RSDTÄÚ´æµØÖ·
; Åжϡ°RSD PTR¡± µÄ 18h ´¦ ÊDz»ÊÇ XSDT , ÓÃÀ´Çø ACPI µÄ°æ±¾
xor ecx,ecx
mov esi,[esi+18h] ; AWARD bios ¶¨Òå XSDT ÔÚ ¡°RSD PTR¡± µÄ 18h ´¦
cmp dword [esi],XSDT ; ¿´ ¡°RSD PTR¡± µÄ 18h ´¦ ´æ·ÅµÄÄÚ´æµØÖ·ÊÇ·ñÖ¸ XSDT
jne FIND_LAST
mov ecx,esi
; ÉÏÃæµÃµ½ EDI = RSDTÄÚ´æµØÖ· , CX=0 ACPI1.0 , ECX = XSDTÄÚ´æµØÖ· ACPI2.0
; ÏÂÃæÅжÏÄǸö±íÊÇ×îºóµÄ±í , ͬʱÅжÏÊÇ·ñÔÉúSLIC
FIND_LAST:
mov esi,[edi+24h] ; esi = FACP±íÄÚ´æµØÖ·
mov esi,[esi+28h] ; esi = DSDT±íÄÚ´æµØÖ·
mov eax,[edi+4h]
NEXT_ACPI:
sub eax,4 ; eax = RSDT±í³¤ - 4
mov edx,[edi+eax]
cmp dword[edx],SLIC ; ÅжÏÊÇ·ñÊÇÔÉú SLIC ±í
jne N_SLIC ; ²»ÊÇ SLIC £¬Ìøµ½ÏÂÃæ±È½Ï´óС
;ÒòΪÓÐ "³¬¼¶¾²Ì¬·¨" µÄ´æÔÚ,ËùÒÔ¼ÓÅжÏ
cmp edx,0FFF00000h ; "³¬¼¶¾²Ì¬·¨" SLIC±íÄÚ´æµØÖ· > 0FFF00000h
ja KILL_SLIC
mov esi,edx
xor edx,edx ; ÔÉú SLIC ±í , dx = 0h
jmp SLIC_OK ; ÔÉú SLIC ±í ,Ö±½ÓÌøµ½ SLIC ±í´¦Àí´¦
KILL_SLIC:
mov [edi+eax],edi
jmp NEXT_ACPI ; "³¬¼¶¾²Ì¬·¨" Ìøµ½Ò»¸ö ACPI ±íÅжÏ
N_SLIC: ; ·ÇÔÉú SLIC £¬¼ÌÐøÅжÏ
cmp eax,24h ; 24h ÊÇRSDTÖдæ·ÅµÄµÚÒ»¸ö±íµÄÄÚ´æµØÖ·
je FIX_TEMP ; eax = 24h ¾ÍÌø
cmp esi,edx ;
ja NEXT_ACPI ; ´óÓÚ¾ÍÌøµ½ÏÂÒ»¸ö±íÅжÏ
LAST_ACPI:
mov esi,edx ; esi ±£³Ö×î´ó
jmp NEXT_ACPI ; ¼ÌÐøÅжÏ
; ÉÏÃæµÃµ½ esi = ×îºóÒ»¸ö±íµÄÄÚ´æµØÖ·,¼ÙÉèÊÇ XXXX »ò ÔÉúSLIC±íµÄÄÚ´æµØÖ·
; ÉÏÃæµÃµ½ dx = 0 ·ÇÔÉúSLIC , dx = 8888h ÔÉúSLIC
FIX_TEMP:
push ecx ; ±£´æ ecx = XSDT
push edx ; ±£´æ edx ,ÊÇ·ñÊÇÔÉú SLIC ±í
mov eax,[esi+4] ; eax = XXXX µÄ±í³¤
xor edx,edx ; edx ×îºÃÇåÁ㣬·ñÔòÈÝÒ׳ö´í
mov ecx,40h
push eax ; eax = XXXX µÄ±í³¤
div ecx ; ecx = 40h edx = ÕûÊý³ý·¨²úÉúµÄÓàÊý , eax = ÉÌ
pop eax ; eax = XXXX µÄ±í³¤
sub ecx,edx ; ecx = 40h - edx (ÕûÊý³ý·¨²úÉúµÄÓàÊý)
add eax,ecx ; eax = eax + ecx
add esi,eax ; esi ÔÚ XXXX ±í µÄºóÃæ
pop edx
pop ecx
; ÉÏÃæµÃµ½ esi = ·ÇÔÉúSLIC »ò ÔÉúSLIC ±íµÄÄÚ´æµØÖ·
; ÐÞ¸Ä RSDT ºÍ XSDT µÄ OEM ²¿·Ö
SLIC_OK:
; ÐÞ¸Ä RSDT µÄ OEM
call OEM_ID
CMP ch,0h ; CX=0 ACPI1.0 , ECX = XSDTÄÚ´æµØÖ· ACPI2.0
je OEM_OK
; ÐÞ¸Ä XSDT µÄ OEM
push edi ; ±£´æ EDI = RSDTÄÚ´æµØÖ·
mov edi,ecx ; ÏÂÃæµÄ CALL ΪÁËͨÓÃ,ʹÓÃÁË EDI ,ËùÒÔÏÈÉ趨 EDI ²ÅÐÐ
call OEM_ID ; ÐÞ¸Ä XSDT µÄ OEM
; ¼ÆËã XSDT µÄУÑé
call LOOP_CHECKSUM ; ¼ÆËã XSDT µÄУÑé
pop edi ; EDI = RSDTÄÚ´æµØÖ·
OEM_OK:
cmp dl,0 ; dx = 0 , ÔÉúSLIC
je SLIC_FIX
; ·ÇÔÉúSLIC,ÔÚRSDT±íºóд SLICµØÖ· , RSDT±í³¤+4
mov eax,[edi+4] ; EAX = RSDT±í³¤
mov [edi+eax],esi ; ÔÚRSDT±íºóд SLICµØÖ·
add dword [edi+4],4 ; RSDT±í³¤+4
CMP ch,0h ; CX=0 ACPI1.0 , ECX = XSDTÄÚ´æµØÖ· ACPI2.0
je SLIC_FIX
; ·ÇÔÉúSLIC,ÔÚXSDT±íºóд SLICµØÖ· , XSDT±í³¤+8
mov eax,[ecx+4] ; EAX = XSDT±í³¤
mov [ecx+eax],esi ; ÔÚXSDT±íºóд SLICµØÖ·
add dword [ecx+4],8 ; XSDT±í³¤+8
; ¼ÆËã XSDT µÄУÑé
push edi
mov edi,ecx
call LOOP_CHECKSUM
pop edi
; д SLIC ±í
SLIC_FIX:
; ¼ÆËã RSDT µÄУÑé
call LOOP_CHECKSUM
; д SLIC ±í
mov ecx,SLIC_SIZE
mov edi,esi
mov esi,SLICIN
rep movs byte [edi],byte [esi]
MAIN_OUT:
retn
OEM_ID:
push esi ; ±£´æ ESI = SLICÄÚ´æµØÖ·
push edi ; ±£´æ EDI = RSDTÄÚ´æµØÖ·, OR EDI = ECX = XSDT ÄÚ´æµØÖ·
push ecx ; ±£´æ ECX = XSDTÄÚ´æµØÖ·
mov ecx,0Eh ; ecx = 0Eh = 14 (OEMID+OEMTABLEID³¤¶È )
add edi,0ah ; edi = ±»Ð޸ıíµÄ OEMID+OEMTABLEID λÖÃ
mov esi,OEMIN ; Ä£¿éÔËÐеÄÄÚ´æÖÐ OEMID+OEMTABLEID ÔÚ SLIC ±í ÖеÄλÖÃ
rep movs byte [edi],byte [esi] ; ͬ²½¸´ÖÆ esi µÄÄÚÈÝ µ½ edi
pop ecx
pop edi
pop esi
retn
LOOP_CHECKSUM:
push esi
push ecx
xor ax,ax
mov [edi+9h],ah
mov ecx,[edi+4h]
push edi
LOOP_NEXT:
mov al,[edi]
inc edi
add ah,al
loop LOOP_NEXT
neg ah
pop edi
mov [edi+9h],ah
pop ecx
pop esi
retn
; Ö÷³ÌÐò½áÊø
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
GDTR:
dw 8*3;limit GDT length
dw GDT1;offset
dw 04h; in 0004h segment
times (0x10-($ mod 0x10)) db 0
GDT1:
dw 0;limit(bit0-15)
dw 0;base address(bit0-15)
db 0;hibase address(bit16-23)
db 0;access(attribute)
db 0;hilimit(bit16-19,20-23)
db 0;msbase address(bit24-31)
DATA64K: ; cs - prom code segment
DATA64K_INDEX = ((DATA64K - GDT1)/8) SHL 3
dw 0ffffh ; limit
dw 0 ; base
db 0 ; hibase
db 93h ; access
db 0 ; hilimit
db 0 ; msbase
DATA4G:
DATA4G_INDEX = ((DATA4G - GDT1)/8) SHL 3
dw 0ffffh ; limit
dw 0 ; base data segment points to
db 0 ; hibase ; 00000000
db 93h ; access
db 08fh ; hilimit (4GB)
db 0 ; msbase
times (ROM_SIZE-$-5-176h-5) db 0
SLIC_DB:
db 053h,04Ch,049h,043h,076h,001h,000h,000h,001h,04Bh,05Fh,041h,053h,055h,053h,05Fh,04Eh,06Fh,074h,065h,062h,06Fh,06Fh,06Bh,024h,006h,000h,011h,04Dh,053h,046h,054h,097h,000h,000h,000h,000h,000h,000h,000h,09Ch,000h,000h,000h,006h,002h,000h,000h,000h,024h,000h,000h,052h,053h,041h,031h,000h,004h,000h,000h,001h,000h,001h,000h,06Fh,092h,09Dh,0DCh,0B3h,079h,0EEh,027h,026h,008h,0F8h,0DCh,05Bh,0D8h,05Fh,04Bh,021h,034h,0ABh,060h,0ECh,090h,0C7h,0C2h,0D5h,060h,0D5h,0F5h,0D9h,082h,0F9h,02Eh,0BEh,0E8h,043h,038h,0D5h,0C2h,05Bh,09Eh,025h,0B8h,093h,0CDh,015h,0B8h,01Bh,0C3h,030h,07Dh,0ADh,055h,069h,079h,0BDh,01Ah,07Eh,044h,0C8h,0BCh,059h,05Ah,017h,0BEh,081h,0ADh,0EFh,0EEh,096h,021h,037h,0CCh,08Ah,042h,062h,0C6h,014h,005h,009h,021h,069h,07Ah,0E1h,08Ch,04Ah,0CEh,0D6h,0C8h,018h,078h,078h,086h,02Bh,030h,063h,0A6h,0E5h,064h,0B7h,0D2h,014h,05Eh,02Bh,044h,0BEh,033h,012h,06Bh,06Bh,0A3h,0BDh,09Eh,085h,0BBh,0BEh,06Ch,0E1h,0B1h,033h,0C2h,0DAh,091h,080h,0F3h,044h,0B4h,0CAh,09Fh,001h,000h,000h,000h,0B6h,000h,000h,000h,000h,000h,002h,000h,05Fh,041h,053h,055h,053h,05Fh,04Eh,06Fh,074h,065h,062h,06Fh,06Fh,06Bh,057h,049h,04Eh,044h,04Fh,057h,053h,020h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,024h,0B0h,089h,0CFh,0B1h,0F3h,01Dh,0B8h,07Ah,080h,035h,0CBh,0CDh,04Ah,0C8h,02Fh,084h,0CEh,099h,0A0h,04Fh,038h,076h,0B0h,004h,0F9h,06Fh,005h,033h,0C7h,0ECh,0A8h,058h,0A6h,0D7h,0B7h,03Fh,05Bh,082h,0B1h,0EEh,02Bh,0A7h,081h,052h,0F3h,045h,013h,0CEh,0EEh,0D5h,057h,037h,0FEh,075h,05Fh,05Ch,062h,0C4h,053h,0DAh,086h,0F1h,034h,0FAh,0EDh,091h,086h,073h,09Eh,0D2h,065h,0FDh,08Ah,03Dh,086h,094h,02Fh,02Ah,065h,018h,05Ch,0D9h,0E5h,07Ch,015h,01Eh,0F2h,008h,0C5h,085h,0C4h,08Fh,00Bh,0FAh,0A5h,0C3h,0A9h,0B0h,0F1h,0B2h,0E7h,06Ah,046h,0FBh,018h,001h,05Dh,04Ch,036h,033h,0DEh,0FBh,0E7h,01Dh,0E8h,015h,0C2h,085h,09Fh,08Ah,0A9h,032h,068h,01Fh,0B4h,0BCh,0A8h
db 0,0,0,0,0,06Dh,075h,079h,075h,00h
PREV_CHKSUM = 0
repeat $
load CHKSUM byte from %-1
CHKSUM = (PREV_CHKSUM + CHKSUM) mod 0x100
PREV_CHKSUM = CHKSUM
end repeat
store byte ((0x100-CHKSUM) mod 0x100) at ($-1) ; store the patch_byte
[ ±¾Ìû×îºóÓÉ zhaoliang ÓÚ 2007-5-21 20:07 ±à¼ ]
¸½¼þ: ÄúËùÔÚµÄÓû§×éÎÞ·¨ÏÂÔØ»ò²é¿´¸½¼þ