Поиск базового адреса устройства для связи через inb () и outb () - PullRequest
4 голосов
/ 04 января 2010

Я пытаюсь связаться с диском с помощью команд inb (), inw (), outb () и outw (), чтобы найти конкретную информацию о диске. Однако для использования этих команд мне нужны правильные порты ввода-вывода для устройства. Когда у меня есть правильные порты ввода / вывода, я очень легко могу найти нужную информацию, однако я не знаю способа найти базовый адрес портов ввода / вывода устройства в Linux.

В DOS я могу использовать Hdat2, чтобы найти базовый адрес устройства, однако я пытаюсь найти адрес в Linux. Есть ли способ найти, какое устройство сопоставляется с каким портом ввода / вывода в Linux?

В / proc есть файл ioports, который содержит некоторую информацию, но я не знаю, как связать эту информацию с конкретными устройствами.

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 4 ]

4 голосов
/ 14 января 2010

Итак, я нашел что-то, хотя это не самое элегантное решение, и оно определенно не работает везде, оно работало на моем оборудовании, поэтому я решил, что поделюсь.

Во-первых, вы должны получить адрес контроллера SATA из команды lspci, как показал Николай (ключ -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 соответствует хосту 0 на контроллере SATA в 0000: 00: 1f.2. Теперь, чтобы найти адрес, который мы можем использовать для общения с / dev / sda с помощью команд inb () и outb (), мы смотрим в файле с именем «resource» в / sys / bus / pci / devices / 0000: 00: 1f 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 голос
/ 17 октября 2013

Кажется, что путь произошел в ядре 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
1 голос
/ 08 января 2010

Вы получаете доступ к оборудованию из пользовательской программы или из модуля ядра?

Если вы делаете это из пространства пользователя, причина, по которой трудно найти информацию о физическом адресе, состоит в том, что никто не получает доступ к оборудованию таким образом; все, что должно касаться необработанного оборудования, живет в ядре.

Если вы пишете модуль ядра, вы получаете информацию об адресе из структур внутри ядра, а не путем доступа к /sys/...

1 голос
/ 04 января 2010

Устройство, скорее всего, зависает от шины 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 .

Edit:

Ознакомьтесь с этим руководством по именованию разделов и запоминающих устройств для получения справки по именованию дисков Linux.

...