📄 add_slic.asm
字号:
je public_table_function_is_support_ACPI;如果为0,则表明该BIOS支持ACPI 2.0+,修改XSDT
jmp exit_public_table_function
public_table_function_is_support_ACPI:
mov [edx+4h],ebx
mov bl,4h
public_table_function_is_rsdt_table:
mov [edx],edi
add bl,4h
add [esi+4h],ebx
public_table_function_is_ori_bios:
call copy_oem_input_esi
call chksum_input_esi
exit_public_table_function:
pop edi
pop esi
retn
s_support_ACPI:
mov bl,[esi+0fh] ;比较RSD PTR的0FH偏移的数据是否小于2
cmp bl,02h ;如果小于2,表明不支持ACPI 2.0+
jl not_ACPI ;如果大于等于2,表明支持ACPI 2.0+
retn
not_ACPI:
add al,2h
retn
find_enough_slic_space:
push esi ;esi=rsd_ptr address !
xor ecx,ecx
xor edx,edx
xor edi,edi
mov esi,[esi+10h] ;esi=rsdt address
mov eax,[esi+4h]
sub ax,24h
mov cl,4h
div cx ;word division-->dx,ax /cx -->ax=quotient(shang),dx=residue(yu shu)
mov cx,ax
xor eax,eax
call find_largest_edi
jb found_is_ori_slic
mov esi,[esi+24h] ;esi=facp address
mov cx,2h
call find_largest_edi
found_is_ori_slic:
pushf ;*************************
mov ecx,[edi+4h]
lea edi,[edi+ecx+40h] ;找到地址最大的表后,将该地址加上该表的表长+40h,然后修正该地址的低4位为0
and di,0fff0h
popf ;*************************
cmc
pop esi
retn
find_largest_edi: ;destroy cx,edi,ebx,don't destroy esi,eax ! Input cx,esi,output edi !
push esi
mov edx, 43494c53h ;43494c53h='CILS'
lea ebx,[esi+24h]
loop_find_largest_edi:
mov esi,[ebx]
cmp [esi],edx ;test if esi point to slic address ! yes=is_ori_slic
je is_ori_slic
cmp esi,edi
jl next_find_largest_edi
xchg esi,edi
next_find_largest_edi:
add ebx,4h
loop loop_find_largest_edi
mov al,1h
clc
pop esi
retn
is_ori_slic:
mov edi,esi
xor al,al
stc
pop esi
retn
copy_slic_to_edi:
push eax
push esi
push edi
mov esi,SLIC
mov ecx,[cs:esi+4h]
rep movs byte [edi],byte [cs:esi]
pop edi
pop esi
pop eax
retn
copy_oem_input_esi:
push eax
push esi
push edi
mov edi,esi
add edi,0ah
mov esi,SLIC+0ah
xor ecx,ecx
mov cx,0eh
rep movs byte [edi],byte [cs:esi]
pop edi
pop esi
pop eax
retn
chksum_input_esi:
push eax
xor ax,ax
mov [esi+9h],ah
mov ecx,[esi+4h]
push esi
loop_checksum:
mov al,[esi]
inc esi
add ah,al
loop loop_checksum
neg ah
pop esi
mov [esi+9h],ah
pop eax
retn
S_RSD_PTR_:
mov ebx,0e0000h ; start
mov edx,0fffe0h ; end
clc
mov esi,edx
CMP_RSD_:
cmp dword [esi],20445352h ; serach "RSD "
jz short CMP_PTR_ ; if = jmp to cmp "RSD " + 4 = "PTR "
PUBLIC_S_RSD_PTR:
sub esi,10h
cmp esi,ebx
jge short CMP_RSD_ ; if < jmp to serach "RSD "
stc ; set jin wei biao zhi wei
retn ; not find
CMP_PTR_:
cmp dword [esi+4h],20525450h ; cmp "RSD " + 4 = "PTR "
jz short loc_DB ; = jmp
jmp PUBLIC_S_RSD_PTR
loc_DB:
clc ; clean jin wei biao zhi wei
retn
times (0x10*2-($ mod 0x10)) db 0
;/////////////////////////////////////////////////////////////////////////////////////////////////////////
;// memory model: segmentation.
;// create and load GDT.
;// two segments: code and data.
;//
;// segment registers descriptor table(GDT and LDT)
;// +----------------+ +--------------+-------+--------+
;// | Selector | -> | Base address | Limit | Access |
;// +----------------+ +--------------+-------+--------+
;//
;//
;// using DS register to select a descriptor from GDT.
;// segment registers descriptor table(GDT and LDT)
;// +----------------+ +--------------+-------+--------+
;// DS | Selector | -> | Base address | Limit | Access |
;// +----------------+ +--------------+-------+--------+
;// for example:
;// GDT
;// +------------------------+ +--------+ |... ...| FF,FF,FF
;// | | | offset | | |
;// | | +--------+ +--------------+ 10,00,FF
;// | | | | |
;// | | ⊕------->| Data segment |
;// +------+ +--+-----+-+--------+----+ | | |
;// DS | 0008 | -> |00| ... |0|10,00,00|00FF|(1) ----------->+--------------+ 10,00,00
;// +------+ +--+-----+-+--------+----+ | |
;// | null |(0) | |
;// +------------------------+ |... ...| 00,00,00
;// base address: 00,10,00,00
;// limit: 0,00FF
;// DS value = 0008, 0008>>3 = 0001, so the (1)-GD in GDT is selected.
;//
;// code and data segment descriptor (4 double word, each is 16 bits)
;// +---------------------------------------+-----+-----+-----+------+--------------+
;// | Base(31-24) |G(23)|D(22)|0(21)|AV(20)| Limit(19-16) |
;// +---------------------------------------+-----+-----+-----+------+--------------+
;// | Access rights(31-24) | Base(23-16) |
;// +---------------------------------------+---------------------------------------+
;// | Base(15-0) |
;// +-------------------------------------------------------------------------------+
;// | Limit(15-0) |
;// +-------------------------------------------------------------------------------+
;//
;// Access rights: (8 bits)
;// +-----+----------+-----+-----+--------+-------+-----+
;// |P(31)|DPL(30-29)|S(28)|E(27)|ED/C(26)|R/W(25)|A(24)|
;// +-----+----------+-----+-----+--------+-------+-----+
;// [bit 24] A = 0: Segment not accessed.
;// A = 1: Segment has been accessed.
;// [bit 25] R/W = 1: data may be written.
;// R/W = 0: data may not be written.
;// [bit 26] set it to 0. (非顺从性)
;// [bit 27] E = 0: descriptor describes a data segment.
;// E = 1: descriptor describes a code segment.
;// [bit 28] S = 0:system descriptor.
;// S = 1: code or segment descriptor.
;// [bit 29-30] DPL: sets the descriptor privilege level.
;// DPL = 00: the highest privilege level, used by OS.
;// DPL = 11: the lowest privilege level, used by application in user-mode.
;// [bit 31] P = 0: descriptor is undefined
;// P = 1: segment contains a valid base and limit
;
;/////////////////////////////////// hilimit ///////////////////////////////////////////////
;
; Sys Sgg G x 0 x 0
; Code Seg 1 1 C R A
; Data seg G B 1 0 E W A
; +-------------+-/-/-/-/--------+-/--/-/-------+------------+
; | | |D| |A|Seg-Lim | |D | | | |
; hilimit = | base 31:24 |G|/|0|V| |P| P|S| Type | Base 23:16 |
; | | |B| |L| 19:16 | |L | | | |
; +-------------+-\-\-\-\--------+-\--\-\-------+------------+
;
;
; AVL -- Available for use by system software
; BASE -- Segment base address
; D/B -- Default operation size (0 = 16-bit segment; 1 = 32-bit segment)
; DPL -- Descriptor privilege level (0-3)
; G -- Granularity (clear for byte unit of seg. limit, set for 4k unit)
; LIMIT-- Segment Limit
; P -- Segment present
; S -- Descriptor type (0 = system; 1 = code or data)
;
;///////////////////////////////////////////////////////////////////////////////////////////////////////////
GDTR:
dw GDT1_END-GDT1-1h;8*3-1;limit GDT length
dd 00000000h
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
dw 0ffffh ; limit
dw 00000h ; base
db 000h ; hibase
db 093h ; access
db 000h ; hilimit D/B Must set to 0 ,or error occur!
db 000h ; msbase
DATA4G:
DATA4G_INDEX = DATA4G - GDT1
dw 0ffffh ; limit
dw 00000h ; base data segment points to
db 000h ; hibase ; 00000000
db 093h ; access
db 08fh ; hilimit (4GB)
db 000h ; msbase
GDT1_END:
times (0x10*2-($ mod 0x10)) db 0
SLIC:
db 053h,04Ch,049h,043h,076h,001h,000h,000h,001h,0DAh,04Ch,045h,04Eh,04Fh,056h,04Fh,054h,043h,02Dh,030h,033h,020h,020h,020h,011h,007h,000h,001h,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,069h,016h,04Ah,09Fh,0B1h,04Bh,03Ah,0FBh,080h,020h,0AAh,0AFh,0C4h,0F9h,03Eh,0C1h,080h,049h,0EEh,06Ah,065h,026h,072h,01Eh,0CDh,0BFh,05Fh,02Fh,096h,0D6h,0C0h,00Ah,092h,0F5h,006h,0B5h,000h,0B2h,03Bh,029h,002h,0E2h,04Ch,08Dh,0C2h,0F2h,0BCh,041h,077h,09Ch,070h,0F0h,0F3h,01Bh,009h,0D2h,063h,05Ah,0DCh,0A8h,083h,0F8h,05Eh,0C9h,015h,095h,0F9h,0FAh,0FDh,0DCh,005h,0B7h,04Dh,067h,07Fh,02Dh,0B3h,084h,033h,020h,0E1h,0D1h,079h,02Ah,0A7h,06Ah,077h,0D1h,0B6h,020h,02Ah,076h,042h,0C5h,0D5h,0E9h,0B6h,043h,040h,055h,044h,0C3h,0C9h,037h,099h,05Fh,041h,097h,070h,0F3h,0D1h,0F6h,007h,0ECh,07Bh,01Ah,029h,0A1h,0C1h,0F1h,091h,0FDh,048h,086h,06Eh,03Eh,0CEh,0CBh,001h,000h,000h,000h,0B6h,000h,000h,000h,000h,000h,002h,000h,04Ch,045h,04Eh,04Fh,056h,04Fh,054h,043h,02Dh,030h,033h,020h,020h,020h,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,0ACh,090h,05Bh,0C2h,012h,014h,029h,05Ch,0FAh,092h,0D6h,0A5h,03Bh,015h,061h,0AEh,023h,0B6h,005h,094h,056h,0A5h,00Dh,0E3h,077h,061h,0B0h,01Ah,0D9h,0A8h,00Ch,072h,0F9h,0C2h,04Eh,045h,019h,066h,067h,00Ch,04Ch,06Ah,010h,0B4h,04Fh,066h,058h,017h,07Fh,07Bh,086h,0BEh,002h,072h,000h,01Ch,0DAh,044h,07Eh,08Ch,066h,028h,04Ch,01Ah,090h,026h,0D2h,044h,047h,0C2h,095h,004h,0FDh,0D5h,0F1h,064h,0D6h,0D3h,0B2h,0BEh,0A3h,0AAh,024h,0D4h,00Bh,042h,0F8h,094h,0F2h,0BFh,097h,027h,029h,04Dh,05Bh,06Dh,097h,06Ah,0E8h,01Ch,072h,02Ch,0ABh,036h,006h,05Ah,060h,037h,067h,002h,0C7h,003h,004h,0A2h,0C9h,020h,0A2h,068h,0A4h,0C5h,072h,030h,0E2h,005h,08Bh,0EBh,0A0h,0ECh
times (ROM_SIZE-$) db 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -