Arquitectura del Sistema

TEMARIO:

Introducción

En la evolución de la informática electrónica, los fabricantes de computadoras han integrado diversos componentes de hardware en sus máquinas, los cuales deben ser compatibles con el sistema operativo. Esto puede ser desafiante para los desarrolladores de sistemas operativos, a menos que se establezcan estándares para los conjuntos de instrucciones y la comunicación del dispositivo. Estos estándares, al igual que la capa de abstracción proporcionada por el sistema operativo a las aplicaciones, simplifican la escritura y el mantenimiento de un sistema operativo independiente del modelo de hardware específico. Sin embargo, la complejidad del hardware a veces requiere ajustes en la exposición de los recursos al sistema operativo para garantizar su correcta instalación y funcionamiento.

Hasta mediados de los años 2000, la configuración del hardware se realizaba a través del BIOS, un estándar de firmware presente en placas base x86. Sin embargo, desde finales de esa década, se introdujo el UEFI (Unified Extensible Firmware Interface), una implementación más avanzada que ofrece características sofisticadas para la configuración y actualización del firmware en las máquinas basadas en arquitectura x86. Aunque se ha producido este cambio, es común referirse a la utilidad de configuración como BIOS, ya que ambas cumplen el mismo propósito básico.

Configuración de Periféricos

La utilidad de configuración del sistema se activa al presionar una tecla específica al encender la computadora, como Del, F2 o F12, dependiendo del fabricante. Esta combinación de teclas, generalmente mostrada al iniciar la máquina, permite acceder al BIOS para ajustar la configuración del sistema.

En la utilidad de configuración del BIOS, se pueden habilitar/deshabilitar periféricos integrados, activar protección básica contra errores y modificar configuraciones de hardware como IRQ y DMA. Aunque raramente se requieren cambios en las máquinas modernas, ajustes pueden ser necesarios para resolver problemas específicos. Por ejemplo, ajustar la velocidad de transferencia de datos para tecnologías RAM compatibles con velocidades más altas. Además, algunas CPU ofrecen funciones que pueden desactivarse para reducir el consumo de energía y aumentar la protección del sistema.

Es crucial establecer correctamente el gestor de arranque y su orden en el BIOS cuando hay múltiples dispositivos de almacenamiento en una máquina. Si el dispositivo incorrecto tiene prioridad en la lista de arranque, el sistema operativo podría no cargarse correctamente.

Exploración de Dispositivos en Linux

Una vez que los dispositivos se identifican, el sistema operativo debe asociar los componentes de software correspondientes. Para abordar problemas de hardware, es esencial identificar dónde ocurre el problema. Si el sistema operativo no detecta un dispositivo, podría ser defectuoso. Si se detecta pero no funciona, el problema puede estar en el sistema operativo. Para diagnosticar, se pueden usar comandos especializados o leer archivos específicos en sistemas de archivos especiales.

Exploración mediante Comandos

Los dos comandos clave para detectar dispositivos en Linux:

lspci.- Enumera todos los dispositivos actualmente conectados al bus PCI (Interconexión de Componentes Periféricos). Estos dispositivos pueden ser componentes integrados en la placa base, como controladores de disco, o tarjetas de expansión insertadas en ranuras PCI, como tarjetas gráficas adicionales.

lsusb.- Identifica y lista los dispositivos USB (Universal Serial Bus) que están actualmente conectados a tu máquina. Aunque la interfaz USB abarca una amplia gama de dispositivos, se destaca principalmente por conectar dispositivos de entrada, como teclados y ratones, además de medios de almacenamiento extraíbles.

Los comandos lspci y lsusb proporcionan una lista de todos los dispositivos PCI y USB detectados por el sistema operativo. Sin embargo, la presencia en la lista no garantiza que el dispositivo esté completamente operativo, ya que cada componente de hardware requiere un módulo de kernel correspondiente para funcionar. Estos módulos pueden ser parte del núcleo oficial de Linux o agregados desde otras fuentes de manera independiente.

