📄 multi-add-slic.asm
字号:
pop eax
push eax
or al,al
jz 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,0feh ;将cr0的0位设置为0,就退出了保护模式
mov cr0,eax ;退出保护模式,进入实模式
jmp rm_flush_queue ;clear CPU instruction queue
rm_flush_queue:
xor ax,ax
mov ds,ax
mov es,ax
sti ;恢复中断
pop eax
retn
main:
call S_RSD_PTR_
jb UNdo_1 ;if < jmp to undo
call find_enough_slic_space ;al的定义:将AL转换成2进制,如: 10H(00010000),aXY这里设置为标志位
jb not_ori_slic ;x=(0,支持ACPI规范[2.0+];1,不支持) a xy
call public_function ;y=(0,原生BIOS;1,非原生BIOS)
UNdo_1:
retn
not_ori_slic:
call s_support_ACPI
call public_function
Undo_2:
retn
public_function:
call copy_slic_to_edi
add al,10h ;保留AL的标志位,+10=带标志位的RSDT地址在RSD PTR中的偏移
call public_table_function
add al,8h ;保留AL的标志位,+10=带标志位的xsdt地址在RSD PTR中的偏移
call public_table_function
retn
public_table_function:
push esi
push edi
movzx ebx,al ;将AL扩展成32位的EBX,变成000000AL
and bl,18h ;清除BL的标志位,即还原成真正的偏移
mov esi,[esi+ebx] ;esi = rsdt_address or xsdt_address !
test al,1h ;检查AL中的Y是否为0
je public_table_function_is_ori_bios ;如果为0,则表明该BIOS是原生的,原生BIOS肯定支持ACPI 2.0+
mov ecx,[esi+4h]
xor ebx,ebx
lea edx,[esi+ecx]
test al,8h ;检查AL中的a是否为0(18H=0001 1000)(0001a0xy)
je public_table_function_is_rsdt_table ;如果为0,则表明调用的AL=带标志位的rsdt地址在RSD PTR中的偏移
test al,2h ;检查AL中的x是否为0
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
call read_hd_data
mov esi,SLIC
add esi,eax
mov ecx,[cs:esi+4h]
rep movs byte [edi],byte [cs:esi]
pop edi
mov esi,edi
call chksum_input_esi
pop esi
pop eax
retn
read_hd_data:
push edx
mov dh,2h
call RW_HD_DATA
and al,0fh
movzx eax,al
mov dx,180h
mul dx
shl edx,10h
add eax,edx
pop edx
retn
copy_oem_input_esi:
push eax
push esi
push edi
mov edi,esi
add edi,0ah
call read_hd_data
mov esi,SLIC+0ah
add esi,eax
xor ecx,ecx
mov cx,0eh
rep movs byte [edi],byte [cs:esi]
pop edi
pop esi
pop eax
retn
chksum_input_esi: ;修正ESI所指向的表的校验值
push eax ;入口:esi ; 出口:无
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -