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

📄 add_slic.asm

📁 电子邮件推入
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;                                       Vista Add-SLIC Module For AMI BIOS
;       功能:为了实现Microsoft Vista的免激活(OEM形式的激活),该模块给BIOS添加上相应的SLIC。只需要再使用对应Vista版本
;       的OEM版的KEY和对应SLIC中的品牌的证书,就可以实现Microsoft Vista的免激活。
;
;       使用方法:
;       1、用MMTOOL打开AMI BIOS以.ROM形式保存的文件,找到其中的ID=20的模块,释放这些模块,然后用WINHEX或者ULTRA 
;       EDIT打开这些模块,搜索“PXE”、“NETWORK”、“ETHERNET”等字符串,只要找到其中的一个,就可以确定这个模块是网卡
;       的BOOT ROM。在该模块的搜索“PCIR”,其后面的数据假设为YYXX BBAA形式,其中:
;       XXYY(注意都是倒写的)=VENDOR ID        AABB = DEVICE ID
;       将上面的值填写到下面的PCI_VENDOR_ID、PCI_DEVICE_ID处,然后编译成.bin文件。然后用MMTOOL的替换功能将该BIN文件替换
;       原来的网卡的BOOT ROM(一定要替换网卡的BOOT ROM)。
;       
;       2、将修改后的该.rom文件刷进主板的CMOS后,重新开机,按DEL、F1、F2或者其他键进入CMOS设置,在“BOOT”(或其他类似
;       的)菜单中,一定要将“ SLIC Mod”设置在“HARD DRIVE”的前面。按F10保存就可以了!
;       如果找不到“SLIC Mod”,如果有“LAN”之类的与网络有关的字样,把它设置在“HARD DRIVE”前面,还要修改“Integrated
;       Peripherals”(整合周边设备设定)中的“Onboard LAN Option ROM”设置为“Enabled”。
;
;       3、该模块也可以应用于AWARD,修改VENDOR ID、DEVICE ID后,直接执行cbrom xxx.rom /pci add_slic.mod就可以了。       
;       这样会直接替换掉原来的BOOT ROM。
;
;       4、如果启用了该模块后,会黑屏(不是那种刷了BIOS就黑屏的情况),这时,仅需要在CMOS设置中将该模块禁用就行了。
;
;       5、有些特殊的BIOS,即带有MINIT、GV3情况的BIOS,请检查原始的网卡的BOOT ROM是否在其后面,如果在后面,可以放心刷, 
;       如果不是,最好不要用。
;
;
;       注意:刷BIOS必然有风险,在使用该模块之时,使用者必须自行承担该风险,本模块的开发者不承担解决风险的责任。
;       声明:本模块开发者开拔该模块,是为了方便某些主板的用户给BIOS添加SLIC功能,并非是为了鼓励使用盗版!
;       如经济许可,请支持正版!
;
;       开发者:
;       核心技术                                XBXCC           @VistaFans      
;       SLIC添加功能实现[A M I]         dkpnop[nopworld]        @VistaFans
;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
use16  ; 16-bit by default
ROM_BLOCK = 03H  ;block
ROM_SIZE = ROM_BLOCK * 512
PCI_VENDOR_ID = 1011h	 ;VirtualPC=[VID= 1011 h, DID= 0009 h]  vmware(amd am79c970a)=[1022h,2000h]
PCI_DEVICE_ID = 0009h  ;
PCI_CLASS_CODE0 = 02h
PCI_CLASS_CODE1 = 00h
PCI_CLASS_CODE2 = 00h

pci_rom_header_start:
pci_rom_signature	dw 0AA55H		     ;Always equal to AA55h
pci_rom_init_size	db ROM_BLOCK		     ;Size in 512 byte blocks
;pci_rom_init_entry     dd ?                         ;JMP instruction (entry point for init)
			CALL INIT		     ;绝对不可以一个retf了事,不然,会在BIOS
			RETF			     ;的BOOT设置中看不到PnPIC_Prod_STR所代表的内容