En Linux, los módulos del núcleo asociados con dispositivos de hardware, también conocidos como controladores, son esenciales para su funcionamiento, al igual que en otros sistemas operativos. Sin embargo, a diferencia de otros sistemas, no todos los controladores en Linux son proporcionados por los fabricantes de los dispositivos. Muchos son desarrollados por la comunidad de manera independiente. Aunque históricamente algunos dispositivos compatibles con Windows carecían de controladores equivalentes para Linux, en la actualidad, los sistemas basados en Linux ofrecen un sólido soporte de hardware, lo que permite que la mayoría de los dispositivos funcionen sin problemas.

Los comandos que están estrechamente vinculados con el hardware a menudo necesitan privilegios de administrador (root) para ejecutarse completamente, ya que si son ejecutados por un usuario normal, solo mostrarán información limitada. Por lo tanto, puede ser necesario iniciar sesión como root o ejecutar el comando «sudo» para obtener todos los detalles relacionados con el hardware.

La siguiente salida del comando lspci, por ejemplo, muestra algunos dispositivos identificados:

Debido a que la salida de estos comandos puede extenderse a decenas de líneas, los ejemplos proporcionados se enfocan únicamente en las secciones relevantes. Los números hexadecimales al inicio de cada línea representan las direcciones únicas de los dispositivos PCI. Al utilizar el comando lspci, se pueden obtener más detalles sobre un dispositivo específico al especificar su dirección con la opción -s, junto con la opción -v.

El comando lspci -s 00:0b.0 -v muestra información detallada sobre un puente PCI de NVIDIA Corporation, con la dirección 00:0b.0. Incluye detalles como la revisión del dispositivo, el subsistema al que pertenece, las características del bus y el controlador del kernel en uso, que en este caso es pcieport.

La opción -k, disponible en versiones más recientes de lspci, proporciona otra forma de verificar qué módulo del núcleo del sistema operativo está en uso para el dispositivo especificado:

El resultado del comando lspci -s 00:0b.0 -k indica que se está mostrando información sobre el dispositivo PCI con la dirección 00:0b.0. Este dispositivo es un puente PCI de NVIDIA Corporation, específicamente el puente PCIe MCP73. Además, se indica que el controlador del kernel en uso para este dispositivo es pcieport.

El comando lsusb es similar a lspci, pero enumerando exclusivamente la información de los USB:

El comando lsusb permite visualizar los dispositivos USB conectados al sistema, junto con los puertos USB disponibles. Al usar la opción -v, se obtiene una salida más detallada que incluye información adicional sobre cada dispositivo. Además, se puede especificar un dispositivo específico para inspeccionar, proporcionando su ID con el argumento -d.

Con la opción -t, el comando lsusb muestra las asignaciones actuales de los dispositivos USB en forma de árbol jerárquico:

Es posible que no todos los dispositivos tengan los módulos correspondientes asociados. La comunicación con determinados dispositivos puede ser manejada directamente por la aplicación, sin la intermediación que proporciona un módulo. Sin embargo, hay información significativa en la salida proporcionada por lsusb -t. Cuando existe un módulo coincidente, su nombre aparece al final de la línea del dispositivo, como en Driver=usbhid. El dispositivo Class identifica la categoría general, como Human Interface Device, Wireless, Vendor Specific Class, Mass Storage, entre otros. Para verificar qué dispositivo está usando el módulo btusb, presente en la lista anterior, se deben dar tanto los números de Bus como de Dev a la opción -s del comando lsusb:

El sistema operativo Linux típicamente carga varios módulos del núcleo en un momento dado. Para interactuar con estos módulos, se recomienda usar las herramientas proporcionadas por el paquete kmod. Este paquete ofrece un conjunto de herramientas para tareas comunes relacionadas con los módulos del kernel de Linux, como la inserción, eliminación, enumeración, verificación de propiedades, resolución de dependencias y configuración de alias. Por ejemplo, el comando lsmod muestra todos los módulos cargados en el momento actual.

La salida del comando lsmod se divide en tres columnas:

  • Module .- Nombre del módulo.
  • Size.- Cantidad de memoria RAM ocupada por el módulo, en bytes.
  • Used by.- Módulos dependientes.

Algunos módulos requieren que otros módulos funcionen correctamente, como es el caso de los módulos para dispositivos de audio:

