『第
2 楼』:
[原创]检索PCI 2.0设备HWID
我在无忧发表过一个在DOS,依据硬件库匹配PCI设备驱动的程序,硬件库可以后来定制(建议link /tiny生成.com文件,酱紫可以直接用UE把硬件库插到HWDBSTART:后面),每条硬件记录以$分割,硬件库以ASC(FF)为结束,硬件hwid和xp一致。方法和楼主差不多(其实Func num通常在r/w数据的时候用,一般检测不考虑,还是让所有设备都显示为佳,事实上windows也是酱紫的,有多个内存控制器、OHCIUSB或UHCIUSB控制器,另外不同版本号有不兼容的情况不应被忽略)。所以顺便把源码贴上(为了方便他人,已删除未匹配硬件的显示)。最近正在研究ACPI,发现不懂的东西太多了,想抄都没得抄@_@。
**采用读一条PCI硬件匹配一次方法,主要考虑,当透过桥接长时间读取(BusNum不为0通常就是通过桥接片)有可能会导致其他任务被堵塞,还有pcicfg对齐4的倍数就是防止内存访问被掰成两个甚至四个内存访问周期,国内目前的读取pcicfg程序大多有BUG**
;文件名:CHKPCI.ASM
;作者:netwinxp
;免责任声明:CHKPCI是个开放源码的自由软件,注意事项请参照http://www.gnu.org/licenses/
; 本人不对使用或修改该软件而可能导致的任何问题负责(即使事先被告知)。
;编译环境:masm6.11
;使用平台:DOS
.model tiny
.386
code segment
assume cs:code,ds:code,es:code
org 100H
START: mov ax,cs
mov ds,ax
mov es,ax
mov ax,0B101H;支持PCI 2.0?
int 1AH
jc PCIERR;否
cmp ah,0
jne PCIERR;否
cmp edx,' ICP'
jne PCIERR;否
;========读取PCI配置空间数据
mov ecx,7FFFFF00H
READPCI:add ecx,100H
cmp ecx,80FFFF00H;全读完了?
jnb EXIT;是
mov dx,0CF8H
mov eax,ecx
cli
out dx,eax
mov dx,0CFCH
in eax,dx
sti
cmp eax,0FFFFFFFFH;无效设备?
je READPCI;是
push ecx
mov di,offset venid
cld
PCISTR: mov eax,ecx
mov dx,0CF8H
cli
out dx,eax
mov dx,0CFCH
insd
sti
add cl,4
cmp cl,0FCH;读完256字节数据?
jb PCISTR;否
;=======查找匹配的记录
mov bx,offset hwdb
L0: xor di,di;指向新记录首字节
mov chkok,di;匹配标志清零
L1: mov al,[bx][di]
cmp al,0FFH;读完所有记录?
je UNKNOW;是
mov dx,chkok
cmp al,'$';本记录尾部?
jne L3;否
cmp dx,1;该记录匹配?
je DISP;是
L2: inc di
add bx,di;bx指向下一记录
jmp L0
L3: cmp dx,0FFFFH;本记录不匹配?
jne L5;否。是的话直到下一条记录之前不再进行匹配尝试
L4: inc di
jmp L1
L5: cmp al,'_';有可能是硬件信息?
jne L4;否
mov eax,[bx][di-3]
cmp eax,'_NEV';后面的是VEN信息?
je CHKVEN
cmp eax,'_VED';后面的是DEV信息?
je CHKDEV
cmp eax,'_SYS';后面的是SUBSYS信息?
je CHKSUB
cmp eax,'_VER';后面的是REV信息?
je CHKREV
and eax,0FFFFFF00H
cmp eax,5F434300H;高三位为'_CC';后面的是CLASS信息?
jne L4;都不是
CHKCC: mov eax,[bx][di+1]
call asctohex
mov cx,classid
cmp ax,cx
jz L12
jmp L11
CHKVEN: mov eax,[bx][di+1]
call asctohex
mov cx,venid
cmp ax,cx;与检测到的venid比较
jz L12
jmp L11
CHKDEV: mov eax,[bx][di+1]
call asctohex
mov cx,devid
cmp ax,cx;与检测到的devid比较
jz L12
jmp L11
CHKSUB: mov eax,[bx][di+5]
call asctohex
push di
mov di,offset subsys
mov cx,[di]
pop di
cmp ax,cx;与检测到的subdid比较
jnz L11
mov eax,[bx][di+1]
call asctohex
push di
mov di,offset subsys
mov cx,[di+2]
pop di
cmp ax,cx;与检测到的subvid比较
jnz L11
jmp L12
CHKREV: mov eax,30303030H;为了兼容子过程的处理
mov ax,[bx][di+1]
call asctohex
mov cl,revid
cmp ah,cl;与检测到的rid比较
jz L12
L11: mov dx,0FFFFH
mov chkok,dx;填充不匹配标志
jmp L4
L12: mov dx,1;填充匹配标志
mov chkok,dx
jmp L4
DISP: mov dx,bx
mov ah,9;主要方便输出转向。否则的话稍作修改可以脱离DOS运行。
int 21H
UNKNOW: pop ecx;跳过未匹配设备
jmp READPCI
PCIERR: mov ax,4C01H;非PCI2.0以上版本返回ERRORLEVEL=1
int 21H
EXIT: mov ax,4C00H
int 21H
;把eax的四字节HEX字符串转换成ax数据
asctohex proc near;会破坏edx、ecx、eax内容
;输入:eax待转换值
;返回:ax
push bx
mov cx,4
mov edx,eax
xor eax,eax
S11: mov bl,dl
cmp bl,'9';不做更多判断请务必保证待匹配字串由'0-9、A-F、a-f'组成
jbe S12
and bl,0DFH;转大写字母
sub bl,7
S12: and bl,0FH
shl ax,4
add al,bl
shr edx,8
loop S11
pop bx
ret
asctohex endp
; db 'XXX';用来使后面对齐4的倍数
venid dw 0;pcicfg offset 00H
devid dw 0;pcicfg offset 02H
command_reg dw 0
status_reg dw 0
revid db 0;pcicfg offset 08H
progif db 0;pcicfg offset 09H
classid dw 0;pcicfg offset 0AH
cacheline_size db 0
latency db 0
headtype db 0;pcicfg offset 0EH,=00时SUBSYS有效
bist db 0
baseaddr0 dd 0
baseaddr1 dd 0
baseaddr2 dd 0
baseaddr3 dd 0
baseaddr4 dd 0
baseaddr5 dd 0
cardbus_cis dd 0
subsys dd 0;pcicfg offset 2CH
expansion_ROM dd 0
cap_ptr db 0
reserved1 db 3 dup(0)
reserved2 dd 0
interrupt_line db 0
interrupt_pin db 0
min_grant db 0
max_latency db 0
specific db 192 dup(0)
chkok dw 0;匹配判定标志
hwdbstart db 'HWDBSTART:'
hwdb db 16 dup(' ')
hwdbend db 0FFH
code ends
end START 下面是nforce3-250和mcp51磁盘硬件库示范:
Quote: | PCI\VEN_10DE&DEV_00E5="pciide";CK8S PATA
$GenNvRaidDisk="nvraid"
*_NVRAIDBUS="nvraid"
PCI\VEN_10DE&DEV_00E3="nvatabus";CK8S SATA
$GenNvRaidDisk="nvraid"
*_NVRAIDBUS="nvraid"
PCI\VEN_10DE&DEV_00EE="nvatabus";CK8S SATA
$PCI\VEN_10DE&DEV_0265="pciide";MCP51 PATA
$SCSI\NVIDIA__Raid_Disk________="nvrd32"
SCSI\__NVIDIA_______Raid_Disk="nvrd32"
SCSI\NVIDIA__Raid_Disk_20_____="nvrd32"
SCSI\__NVIDIA____Raid_Disk_20="nvrd32"
*NVRAID20="nvrd32"
*NVRAIDBUS="nvraid32"
*_NVRAIDBUS="nvraid32"
GenNvRaidDisk="nvraid32"
PCI\VEN_10DE&DEV_0266="nvgts";MCP51 SATA
$SCSI\NVIDIA__Raid_Disk________="nvrd32"
SCSI\__NVIDIA_______Raid_Disk="nvrd32"
SCSI\NVIDIA__Raid_Disk_20_____="nvrd32"
SCSI\__NVIDIA____Raid_Disk_20="nvrd32"
*NVRAID20="nvrd32"
*NVRAIDBUS="nvraid32"
*_NVRAIDBUS="nvraid32"
GenNvRaidDisk="nvraid32"
PCI\VEN_10DE&DEV_0267="nvgts";MCP51 SATA
$ |
|
[ Last edited by netwinxp on 2008-5-11 at 02:10 PM ]
|