我正在尝试使用inb(),inw(),outb()和outw()命令与磁盘驱动器通信,以便我可以找到有关驱动器的特定信息。但是,要使用这些命令,我需要为设备提供正确的I / O端口。当我有正确的I / O端口时,我可以很容易地找到我正在寻找的信息,但是,我不知道如何在Linux中找到设备的I / O端口的基地址。
在DOS中,我可以使用Hdat2来查找设备的基地址,但是,我试图在Linux中找到该地址。有没有办法找到哪个设备映射到Linux中的哪个I / O端口?
/ proc中有一个名为ioports的文件,其中包含一些信息,但我不知道如何将此信息与特定设备相关联。
非常感谢任何帮助。谢谢!
答案 0 :(得分:4)
所以我确实找到了一些东西,虽然它不是最优雅的解决方案,但它无处不在,它已经在我的硬件上工作,所以我想我会分享。
首先,你必须从像尼古拉所示的lspci命令中获取SATA控制器的地址(-D只显示完整的域名号码):
# lspci -D
...
0000:00:1f.2 SATA controller: Intel Corporation 82801IR 6 port SATA AHCI Controller
...
现在有了这个地址(0000:00:1f.2),你可以进入/ sys。
在/ sys / bus / pci / devices中,应列出您的设备:
# ls -l /sys/bus/pci/devices
...
lrwxrwxrwx 1 root root 0 Jan 14 12:35 0000:00:1f.2 -> ../../../devices/pci0000:00/0000:00:1f.2
现在在这个目录中会有几个hostX目录。
# ls -l /sys/bus/pci/devices/0000\:00\:1f.2/
...
drwxr-xr-x 4 root root 0 Jan 13 12:40 host0
drwxr-xr-x 4 root root 0 Jan 13 12:40 host1
drwxr-xr-x 3 root root 0 Jan 13 12:40 host2
drwxr-xr-x 3 root root 0 Jan 13 12:40 host3
drwxr-xr-x 3 root root 0 Jan 13 12:40 host4
drwxr-xr-x 4 root root 0 Jan 14 08:21 host5
...
在其中一个hostX目录中,将有一个targetX:X:X目录。这个targetX:X:X目录将有一个名为X的目录:X:X:X(X是可以变化的数字)。
# ls -R /sys/bus/pci/devices/0000\:00\:1f.2/host0
/sys/bus/pci/devices/0000:00:1f.2/host0:
power scsi_host:host0 target0:0:0 uevent
/sys/bus/pci/devices/0000:00:1f.2/host0/target0:0:0:
0:0:0:0 power uevent
...
在X:X:X:X目录中,有一个名为“block:sdX”的链接(其中X是一个字母)。此sdX是此目录对应的驱动器的名称。
# ls -l /sys/bus/pci/devices/0000\:00\:1f.2/host0/target0\:0\:0/0\:0\:0\:0/
lrwxrwxrwx 1 root root 0 Jan 14 15:01 block:sda -> ../../../../../../block/sda
因此/ dev / sda对应于SATA控制器上0000:00:1f.2的主机0。现在找到我们可以用来通过inb()和outb()命令与/ dev / sda交谈的地址,我们查看/ sys / bus / pci / devices / 0000:00:1f中名为“resource”的文件0.2 /。
# cat /sys/bus/pci/devices/0000\:00\:1f.2/resource
0x000000000000fe00 0x000000000000fe07 0x0000000000000101
0x000000000000fe10 0x000000000000fe13 0x0000000000000101
0x000000000000fe20 0x000000000000fe27 0x0000000000000101
0x000000000000fe30 0x000000000000fe33 0x0000000000000101
0x000000000000fec0 0x000000000000fedf 0x0000000000000101
0x00000000ff970000 0x00000000ff9707ff 0x0000000000000200
0x0000000000000000 0x0000000000000000 0x0000000000000000
我们正在寻找的地址是fe00,它位于第一行。我们想要第一行,因为它是主机0,如果它是主机1,我们将查看第二行,主机2看第三行,依此类推。主机号由我们之前找到的hostX目录给出。资源文件中的每一行分为3列:
第1列=开始地址 第2列=结束地址 第3列=标志
这就是我从/ dev / sda到0xfe00的方式,以便向设备发送命令。
如果有人知道更好的方法,我会全力以赴......
答案 1 :(得分:1)
该设备很可能悬挂在PCI总线上,因此lspci(8)
是第一个看到的。然后找出控制器描述在/sys
下的位置。在这里,例如,我有:
~$ lspci
...
03:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 1078 (rev 04)
...
~$ ll /sys/bus/pci/devices/0000\:03\:00.0/
total 0
drwxr-xr-x 4 root root 0 Dec 16 11:57 ./
drwxr-xr-x 6 root root 0 Dec 16 11:57 ../
-rw-r--r-- 1 root root 4096 Dec 16 11:57 broken_parity_status
lrwxrwxrwx 1 root root 0 Dec 16 11:57 bus -> ../../../../bus/pci/
-r--r--r-- 1 root root 4096 Dec 16 11:57 class
-rw-r--r-- 1 root root 4096 Dec 16 11:57 config
-r--r--r-- 1 root root 4096 Dec 16 11:57 device
lrwxrwxrwx 1 root root 0 Dec 16 11:57 driver -> ../../../../bus/pci/drivers/megaraid_sas/
-rw------- 1 root root 4096 Dec 16 11:57 enable
drwxr-xr-x 5 root root 0 Dec 16 11:57 host0/
-r--r--r-- 1 root root 4096 Dec 16 11:57 irq
-r--r--r-- 1 root root 4096 Dec 16 11:57 local_cpus
-r--r--r-- 1 root root 4096 Dec 16 11:57 modalias
-r--r--r-- 1 root root 4096 Dec 16 11:57 pools
drwxr-xr-x 2 root root 0 Dec 16 11:57 power/
-r--r--r-- 1 root root 4096 Dec 16 11:57 resource
-rw------- 1 root root 262144 Dec 16 11:57 resource0
-rw------- 1 root root 256 Dec 16 11:57 resource2
-rw------- 1 root root 262144 Dec 16 11:57 resource3
-r-------- 1 root root 32768 Dec 16 11:57 rom
lrwxrwxrwx 1 root root 0 Dec 16 11:57 subsystem -> ../../../../bus/pci/
-r--r--r-- 1 root root 4096 Dec 16 11:57 subsystem_device
-r--r--r-- 1 root root 4096 Dec 16 11:57 subsystem_vendor
--w------- 1 root root 4096 Dec 16 11:57 uevent
-r--r--r-- 1 root root 4096 Dec 16 11:57 vendor
显示控制器的PCI配置空间。请参阅Linux Device Drivers, Third Edition. Chapter 12: PCI Drivers中的详细信息。
请查看此partition and mass-storage naming howto以获取有关Linux驱动器命名的帮助。
答案 2 :(得分:1)
您是从用户空间程序还是从内核模块访问硬件?
如果你是从用户空间进行的,那么很难找到物理地址信息的原因是没有人以这种方式访问硬件;任何需要触摸原始硬件的东西都存在于内核中。
如果您正在编写内核模块,则从内核结构中获取地址信息,而不是通过访问/sys/...
答案 3 :(得分:1)
路径似乎在内核3.10中出现了机会,这就是我找到相应设备节点的方式:
$ ls -l /sys/bus/pci/devices/0000\:00\:1f.2/ata1/host0/target0\:0\:0/0\:0\:0\:0/block/
total 0
drwxr-xr-x 10 root root 0 Oct 17 08:35 sda
$ ls -l /sys/bus/pci/devices/0000\:00\:1f.2/ata2/host1/target1\:0\:0/1\:0\:0\:0/block/
total 0
drwxr-xr-x 9 root root 0 Oct 17 08:35 sdb