La tercera columna en la salida de lsmod, llamada «Used by«, indica los módulos que dependen del módulo listado en la primera columna para funcionar correctamente. Muchos módulos de la arquitectura de sonido de Linux, identificados con el prefijo «snd«, tienen interdependencias. Durante el diagnóstico del sistema, puede ser útil descargar módulos específicos que estén actualmente cargados. Para esto, se utiliza el comando modprobe, el cual puede cargar o descargar módulos del núcleo del sistema operativo. Para descargar un módulo y sus dependencias, siempre que no estén siendo utilizados por algún proceso en ejecución, se emplea el comando modprobe -r. Por ejemplo, para descargar el módulo snd-hda-intel (relacionado con un dispositivo de audio Intel HDA) y otros módulos relacionados con el sistema de sonido.

En este caso, se señala que el módulo está en uso. Además de cargar y descargar módulos del núcleo del sistema operativo en tiempo de ejecución, es posible modificar los parámetros del módulo durante el proceso de carga del núcleo, similar a pasar opciones a comandos. Cada módulo puede aceptar parámetros específicos, aunque generalmente se recomienda utilizar los valores predeterminados y no necesitar parámetros adicionales. Sin embargo, en ciertas situaciones es necesario utilizar parámetros para ajustar el comportamiento de un módulo y lograr el funcionamiento esperado.

El comando modinfo, utilizado con el nombre del módulo como único argumento, proporciona una descripción detallada del módulo, incluyendo el archivo, autor, licencia, identificación, dependencias y parámetros disponibles. Estos parámetros pueden ser personalizados y hacerse persistentes al incluirlos en el archivo /etc/modprobe.conf o en archivos individuales con extensión .conf en el directorio /etc/modprobe.d/. La opción -p del comando modinfo muestra exclusivamente los parámetros disponibles, ignorando otra información.

La salida muestra todos los parámetros disponibles para el módulo «nouveau«, el cual es un componente del kernel proporcionado por el Proyecto Nouveau. Este módulo se utiliza como una alternativa a los controladores propietarios para tarjetas gráficas NVIDIA. Por ejemplo, la opción «modeset» permite controlar si la resolución y la profundidad de la pantalla se establecerán en el espacio del kernel en lugar del espacio del usuario. Para deshabilitar la función del kernel «modeset«, se puede agregar la línea «options nouveau modeset=0» al archivo «/etc/modprobe.d/nouveau.conf«.

Si un módulo está ocasionando dificultades, se puede evitar su carga mediante la edición del archivo /etc/modprobe.d/blacklist.conf. Por ejemplo, para impedir que el módulo «nouveau» se cargue automáticamente, se añade la línea «blacklist nouveau» a dicho archivo. Esta medida es esencial cuando se ha instalado el controlador propietario «nvidia» y se desea que el módulo predeterminado «nouveau» sea ignorado.

Explorando archivos de información y dispositivos en Linux

Los comandos lspci, lsusb y lsmod proporcionan una interfaz para acceder a la información del dispositivo almacenada por el sistema operativo. Esta información se almacena en archivos especiales dentro de los directorios /proc y /sys. Estos directorios actúan como puntos de montaje para sistemas de archivos que no residen en una partición de disco, sino en el espacio de memoria RAM utilizado por el núcleo del sistema operativo para almacenar configuraciones en tiempo de ejecución y datos sobre procesos en curso. Estos sistemas de archivos, conocidos como pseudo-sistemas de archivos, existen temporalmente solo durante la ejecución del sistema, ya que no están destinados al almacenamiento permanente de archivos. El directorio /proc contiene archivos que proporcionan información sobre los procesos en curso y los recursos de hardware. Algunos archivos importantes en
/proc para la inspección del hardware son:

  • /proc/cpuinfo.- Proporciona información detallada sobre las CPU encontradas por el sistema operativo.
  • /proc/interrupts.- Lista los números de las interrupciones por dispositivo de entrada/salida para cada CPU.
  • /proc/ioports.- Enumera los puertos de entrada/salida registrados actualmente en uso.
  • /proc/dma.- Lista los canales DMA (Acceso Directo a Memoria) registrados en uso.

