首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找要通过inb()和outb()通信的设备基址

查找要通过inb()和outb()通信的设备基址
EN

Stack Overflow用户
提问于 2010-01-05 00:54:02
回答 4查看 4.7K关注 0票数 4

我正在尝试使用inb()、inw()、outb()和outw()命令与磁盘驱动器通信,以便找到有关该驱动器的特定信息。但是,要使用这些命令,我需要设备的正确I/O端口。当我拥有正确的I/O端口时,我可以非常容易地找到我正在寻找的信息,但是,我不知道在Linux中找到设备I/O端口的基地址的方法。

在DOS中,我可以使用Hdat2来查找设备的基地址,但是,我正在尝试在Linux中查找地址。在Linux中,有没有办法找出哪个设备映射到哪个I/O端口?

在/proc中有一个名为ioports的文件,其中包含一些信息,但我不知道如何将这些信息与特定设备关联起来。

任何帮助都将不胜感激。谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-01-15 04:19:30

所以我确实找到了一些东西,尽管它不是最优雅的解决方案,也不是所有地方都适用,但它在我的硬件上起作用了,所以我想我会分享。

首先,您必须从lspci命令中获取SATA控制器的地址,如Nikolai所示( -D仅显示完整的域号):

代码语言:javascript
复制
# 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中,应列出您的设备:

代码语言:javascript
复制
# 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目录。

代码语言:javascript
复制
# 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 X:X:X目录。这个targetX:X:X目录将有一个名为X:X的目录(X是可以改变的数字)。

代码语言:javascript
复制
# 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目录中,有一个名为"block:sdX“的链接(其中X是一个字母)。此sdX是此目录对应的驱动器的名称。

代码语言:javascript
复制
# 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.2/中查找名为"resource“的文件。

代码语言:javascript
复制
# 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,以便向设备发送命令。

如果有人知道更好的方法,我洗耳恭听...

票数 4
EN

Stack Overflow用户

发布于 2010-01-05 01:11:31

设备很可能挂在PCI总线上,所以lspci(8)是第一个要看的。然后找出在/sys下控制器的描述位置。例如,在这里,我有:

代码语言:javascript
复制
~$ 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驱动器命名的帮助。

票数 1
EN

Stack Overflow用户

发布于 2010-01-08 09:13:03

您是从用户空间程序还是从内核模块访问硬件?

如果您是在用户空间中执行此操作,那么很难找到物理地址信息的原因是没有人以这种方式访问硬件;任何需要接触原始硬件的东西都存在于内核中。

如果您正在编写内核模块,则可以从内核内结构中获取地址信息,而不是通过访问/sys/...

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2000724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档