Pergunta

Eu estou tentando comunicar-se com uma unidade de disco usando inb(), pin(), outb() e outw() comandos para que eu possa encontrar informações específicas sobre a unidade.No entanto, a utilização desses comandos, eu preciso que o correto portas de e/S para o dispositivo.Quando eu tiver o correto portas de I/O, que eu possa encontrar as informações que eu estou procurando muito facilmente, no entanto, eu não sei uma maneira de localizar o endereço base de um dispositivo de portas de e/S em Linux.

No ms-DOS, eu sou capaz de usar Hdat2 para encontrar o dispositivo do endereço base, no entanto, eu estou tentando encontrar o endereço no Linux.Existe uma maneira de encontrar o dispositivo que mapeia para porta de e/S em Linux?

Há um arquivo em /proc chamado ioports que contém algumas informações, mas eu não como associar essas informações com dispositivos específicos.

Qualquer ajuda seria muito apreciada.Obrigado!

Foi útil?

Solução

Então eu encontre alguma coisa, embora não seja a solução mais elegante e, definitivamente, não funciona em todos os lugares, ele tem trabalhado em meu hardware, então eu percebi que eu iria partilhar.

Primeiro, você tem que obter o endereço do Controlador SATA do comando lspci como Nikolai mostrou (a -D mostra o completo domínio de números):

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

Agora com este endereço (0000:00:1f.2) você pode ir em /sys.

Em /sys/bus/pci/devices, o seu dispositivo deve ser listados:

# 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

Agora neste diretório existem várias hostX diretórios.

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

Em um desses hostX diretórios, haverá um targetX:X:X directory.Este targetX:X:X directory, em seguida, irá ter um diretório chamado X:X:X:X (o X são os números que pode variar).

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

Em X:X:X:X diretório, há um link chamado "bloquear:sdX" (onde X é uma letra).Este sdX é o nome da unidade que este diretório correspondente.

# 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

Assim, /dev/sda corresponde ao host 0 sobre o Controlador SATA em 0000:00:1f.2.Agora, para encontrar o endereço que podemos usar para falar /dev/sda, através da inb() e outb() comandos, temos de olhar no arquivo chamado "recurso" em /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

O endereço que estamos procurando é fe00, que está na primeira linha.Nós queremos que a primeira linha porque ele é anfitrião 0, se fosse host 1, ficaria na segunda linha, e o host 2, a terceira linha e assim por diante.O número de host foi dada pelo hostX diretório que vimos anteriormente.Cada linha no arquivo de recurso é separado em 3 colunas:

Coluna 1 = endereço de início Coluna 2 = endereço final Coluna 3 = sinalizadores

É assim que eu começar a partir de /dev/sda para 0xfe00 para enviar comandos para o dispositivo.

Se alguém sabe alguma maneira melhor de fazer isso, eu sou todo ouvidos...

Outras dicas

O dispositivo provavelmente está pendurado no barramento PCI, então lspci(8) é o primeiro a olhar. Então descubra onde embaixo /sys o controlador é descrito. Aqui, por exemplo, eu tenho:


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

Isso mostra o espaço de configuração do PCI do controlador. Veja os detalhes em Drivers de dispositivo Linux, terceira edição. Capítulo 12: Drivers PCI.

Editar:

Dê uma olhada nisso partição e armazenamento em massa nomeando como Para obter ajuda no Linux Drive Naming.

Você está acessando o hardware de um programa de espaço de usuários ou de um módulo de kernel?

Se você está fazendo isso no espaço do usuário, o motivo pelo qual é difícil encontrar informações de endereço físico é que ninguém acessa o hardware dessa maneira; Qualquer coisa que precise tocar hardware cru viva no kernel.

Se você está escrevendo um módulo de kernel, obtém informações de endereço das estruturas no kernel, não acessando /sys/...

O caminho parece ter acontecido no kernel 3.10, é assim que encontro o nó do dispositivo correspondente:

$ 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top