/sys y /proc son directorios en sistemas Linux que proporcionan información sobre el sistema en tiempo de ejecución. Mientras que /proc contiene información sobre procesos en ejecución y configuración del sistema, /sys está específicamente dedicado a almacenar información del dispositivo y datos del kernel relacionados con el hardware.
En términos generales, /proc se utiliza para acceder a información sobre procesos y configuración del sistema, mientras que /sys se utiliza para acceder a información sobre hardware y datos del kernel relacionados con los dispositivos.

El directorio /dev en sistemas Linux alberga archivos asociados con dispositivos del sistema, especialmente dispositivos de almacenamiento. Por ejemplo, un disco duro IDE conectado al primer canal IDE de la placa base se representará como /dev/hda. Las particiones en un disco duro se identifican agregando números después del nombre del dispositivo. Por ejemplo, las particiones en /dev/hda se representarán como `/dev/h /dev/hda1, /dev/hda2, etc.

Los dispositivos extraíbles son gestionados por el subsistema udev, encargado de crear los dispositivos correspondientes en el directorio /dev. Cuando el núcleo de Linux detecta un nuevo hardware, transmite este evento al proceso udev, el cual identifica el dispositivo y genera dinámicamente los archivos correspondientes en /dev según reglas predefinidas.

En las distribuciones modernas de Linux, udev gestiona tanto la identificación y configuración de dispositivos presentes al encender la máquina (coldplug detection) como aquellos identificados mientras el sistema está en ejecución (hotplug detection). Este subsistema se apoya en SysFS, un pseudo sistema de archivos que almacena información sobre dispositivos en el directorio /sys.

udev busca reglas coincidentes en /etc/udev/rules.d/ cuando detecta nuevos dispositivos. Aunque la distribución proporciona las reglas más importantes, es posible agregar reglas específicas según sea necesario.

Dispositivos de Almacenamiento

En Linux, los dispositivos de almacenamiento se denominan genéricamente dispositivos de bloque, porque los datos se leen desde y hacia estos dispositivos en bloques de datos almacenados en búfer con diferentes tamaños y posiciones. Cada dispositivo de bloque se identifica mediante un archivo en el directorio /dev, con el nombre del archivo según el tipo de dispositivo (IDE, SATA, SCSI, etc.) y sus particiones. Los dispositivos de CD/DVD y disquetes, por ejemplo, recibirán sus nombres correspondientes en /dev: una unidad de CD/DVD conectada al segundo canal IDE se identificará como /dev/hdc (/dev/hda y /dev/hdb están reservados para los dispositivos maestro y esclavo en el primer canal IDE) y una unidad de disquete antigua se identificará como /dev/fdO, /dev/fd1, etc.

Desde la versión 2.4 del kernel de Linux en adelante, la mayoría de los dispositivos de almacenamiento ahora se identifican como si fueran dispositivos SCSI, independientemente de su tipo de hardware. Los dispositivos de bloque IDE, SSD y USB tendrán el prefijo sd. Para los discos IDE, se utilizará el prefijo sd, pero se elegirá la tercera letra dependiendo de si la unidad es maestra o esclava (en el primer canal IDE, el maestro será sda y el esclavo será sdb) Las particiones se listan numéricamente. Las rutas /dev/sda1, /dev/sda2, etc. se usan para la primera y segunda partición del dispositivo de bloque identificado primero y /dev/sdb1, /dev/sdb2, etc., identifican las particiones primera y segunda del dispositivo de bloque identificado en segundo lugar. La excepción a este patrón ocurre con las tarjetas de memoria (tarjetas SD) y los dispositivos NVMe (SSD conectados al bus PCI Express). Para las tarjetas SD, las rutas
/dev/mmcblk0p1, /dev/mmcblk0p2, etc. se utilizan para la primera y segunda partición del dispositivo identificado primero y /dev/mmcblk1p1, /dev/mmcblk1p2, etc. utilizado para identificar la primera y la segunda partición del dispositivo identificado en segundo lugar. Los dispositivos NVMe reciben el prefijo nvme, como en /dev/nvme0n1p1 y /dev/nvme0n1p2.