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:
- ioperm (véase la página del manual): permite solicitar
acceso al conjunto de puertos especificados en los parámetros
de la misma. Este servicio, específico de la arquitectura x86, sólo puede
invocarse como superusuario.
- Las funciones de entrada/salida de bajo nivel (man outb),
que encapsulan el acceso real a los puertos y que, evidentemente,
sólo pueden usarse si se ha invocado previamente el servicio
ioperm especificando los puertos a los que se quiere acceder.
Se plantean, a continuación, una serie de etapas de manera que
se acometa la funcionalidad pedida de manera incremental:
- 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.
- Añadir al código la funcionalidad para mostrar esa información de
todos los dispositivos que están asociados al bus 0.
- 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.
- 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.
- Mostrar qué zonas de memoria o de entrada/salida están asociados
a cada dispositivo, especificando la dirección inicial y el tamaño.