通过 inb() 和 outb() 查找设备基地址进行通信

发布于 2024-08-17 05:42:38 字数 351 浏览 5 评论 0原文

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

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

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

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

I am trying to communicate with a disk drive using inb(), inw(), outb() and outw() commands so I can find specific information about the drive. However, to use these commands, I need the correct I/O ports for the device. When I have the correct I/O ports, I can find the information I am looking for very easily, however, I do not know a way to find the base address of a device's I/O ports in Linux.

In DOS, I am able to use Hdat2 to find the device's base address, however, I am trying to find the address in Linux. Is there a way to find which device maps to which I/O port in Linux?

There is a file in /proc called ioports that contains some information but I don't how to associate this information with specific devices.

Any help would be greatly appreciated. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

記柔刀 2024-08-24 05:42:38

所以我确实找到了一些东西,虽然它不是最优雅的解决方案,而且它绝对不能在任何地方工作,但它在我的硬件上工作,所以我想我会分享。

首先,您必须从 lspci 命令中获取 SATA 控制器的地址,如 Nikolai 所示(-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 控制器上的主机 0 0000:00:1f.2。现在,为了找到可用于通过 inb() 和 outb() 命令与 /dev/sda 通信的地址,我们查看 /sys/bus/pci/devices/0000:00:1f 中名为“resource”的文件.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 以便向设备发送命令的方式。

如果有人知道更好的方法来做到这一点,我洗耳恭听......

So I did find something, although it isn't the most elegant solution and it definitely doesn't work everywhere, it has worked on my hardware so I figured I would share.

First, you have to get the address of the SATA Controller from the lspci command like Nikolai showed (the -D just shows the full domain numbers):

# lspci -D
...
0000:00:1f.2 SATA controller: Intel Corporation 82801IR 6 port SATA AHCI Controller
...

Now with this address (0000:00:1f.2) you can go into /sys.

In /sys/bus/pci/devices, your device should be listed:

# 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

Now in this directory there will be several hostX directories.

# 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
...

In one of these hostX directories, there will be a targetX:X:X directory. This targetX:X:X directory will then have a directory called X:X:X:X (the X's are numbers that can vary).

# 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
...

In the X:X:X:X directory, there is a link named "block:sdX" (where X is a letter). This sdX is the name of the drive that this directory corresponds to.

# 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

So /dev/sda corresponds to host 0 on the SATA Controller at 0000:00:1f.2. Now to find the address that we can use to talk to /dev/sda through inb() and outb() commands, we look in the file named "resource" in /sys/bus/pci/devices/0000:00:1f.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

The address we are looking for is fe00, which is on the first line. We want the first line because it is host 0, if it were host 1, we would look on the second line, and host 2 the third line, and so on. The host number was given by the hostX directory that we found earlier. Each line in the resource file is separated into 3 columns:

Column 1 = beginning address
Column 2 = end address
Column 3 = flags

So this is how I get from /dev/sda to 0xfe00 in order to send commands to the device.

If anybody know any better way to do this, I am all ears...

寂寞清仓 2024-08-24 05:42:38

该设备很可能挂在 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 设备驱动程序,第三版中的详细信息。第12章:PCI驱动程序

编辑:

看看这个 分区和大容量存储Naming howto 获取有关 Linux 驱动器命名的帮助。

The device is most probably hanging off of the PCI bus, so lspci(8) is the first to look at. Then figure out where under /sys the controller is described. Here, for example, I have:


~$ 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

This shows controller's PCI configuration space. See the details in Linux Device Drivers, Third Edition. Chapter 12: PCI Drivers.

Edit:

Take a look into this partition and mass-storage naming howto for help on Linux drive naming.

花开浅夏 2024-08-24 05:42:38

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

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

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

Are you accessing hardware from a userspace program or from a kernel module?

If you're doing it from userspace, the reason it's hard to find physical address information is that nobody accesses hardware that way; anything that needs to touch raw hardware lives in the kernel.

If you're writing a kernel module, you get address information from in-kernel structures, not by accessing /sys/...

疏忽 2024-08-24 05:42:38

该路径似乎在内核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

The path seems have chanced in kernel 3.10, this is how I find the corresponding device node:

$ 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文