pci_rom_reserved	db 11h dup (00h)
pci_rom_data_struc_ptr	dw  pci_rom_data_struc_start ;Offset of PCI ROM Data Structure
pci_rom_pnp_struc_ptr	dw  pci_pnp_inst_check_start ;offset of PCI ROM PnP Data Structure
;pci_rom_header_end
times (0x10-($ mod 0x10)) db 0

pci_rom_data_struc_start:
pcird_signature 	dd 'PCIR'		     ;Should equal to PCIR_SIGNATURE
pcird_vendid		dw PCI_VENDOR_ID	     ;PCI Vendor ID
pcird_devid		dw PCI_DEVICE_ID	     ;PCI Device ID
pcird_vpd_ptr		dw 0000h		     ;Pointer to Vital Product Data struc
pcird_struc_len 	dw 0018h		     ;Length of this structure (18h)
pcird_struc_rev 	db 00h			     ;Revision number of this structure (00)
pcird_base_type 	db PCI_CLASS_CODE0	     ;Class code - base type
pcird_sub_type		db PCI_CLASS_CODE1	     ;Class code - sub type
pcird_if_type		db PCI_CLASS_CODE2	     ;Class code - interface type
pcird_image_len 	dw ROM_BLOCK		     ;Length of this ROM image/512
pcird_code_rev		dw 0000h		     ;Vendor defined rev level of ROM code
pcird_code_type 	db 00h			     ;Type of code in image (see equ's below)
pcird_indicator 	db 80h			     ;Indocator flags (see equ's below)
pcird_reserved		dw 0000h
;pci_rom_data_struc_end
times (0x10-($ mod 0x10)) db 0

pci_pnp_inst_check_start:
PnPIC_Signature 	db '$PnP'
PnPIC_Revision		db 01h			      ;01=PCI 2.0
PnPIC_Length		db 02			      ;2*16h
PnPIC_ControlFlags	dw 0000h		      ;offset to next header (0 = none)
PnPIC_Reserved		db 00h			      ;reserved data
PnPIC_CheckSum		db 00h			      ;PnP structure checksum
PnPIC_Dev_Identifier	dd 00000000h		      ;device identifier
PnPIC_Manu_STR_Offset	dw PnPIC_Manu_STR	      ;pointer to manufacturer string
PnPIC_Prod_STR_Offset	dw PnPIC_Prod_STR	      ;pointer to productname string
PnPIC_Dev_Class_Code_0	db PCI_CLASS_CODE0	      ;Class code - base type
PnPIC_Dev_Class_Code_1	db PCI_CLASS_CODE1	      ;Class code - sub typ
PnPIC_Dev_Class_Code_2	db PCI_CLASS_CODE2	      ;Class code - interface type
PnPIC_Dev_Indicator	db 0e4h 		      ;device indicators (64h - shadowable,cacheable,not only for boot,IPL device)
PnPIC_Boot_Conn_Vector	dw 0000h		      ;boot connection vector (0-none)
PnPIC_Disconn_Vetor	dw 0000h		      ;disconnect vector (0-none)
PnPIC_Bootstrar_Vetor	dw BOOTSTRAP		      ;bootstrap entry vector (0-none)
PnPIC_Reserved_DATA	dw 0000h		      ;reserved data
PnPIC_Info_Vector	dw 0000h		      ;static resource info vector (0-none)
;pci_pnp_inst_check_end
;****************************************

PnPIC_Manu_STR DB "China",00h	     ;后面一定要加00h,这代表字符串结束!
PnPIC_Prod_STR DB "SLIC Mod",00h    ;在BIOS的BOOT设置中看到的字符串!


;****************************************
times (0x10-($ mod 0x10)) db 0
PREV_CHKSUM = 0
repeat 20H					      ;20H= Repeat count !
   load CHKSUM byte from pci_pnp_inst_check_start+%-1
   CHKSUM = (PREV_CHKSUM + CHKSUM) mod 0x100
  PREV_CHKSUM = CHKSUM
end repeat
store byte (0x100-CHKSUM) at (pci_pnp_inst_check_start+9h)

times (0x10-($ mod 0x10)) db 0
  INIT: 				;这时的CS是可以写数据的!因为BIOS解压各模块时,各模块都设置为可写状态!
	retn	

  BOOTSTRAP:				;这时的CS是绝对不可以写数据!必须另外想办法写!可以用堆栈!
	pushad				;必须使用BOOTSTRAP,是因为,ACPI很大程度上是在该PCI模块运行后,才生成的。
	push ds 			;经过多次的失败,证明了必须用BOOTSTRAP来解决!
	push es
	xor ecx,ecx
	mov al,1
	call setRealMode		;enter bigrealmode
	push ecx
	call main
	pop ecx
	xor al,al
	call setRealMode
	pop es
	pop ds
	popad
	retf				;return to this rom's header


;//////////////////////////////////////////////////////////////////////////////////////////

;//////////////////////////////////////////////////////////////////////////////////////////

   enableA20:
	in al,92h
	test al,02h
	jne A20_BE_OPEN
	or al,02h
	out 92h,al
	retn
A20_BE_OPEN:
	mov cl,01h
	retn


   disableA20:
	in al,92h
	cmp cl,01h
	je D_A20_EXIT
	and al,0fdh
	out 92h,al
D_A20_EXIT:
	retn

   setRealMode:
	push eax
	cli
	or al,al
	jz short offA20;
	call enableA20
	jmp enable4gb;
     offA20:
	call disableA20
     enable4gb:
	push ecx
;--------------------下面使用堆栈的方法因为部分AWARD主板的8800:AE00等区域是只读的,所以必须用回堆栈---------
	xor eax,eax
	xor ecx,ecx				;计算cs:GDT1的物理地址,用于LGDT
	mov ax,cs				;
	shl eax,4h				;
	mov cx,GDT1				;这里使用堆栈操作,可以不用考虑不可以改写伪GDTR的值的问题
	add eax,ecx
	push eax
	mov ax,GDT1_END-GDT1-1h
	push ax
	mov di,sp				;这里用堆栈来保存伪GDTR的值
	add sp,6h				;恢复原来的堆栈指针!6h = 伪GDTR的长度
	lgdt [ss:di]				;如果PC反复重启,绝大多数情况,是因为GDTR没有设置好。
;-----------------------------------------------------------------------------------------------------------
;       xor eax,eax
;       xor ecx,ecx                             
;       mov ax,08800h                           ;这里使用8800:AE00区域存放临时的伪GDTR
;       mov di,0ae00h                           ;8800:AE00这个数据来源于还原卡
;       push di                                 ;记得将DI进栈,以保留DI的指向。
;       mov es,ax                               ;
;       mov si,GDTR                             ;伪GDTR的格式需要在ASM后面事先写好,这样可以省一些处理代码
;       mov cx,06h
;       rep movs byte [di],[cs:si]
;       pop di                                  ;DI出栈
;       mov ax,cs                               ;
;       shl eax,4h                              ;
;       mov cx,GDT1                             
;       add eax,ecx                             ;这个EAX就是GDT1的物理地址
;       mov [es:di+2h],eax
;       lgdt [es:di]                            ;如果PC反复重启,绝大多数情况,是因为GDTR没有设置好。
;---------------------------------------------------------------------------------------------------------------
	mov eax,cr0				
	or al,1
	mov cr0,eax				;enter protected mode
	jmp pm_flush_queue
pm_flush_queue:
	pop ecx
	pop eax
	push eax
	push ecx
	or al,al
	jz short to64k
	mov ax,DATA4G_INDEX
	jmp short enable4gbOK
      to64k:
	mov ax,DATA64K_INDEX
     enable4gbOK:
	mov dl,al
	mov es,ax
	mov ds,ax
	mov eax,cr0
	and al,0feh
	mov cr0,eax
	jmp rm_flush_queue			;clear CPU instruction queue
rm_flush_queue:
	xor ax,ax
	mov dh,al
	mov ds,ax
	mov es,ax
	sti					;恢复中断
	pop ecx
	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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -