Navegando por el bus PCI

El objetivo de este trabajo es que el alumno se familiarice con la programación de dispositivos desarrollando un código que muestre la información de todos los dispositivos que están asociados a los buses PCI del sistema.

Este código ejecutará en modo usuario demostrando cómo en un sistema operativo de propósito general, como Linux, también se puede interaccionar directamente con los dispositivos sin necesidad de que el código ejecute en modo privilegiado englobado dentro del núcleo del sistema operativo.

Este trabajo permitirá que el alumno se enfrente con algunos aspectos que son habituales en la programación de dispositivos como, por ejemplo, el uso de entrada/salida basada en puertos (PIO) o el manejo de información bit a bit. Asimismo, tendrá que buscar, e interpretar adecuadamente, información de bajo nivel sobre aspectos hardware, concretamente, sobre la configuración del bus PCI. Para ello, se recomienda una referencia de OSDev que explica aspectos de la programación del bus PCI.

El desarrollo de este proyecto requiere el uso de dos tipos de funciones de Linux:

Se plantean, a continuación, una serie de etapas de manera que se acometa la funcionalidad pedida de manera incremental:

  1. Desarrollar un programa que muestre la siguiente información del dispositivo que corresponde con la función 0 de la posición (slot) 0 del bus 0: vendedor, producto, clase y subclase. Nótese que puede consultar manualmente el fichero /usr/share/hwdata/pci.ids para obtener información sobre vendedores y productos. Puede tomar como base el ejemplo usado en clase.
  2. Añadir al código la funcionalidad para mostrar esa información de todos los dispositivos que están asociados al bus 0.
  3. Dotar al programa de la capacidad de explorar (enumerar) todos los buses. En esta primera etapa, siguiendo una estrategia de fuerza bruta (ir probando los 256 posibles buses y las ocho funciones de cada dispositivo). Nótese que el alumno puede optar por saltarse esta etapa y afrontar directamente la versión optimizada.
  4. Optimizar la etapa previa de manera que sólo se intente recorrer un bus cuando se detecta el PCI-PCI bridge que da paso al mismo y sólo se acceda a las funciones restantes de un dispositivo (aquéllas con un identificador mayor que 0) después de comprobar que se trata de un dispositivo multifunción.
  5. Mostrar qué zonas de memoria o de entrada/salida están asociados a cada dispositivo, especificando la dirección inicial y el tamaño.