-
-
查看PCI设备配置空间
-
发表于: 2011-10-30 21:29 6927
-
用I/O命令可以访问PCI总线设备配置空间,具体使用的端口号为CF8和CFC,所用的指令就是in和out.
编程的一些注意点:
1.因为CF8和CFC大于FF,所以不能直接写以下指令 包括in out
asm
out $CF8,eax
end;
应该将端口号赋值dx,然后
asm
mov dx,$CF8
out dx,eax
end;
2.调用内嵌汇编的时候有时会出现莫明奇妙的错误。有时并不是代码的问题。
3.in out 端口需要有特权。只好写驱动程序来完成此任务。
先来理解一下PCI配置空间
PCI配置空间是用来存放设备必要数据的地方,我的理解是系统(1个)它里面包含了总线,而总线里面包括了设备,设备又包括了功能,而每一个功能它所占的空间是256字节(0-$FF)
那么一个系统里面又包含多少个总线啊?根据送往CF8端口的那个地址的结构来看(这个下面介绍),一个系统最多可以包括256个总线(0-$FF),一个总线又最多可以包括32个设备(0-$1F),一个设备最多可以包括8个功能(0-$7)。
所以我们要做一个查看PCI设备配置空间工具,需要搜寻上面所有地址。
for n1:=0 to $FF do //系统内所有的总线
for n2:=0 to $1F do //总线内所有的设备
for n3:=0 to $7 do //设备内所有的功能
for n4:=0 to $FF do //功能空间内所有的字节
理解完宏观的东西,现在理解微观的。那么我要访问一个功能上的一个字节该怎么做啊?
用I/O命令可以办到
CF8称为地址配置端口,只要往这个端口送一个32位(4字节)的数据(这个数据包含了总线,设备,功能,空间字节的信息),然后到CFC端口就可以读出我们想要的内容(32位)(4字节)。
送往CF8的数据的结构:
这个DOWRD的第31位必须为1,24-30位因为保留无功能的关系为0,16-23位代表总线号(0-$FF),11-15位代表设备号(0-$1F),8-10位代表功能号(0-$7),2-7位代表要访问空间的位置(0-$3F).0-1位恒定为0.
解释一下2-7位代表要访问的空间的位置,为什么是0-$3F呢,因为0-$3F即是0-63即64个位置,因为每一个位置都会导致CFC端口返回一个4字节数据,64*4=256字节,刚好是一个功能的配置空间
举个例子说明一下:
比如我想知道总线号为0,设备号为0,功能号为0的设备的配置空间上,256个字节当中第0-3字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000000 00000 000 000000 00 = $80000000
又例如我想知道总线号为0,设备号为0,功能号为0的设备的配置空间上,256个字节当中第4-7字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000000 00000 000 000001 00 = $80000004
那么8-11字节呢?
1 0000000 00000000 00000 000 000010 00 = $80000008
例如我想知道总线号为1,设备号为0,功能号为0的设备的配置空间上,256个字节当中第0-3字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000001 00000 000 000000 00 = $80010000
再例如我想知道总线号为1,设备号为2,功能号为3的设备的配置空间上,256个字节当中第0-3字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000001 00010 011 000000 00 = $80011300
这么多例子应该很好理解.
然后读CFC端口即可获得配置空间上的数据.如果这个总线号,设备号,功能号所对应的设备不存在,那么它配置空间上的第0-1字节上数据为$FF,$FF.这样我们以对每一个功能只访问其的0-3字节的内容即可.判断存在时才继续访问4-$FF上的内容.
伪代码:
Bus:=0; //总线0
Dev:=0; //设备0
Func:=0; //功能0
BytesT:=0; //字节位置 0-3
ToCF8:=$80000000+Bus shl 16+Dev shl 11+Func shl 8+BytesT shl 2;
asm
mov dx,$CF8
mov eax,ToCF8
out dx,eax //将地址码送入寄存器$CF8
mov dx,$CFC
in eax,dx //然后从$CFC中取出返回码
mov Buffer,eax
end;
其中 out dx,eax 与 in eax,dx 两个指令需要有特权才能执行.所以用了驱动
最后附上查看器源代码:
简易PCI查看.rar
(编译环境 运行文件:Delphi 6 驱动: Delphi 6+KmdKit4D)
用这个查看器查看到的数据与著名软件EVEREST查看到的基本上是相同的.
编程的一些注意点:
1.因为CF8和CFC大于FF,所以不能直接写以下指令 包括in out
asm
out $CF8,eax
end;
应该将端口号赋值dx,然后
asm
mov dx,$CF8
out dx,eax
end;
2.调用内嵌汇编的时候有时会出现莫明奇妙的错误。有时并不是代码的问题。
3.in out 端口需要有特权。只好写驱动程序来完成此任务。
先来理解一下PCI配置空间
PCI配置空间是用来存放设备必要数据的地方,我的理解是系统(1个)它里面包含了总线,而总线里面包括了设备,设备又包括了功能,而每一个功能它所占的空间是256字节(0-$FF)
那么一个系统里面又包含多少个总线啊?根据送往CF8端口的那个地址的结构来看(这个下面介绍),一个系统最多可以包括256个总线(0-$FF),一个总线又最多可以包括32个设备(0-$1F),一个设备最多可以包括8个功能(0-$7)。
所以我们要做一个查看PCI设备配置空间工具,需要搜寻上面所有地址。
for n1:=0 to $FF do //系统内所有的总线
for n2:=0 to $1F do //总线内所有的设备
for n3:=0 to $7 do //设备内所有的功能
for n4:=0 to $FF do //功能空间内所有的字节
理解完宏观的东西,现在理解微观的。那么我要访问一个功能上的一个字节该怎么做啊?
用I/O命令可以办到
CF8称为地址配置端口,只要往这个端口送一个32位(4字节)的数据(这个数据包含了总线,设备,功能,空间字节的信息),然后到CFC端口就可以读出我们想要的内容(32位)(4字节)。
送往CF8的数据的结构:
这个DOWRD的第31位必须为1,24-30位因为保留无功能的关系为0,16-23位代表总线号(0-$FF),11-15位代表设备号(0-$1F),8-10位代表功能号(0-$7),2-7位代表要访问空间的位置(0-$3F).0-1位恒定为0.
解释一下2-7位代表要访问的空间的位置,为什么是0-$3F呢,因为0-$3F即是0-63即64个位置,因为每一个位置都会导致CFC端口返回一个4字节数据,64*4=256字节,刚好是一个功能的配置空间
举个例子说明一下:
比如我想知道总线号为0,设备号为0,功能号为0的设备的配置空间上,256个字节当中第0-3字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000000 00000 000 000000 00 = $80000000
又例如我想知道总线号为0,设备号为0,功能号为0的设备的配置空间上,256个字节当中第4-7字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000000 00000 000 000001 00 = $80000004
那么8-11字节呢?
1 0000000 00000000 00000 000 000010 00 = $80000008
例如我想知道总线号为1,设备号为0,功能号为0的设备的配置空间上,256个字节当中第0-3字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000001 00000 000 000000 00 = $80010000
再例如我想知道总线号为1,设备号为2,功能号为3的设备的配置空间上,256个字节当中第0-3字节的内容是什么啊?那么可以向CF8端口送入以下二进制数据:
1 0000000 00000001 00010 011 000000 00 = $80011300
这么多例子应该很好理解.
然后读CFC端口即可获得配置空间上的数据.如果这个总线号,设备号,功能号所对应的设备不存在,那么它配置空间上的第0-1字节上数据为$FF,$FF.这样我们以对每一个功能只访问其的0-3字节的内容即可.判断存在时才继续访问4-$FF上的内容.
伪代码:
Bus:=0; //总线0
Dev:=0; //设备0
Func:=0; //功能0
BytesT:=0; //字节位置 0-3
ToCF8:=$80000000+Bus shl 16+Dev shl 11+Func shl 8+BytesT shl 2;
asm
mov dx,$CF8
mov eax,ToCF8
out dx,eax //将地址码送入寄存器$CF8
mov dx,$CFC
in eax,dx //然后从$CFC中取出返回码
mov Buffer,eax
end;
其中 out dx,eax 与 in eax,dx 两个指令需要有特权才能执行.所以用了驱动
最后附上查看器源代码:
简易PCI查看.rar
(编译环境 运行文件:Delphi 6 驱动: Delphi 6+KmdKit4D)
用这个查看器查看到的数据与著名软件EVEREST查看到的基本上是相同的.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
- [原创]分页机制 打造自己的变速齿轮 28899
- 查看PCI设备配置空间 6928
- OllyIce在调试游戏中断后看不见窗口 4795
谁下载
wuguan
天杀
progray
vinston
kagayaki
jiangdf
王安
nightxie
kingmanscu
陈云城
wormz
Sysnap
shangde
yanghh
雪yaojun
skypismire
KIDX
iniwf
liangdong
leeone
suetorp
hjhjhjhjhj
iqiqeee
yangya
ImHolly
hatling
网络风尘
jshou
zhangzdzzd
ZENGKEFU
MTrickster
ProgmBoy
vienna
suzuk
zhengzhiyi
深夜寂静
zyqqyz
mccoysc
SunV
pinkchild
z许
zhouws
lamla
KiDebug
刹那青春
hinatasdk
unixstudio
jzydt
xiebudong
boyintest
看原图
赞赏
雪币:
留言: