Como os dispositivos PCI são acessados?

2

Eu tenho 2 perguntas relacionadas ao barramento PCI:

Como os drivers de dispositivo acessam dispositivos no barramento PCI? É suficiente gravar na região de memória alocada para o dispositivo ( mov memory_space_allocated_for_dev, something , se o dispositivo estiver mapeado na memória ou out io_space_allocated for_dev, something se não estiver) (o hardware converterá essa tentativa de acessar o local da memória para uma série de comandos PCI no barramento PCI etc. .?).

É correto que depois de configurar todos os dispositivos em todos os barramentos PCI (isto é, alocar memória, enumerar barramentos, etc.) os drivers de dispositivos não precisem saber se o barramento PCI existe ou a decodificação da memória é feita com decodificador simples em computadores antigos) (ou seja, eles simplesmente escrevem e lêem de alguns locais de memória para acessar o dispositivo)?

    
por maplaz 10.06.2016 / 13:43

2 respostas

6

Dispositivos PCI (e) mapeados em memória terão BARs (registradores de endereço base) que permitem que o host saiba quanta memória deve ser alocada para o dispositivo. O BIOS (e o SO depois) alocarão o espaço de memória solicitado para o dispositivo de destino - não que seja um endereço de memória , os bits físicos não estão sendo alocados. Além disso, isso geralmente será um endereço de memória física , não um endereço de memória virtual. O kernel Linux arbitra o acesso a esses dispositivos com funções como mmap () que permitem o mapeamento de memória física para endereços de memória virtual.

Por exemplo, digamos que você tenha um dispositivo PCIe que controle 8 LEDs. Como criador do dispositivo, posso solicitar uma barra muito pequena de 1K de espaço de endereço. O BIOS pode me fornecer um endereço físico em um sistema de 32 bits de 0xE000_0000 a 0xE000_0400 (nota lateral: você deve ver aqui agora porque os sistemas de 32 bits e GPUs com VRAM grande não funcionam bem juntos).

Agora, se eu escrever digito 0xF0 na localização de memória 0xE000_0000 com uma gravação de um byte, isso ativará os LEDs de 7 a 4 e deixará de 3 a 0 desligado. É isso - é simples E / S mapeada na memória. Somando-se às camadas de abstração, no Linux, você utilizaria seu excelente subsistema PCI e gravaria um driver que seja carregado para uma determinada cadeia de ID de fornecedor + ID de dispositivo. Você poderia então escrever um aplicativo do espaço do usuário que chama o driver do kernel, onde uma chamada mmap () pode mapear a memória no espaço do usuário, permitindo que o aplicativo userspace faça leituras / gravações em algum endereço de memória virtual que será traduzido e acabará no espaço da memória física onde pertence.

x86 tem espaço de E / S, e o comportamento é bem parecido, exceto baixo nível no kernel, as instruções outb / outw / outl (e suas entradas primas) serão usadas para escrever / ler a partir de I / O espaço, versus instruções de leitura / gravação de memória. Novamente, um aplicativo userspace deve estar se comunicando através de ioctls () e um segmento de memória mapeado, já que o kernel é responsável pela segurança / acesso à memória assim.

Para a sua segunda pergunta, uma espécie de combinação com o que foi dito acima, mas um moderno driver PCIe para Linux dependerá do subsistema PCI para muitas das tarefas domésticas de baixo nível. Você define principalmente quais identificações de fornecedor / dispositivo você é responsável e, em seguida, escreve uma função .probe () que trava seus IRQs e faz a configuração do dispositivo - sua memória é entregue a você.

    
por 29.06.2016 / 20:02
0

Já faz um tempo, mas se bem me lembro, o seu driver de kernel irá configurar um dispositivo em / dev que mapeia os endereços de memória alocados para os dispositivos PCI pelo BIOS ou pelo kernel. Os programas de espaço do usuário com as permissões apropriadas serão abertos, lidos / gravados / buscados e serão fechados esse arquivo / dev / para interagir com o dispositivo PCI. Veja o capítulo 12 dos drivers de dispositivos Linux: link

    
por 10.06.2016 / 19:20