如何通过 pci capability id 识别设备
How to identify the device by pci capability id
如何通过pci capability id来识别设备?
这是我的代码:
我尝试访问 34h 并检查第一个循环中是否存在功能 ID
如果存在,则指向下一个指针,但是在获取指针和放地址的步骤中似乎有些问题。
'''
push eax
push edi
push esi
mov cx,100
;mov edi,[esi]
add edi,52 ;access 34h
lopreg:
mov eax,edi ;read
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx
cmp cx,100 ;first time
je first
cmp ah,10
jne nextreg
jmp ispcie
first:
cmp ah,0
je ending
sub edi,52
movzx bx,ah
add di,bx
loop lopreg
jmp ending
ispcie:
call set_cur
mov ah,09h
lea dx,regmem ;print pcie
int 21h
jmp ending
nextreg:
cmp al,0
je ending
movzx bx,al ;
add di,bx
loop lopreg
ending:
pop esi
pop edi
pop eax
ret
'''
编写此答案时假设此代码正在寻找 PCI Express 功能。
这段代码中有几个问题。
- 在
first
标签处,应该使用al
而不是ah
来确定第一个能力的偏移量。
- PCI Express 能力的能力 ID 是 10h,而不是 10。
- 读取每个功能 header 后,
al
包含功能 ID,ah
包含下一个指针。所以 cmp ah, 10
应该是 cmp al, 10h
.
- 在
nextreg
标签处,应该使用ah
而不是al
来确定下一个能力的偏移量。
- 在每次迭代中,它会将
bx
添加到 di
而不会删除之前的偏移量。
- 不清楚
edi
被初始化为什么,但如果它没有设置第 31 位,那么这段代码根本不会读取 PCI 配置 space。
这应该有效:
mov cx,100
;mov edi,[esi]
add edi,52 ;access 34h
lopreg:
mov eax,edi ;read
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx
cmp cx,100 ;first time
je first
cmp al,10h
jne nextreg
jmp ispcie
first:
cmp al,0
je ending
sub edi,52
movzx bx,al
add di,bx
loop lopreg
jmp ending
ispcie:
call set_cur
mov ah,09h
lea dx,regmem ;print pcie
int 21h
jmp ending
nextreg:
cmp ah,0
je ending
sub di, bx
movzx bx,ah
add di,bx
loop lopreg
ending:
更好的方法是保留edi
中的原始地址而不更改它,并为每个新偏移量使用lea eax, [edi+ebx]
。
没有必要用ecx
作为循环计数器,逻辑有点绕。可以拉直一点,让流线更清晰。
我会这样写:
lea eax,[edi+34h]
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in al,dx ; read offset of first capability
cmp al,0
je ending
movzx ebx,al
lopreg:
lea eax,[edi+ebx] ; offset of next capability is in ebx
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx ; read capability header
cmp al,10h ; check if it is the PCI Express capability
je ispcie
nextreg:
cmp ah,0 ; check if it is the end of the capability list
je ending
movzx ebx, ah ; set up ebx with the offset of the next capability
jmp lopreg
ispcie:
; base of device PCI config space is in edi
; offset of PCI Express Capability is in ebx
...
ending:
(我不知道 set_cur
和 regmem
是什么,所以我没有尝试编写那部分代码。)
如何通过pci capability id来识别设备? 这是我的代码:
我尝试访问 34h 并检查第一个循环中是否存在功能 ID 如果存在,则指向下一个指针,但是在获取指针和放地址的步骤中似乎有些问题。
'''
push eax
push edi
push esi
mov cx,100
;mov edi,[esi]
add edi,52 ;access 34h
lopreg:
mov eax,edi ;read
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx
cmp cx,100 ;first time
je first
cmp ah,10
jne nextreg
jmp ispcie
first:
cmp ah,0
je ending
sub edi,52
movzx bx,ah
add di,bx
loop lopreg
jmp ending
ispcie:
call set_cur
mov ah,09h
lea dx,regmem ;print pcie
int 21h
jmp ending
nextreg:
cmp al,0
je ending
movzx bx,al ;
add di,bx
loop lopreg
ending:
pop esi
pop edi
pop eax
ret
'''
编写此答案时假设此代码正在寻找 PCI Express 功能。
这段代码中有几个问题。
- 在
first
标签处,应该使用al
而不是ah
来确定第一个能力的偏移量。 - PCI Express 能力的能力 ID 是 10h,而不是 10。
- 读取每个功能 header 后,
al
包含功能 ID,ah
包含下一个指针。所以cmp ah, 10
应该是cmp al, 10h
. - 在
nextreg
标签处,应该使用ah
而不是al
来确定下一个能力的偏移量。 - 在每次迭代中,它会将
bx
添加到di
而不会删除之前的偏移量。 - 不清楚
edi
被初始化为什么,但如果它没有设置第 31 位,那么这段代码根本不会读取 PCI 配置 space。
这应该有效:
mov cx,100
;mov edi,[esi]
add edi,52 ;access 34h
lopreg:
mov eax,edi ;read
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx
cmp cx,100 ;first time
je first
cmp al,10h
jne nextreg
jmp ispcie
first:
cmp al,0
je ending
sub edi,52
movzx bx,al
add di,bx
loop lopreg
jmp ending
ispcie:
call set_cur
mov ah,09h
lea dx,regmem ;print pcie
int 21h
jmp ending
nextreg:
cmp ah,0
je ending
sub di, bx
movzx bx,ah
add di,bx
loop lopreg
ending:
更好的方法是保留
edi
中的原始地址而不更改它,并为每个新偏移量使用lea eax, [edi+ebx]
。没有必要用
ecx
作为循环计数器,逻辑有点绕。可以拉直一点,让流线更清晰。
我会这样写:
lea eax,[edi+34h]
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in al,dx ; read offset of first capability
cmp al,0
je ending
movzx ebx,al
lopreg:
lea eax,[edi+ebx] ; offset of next capability is in ebx
mov dx,0cf8h
out dx,eax
mov dx,0cfch
in eax,dx ; read capability header
cmp al,10h ; check if it is the PCI Express capability
je ispcie
nextreg:
cmp ah,0 ; check if it is the end of the capability list
je ending
movzx ebx, ah ; set up ebx with the offset of the next capability
jmp lopreg
ispcie:
; base of device PCI config space is in edi
; offset of PCI Express Capability is in ebx
...
ending:
(我不知道 set_cur
和 regmem
是什么,所以我没有尝试编写那部分代码。)