⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 add_slic.asm

📁 电子邮件推入
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	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 + -