¿Cómo funciona una computadora?: ¿Qué pasa cuando pulso la tecla A? – Teoría

El título puede parecer algo estúpido, pero qué mejor forma de explicar paso a paso cómo funciona un ordenador a nivel interno que describir lo que ocurre a nivel de hardware y de software cuando se aprieta una tecla como la A. Un procedimiento sencillo, pero que es suficientemente simple para entender cómo trabajan todos los componentes que intervienen en el proceso.

Un proceso descrito de una forma muy simple, ideal para los iniciados que podrán entender cómo funciona un ordenador. No emplearé demasiados detalles muy técnicos, ya suficiente complejos son los ecosistemas actuales como para agregar además distracciones. Y es que las computadoras se han vuelto muy complejas en la actualidad, no son como las de los años 70s u 80s, en las que se podía entender cómo trabajaban de una forma fácil…

¿Qué sucede cuando pulso la letra A?

Esquema de cómo funciona un ordenador

Bien, imagina que tienes un editor de texto ejecutándose en tu equipo. Y vas a comenzar a escribir un texto. La primera letra que tienes que escribir es la A, y procedes a presionar esta tecla en tu teclado. Cuando presionas la tecla, de forma instantánea aparece la letra en el editor. Pero para que eso ocurra, desde que presionas la tecla hasta que aparece, hay una serie de procesos que se van sucediendo. No ocurre como por arte de magia es todo un recorrido, un viaje al que te invito a unirte…

Algunos pasos se superponen, pero he intentado seguir un orden algo más lógico…

1 – Mecánica del teclado

Básicamente, cuando presionas la tecla, ésta hace que una matriz de pistas bajo el teclado genere un pulso eléctrico único, ya que cada tecla activa una pista (fila / columna) diferente.

Suele haber switch o interruptores mecánicos trabajando con resistencias pull-up en estos casos. Pero esto tampoco es interesante describirlo ahora… También habrá un multiplexor trabajando con todas esas filas y columnas de teclas que existen en un teclado común.

2 – Circuitería del teclado

El circuito de control del teclado interpretará la el Scan code recibido por la tecla y lo almacena en un buffer o memoria intermedia. Todo esto sigue siendo dentro del teclado. Así, la circuitería del teclado (procesador embebido dentro del teclado) podrá almacenar la señal correspondiente a la letra A, y seguir haciendo lo mismo con otras teclas que se pulsen a continuación si hiciera falta.

3 – Envío de la señal

El controlador dentro del teclado, según el tipo de protocolo de comunicación, habrá traducido la señal de la tecla en el mensaje adecuado para el protocolo, por ejemplo, por USB (necesitará enviar una serie de pulsos eléctricos alternando voltajes entre 0 y 5v). Es decir, el dato almacenado en el buffer se puede enviar en forma de señal a través de la interfaz por la que esté conectado tu teclado al ordenador (PS/2, USB, Bluetooth, IR…).

4 – Controlador del teclado

En la placa base, cuando llegue la señal, habrá un controlador del teclado, un chip que se encargará de procesar las señales que vayan llegando o saliendo por la interfaz a la que controla. Por ejemplo, si es un teclado USB, será un chip controlador de USB el que se encargue de ello.

No lo confundas con el driver o controlador de software, el controlador físico es un circuito integrado que tendrá un firmware que trabajará estrechamente con el driver de software. Pero no son lo mismo…

Este controlador, interpretará esa señal recibida y la traducirá en un dato apropiado para que la CPU pueda trabajar con él. Enviará una interrupción de hardware a la CPU. Esto sucede poniendo una señal IRQ1 / INT9 (esto variará en función de la arquitectura). De ese modo, la CPU sabrá que debe atender esta petición.

Por cierto, aquí también entraría en juego el sistema DMA, si es un equipo moderno y lo soporta. Pero obviaré eso para no agregar más variantes y complicar todo…

5 – CPU

La CPU detiene lo que estaba haciendo y atenderá la interrupción que le ha llegado desde el sistema E/S, realizando una rutina especial. Recuerda que este E/S será como una memoria más para la CPU, en la que puede leer y escribir.

El procesador invocará al Interrupt Handler, es decir, el sistema que se encarga de gestionar este tipo de interrupciones. Eso generará unos ciclos de búsqueda de direcciones de memoria de un programa especial llamado ISR (Interrupt Service Routine) de la IVT (Interrupt Vector Table) que mantiene el kernel del sistema operativo.

ISR leerá el código con una serie de instrucciones y datos que se irán introduciendo en el cauce de la CPU para que las pueda procesar y luego pase nuevamente el control al programa que estaba ejecutando.

6 – Sistema operativo / app

El kernel será el que vea dicha interrupción, y el que despachará el código de interrupción correspondiente al driver del teclado. Entonces será cuando la CPU atienda a éste código.

Recuerda que el sistema operativo está siempre en constante ejecución. Será una de las partes del kernel la que esté atenta a la presión de las teclas para reaccionar, y lo hace trabajando estrechamente con el driver asignado para el hardware que se está manejando (si es un teclado USB, sería el driver USB). Aquí debes tener en cuenta que la aplicación (en este caso el editor de texto) se está ejecutando en el espacio de usuario (no es código privilegiado) y por tanto no puede manejar los recursos de hardware.

Por tanto, será el kernel del sistema operativo (código privilegiado), mediante la ejecución de llamadas al sistema (syscall) que se inician con dichas interrupciones, el encargado de gestionar estos recursos de hardware. Es decir, la app le hace la petición al kernel y el kernel la atenderá.

En este caso sería capturar un código ASCII o Unicode correspondiente a la tecla A. Una vez obtenido dicho código por parte del hardware, el SO devolvería el control nuevamente al código de la app para que prosiga la CPU ejecutando sus instrucciones. En ese momento, el editor de texto capturaría el evento dejado por el kernel, es decir, en este caso mostraría la A en pantalla.

Pero desde que el kernel asume el control hasta que lo devuelve a la app, han ocurrido varias cosas también. Por ejemplo, los teclados USB usan un estándar llamado HID (Human Interface Device), con un descriptor que le dirá al kernel que tipo de señal pueden emitir y con códigos para las teclas incluidos.

Por ejemplo, en Linux, puedes encontrar un dispositivo de comunicación crudo (raw) HID en el dispositivo /dev/hidrawX. Esta información cruda será traducid. Es decir, los datos scan codes recibidos de la señal física del teclado correspondientes a la tecla A se convierten en key codes, los correspondientes a nivel lógico a dicha tecla A. En este caso disponibles en /dev/input/eventX (si trabajas en Linux, puedes usar evdev para ver los eventos y otras herramientas como showkey, dumpkeys, etc., para ver la tabla de traducciones).

#Prueba a ejecutar estos comandos mientras teclea algo en tu teclado y mueve el ratón para ver su efecto

sudo cat /dev/hidraw0
sudo cat /dev/hidraw1
sudo cat /dev/hidraw2

#Puedes ver que van apareciendo las letras que presionas y una serie de símbolos cuando mueves el cursor

#Otra cosa que puedes hacer es hacer lo mismo para el teclado con:
sudo cat /dev/input/event0

#O para el ratón, mientras lo mueves para ver qué ocurre, con:
sudo cat /dev/input/mouse0

#Te invito también a experimentar con /dev/stdin y /dev/stdout, es decir, los FD o descriptores de archivo de los que ya comenté algo en la serie de artículos sobre LPIC cuando hablé de las pipes y redirecciones, etc....

Recuerda también que el driver también le comunicará al kernel un evento de «Key_Down»  para el subsistema de la interfaz de usuario, ya sea modo texto o gráfica. Este código despachado por el kernel también debe ser atendido por la CPU para que se atienda a la ventana activa y se muestre la letra. Dicho de otro modo, el driver HID, por poner un ejemplo, también «hablará» con el sistema gráfico para que la pila gráfica envíe el mensaje (en este caso la letra A) a la ventana o proceso correspondiente (en este caso el editor de texto).

En el caso de Unix/Linux trabajando con un entorno de escritorio, la cosa se complica algo más con las capas de las que se componen la pila gráfica… Aquí entraría en juego el servidor gráfico X, o Wayland, etc., para traducir esos códigos en key symbols, es decir, en el gráfico de la letra A en este caso. Luego trabajaría también el gestor de ventanas con la ventana del cliente o app, etc. Pero esto ya es otro tema y no me gustaría confundirte…

Si quieres experimentar puedes usar el comando xev para que muestre los eventos que están sucediendo a nivel del servidor gráfico. En la consola puedes usar showkey si lo tienes instalado. Ten en cuenta que si presionas la tecla A en ambos, el valor será diferente. Eso es porque en xev se informa de los códigos de escaneo y en showkey se informa del key code. Es decir, al pulsar la tecla A verás el valor 38 y 30 respectivamente…

#Ver los eventos del servidor gráfico cuando mueves el ratón o tecleas algo con
xev

Otra posibilidad es el comando screenkey, si la tienes instalada. Aunque en este caso es una simple herramienta de screencast para mostrar las teclas presionadas. Más interesante aún es xinput:

#Localiza el número ID de tu teclado con
xinput list

#En mi caso era el 9, por ejemplo, y ahora podrás ver lo que tecleas con
xinput test 9

#Pulsa teclas y verás los códigos

Y hay más opciones para esto, como evtest, etc.

6.1 – Syscall

Me gustaría detenerme de forma más específica en esa llamada al sistema. Es interesante saber cómo funciona para entender mejor todo el proceso.

Poniendo Linux como ejemplo, se necesitaría una llamada sys_read para leer el dato que llega desde el teclado, y sys_write para imprimir el dato en pantalla en este caso. Por ejemplo, en el caso de la segunda, con una instrucción mov eax,4 se movería el valor 4 al registro EAX de la CPU x86, lo que  indicaría que es esa syscall concreta para la escritura y no otra. Aunque en los modernos procesadores existe ya una instrucción call (véase syscall/sysret de AMD o las sysenter/sysexit de Intel), antes se hacía mediante una interrupción con int 0x80 para que la CPU atendiese dicha llamada.

De este modo es como un programa no privilegiado puede hacer peticiones al kernel para que pueda gestionar ciertos recursos de hardware que solo se pueden gestionar desde el código privilegiado. Recuerda el esquema de anillos que he mostrado anteriormente.

Una vez esto es procesado por la CPU, se transfiere el control al código privilegiado necesario, en este caso al subsistema para la gestión del teclado y el driver. Eso haría que la ejecución del programa que la invocó se interrumpa, es decir, el editor de texto se detendría para que se atienda este otro código.

Los datos del editor de texto, en este caso, no se borrarán. Se necesitan para luego recuperar su estado y seguir ejecutándolo. Por eso se almacenan los datos y estado en el PCB (Process Control Block). De esa forma, una vez atendida la llamada se podrá seguir por donde se dejó. El PCB no es más que un registro mantenido por el sistema operativo para guardar información de los procesos en marcha. Por ejemplo, mantendrá el PID, estado, valor del registro PC de la CPU, espacio de memoria delimitado, prioridad, propietario, permisos, etc.

En Linux se usan la syscall system() para crear procesos de forma rápida y simple, pero se recomienda usar fork() y exec() por motivos de seguridad, velocidad y flexibilidad, aunque sea algo más complejo. Recuerda que el planificador del kernel Linux no sabe distinguir entre un proceso y un LWP (thread). Para más información, puedes leer el artículo de la serie LPIC sobre gestión de procesos…

Durante la atención de esta llamada al sistema, la propia llamada tiene una rutina, un programa o código con una serie de instrucciones y datos que la CPU debe procesar para poder realizar lo que quiera que sea. Por ejemplo, en el caso de una llamada para leer un valor, pues lo necesario para que ese dato del teclado creado al pulsar A se pueda captar.

Dicho de otro modo, la CPU estaría ejecutando el programa (en este caso editor de texto), se detiene por la interrupción para atender la llamada al sistema. El kernel hará que la CPU apunten hacia una nueva dirección de memoria que deberá ejecutar para realizar esa rutina. Al finalizar la rutina, se vuelve a recuperar el proceso del programa desde el PCB y la CPU continúa por donde lo dejó.

7 – GPU

GPU cómo funciona

Pero claro, para que la app muestre ese código en forma de gráfico, es necesario la intervención de otro elemento: la GPU. Ella será la encargada de que se pueda mostrar dicha imagen en la pantalla. Para eso, la CPU procesará el código del programa en el que está trabajando y enviará una serie de instrucciones que necesita que ejecute la GPU.

7.1 – ¿Cómo trabaja la GPU?

Las tareas gráficas serán delegadas por parte de la CPU en la GPU. La CPU será la que ordene lo que debe hacer la GPU. Es decir, según el código que está ejecutando la CPU en ese momento para la app y kernel del SO, se irán generando una serie de operaciones referentes a los gráficos que será este otro procesador el que los haga.

La GPU generará gráficos 2D y 3D, e proceso no es exactamente igual, pero aquí te mostraré los pasos de una forma simple para que lo comprendas:

  1. Modelado: se necesita un modelo de la imagen que hay que crear. La superficie del objeto a recrear, en este caso la letra A, se presenta como una combinación de triángulos mediante coordenadas X, Y y Z. Se especificará también el color y la normal de la superficie de cada vértice. No se pueden perfilar curvas, por eso se necesitan muchos de ellos para que la imagen parezca realista. Evidentemente, en el caso de una letra la cosa es más sencilla que cuando se trata de un videojuego, etc.
  2. Iluminación: los objetos generados por el modelado se iluminarán y se sombrean para darles realismo, en caso de ser necesario. Evidentemente, para un editor de texto simple y para una letra, esto no es necesario. Pero cuando la GPU conoce la luz y orientación, podrá calcular mediante algoritmos matemáticos las sombras y tonalidades del color elegido, así como otras propiedades.
  3. Texturización: se aplican las texturas necesarias a la superficie creada, afectando al color y generando los píxeles finales. En el caso de la letra es un color sólido y simple, a no ser que se usen fuentes y decoraciones 3D de letras…
  4. Mezcla: ahora se mezcla el color almacenado en la VRAM para que pueda ser representado en la pantalla. Mediante la técnica z-buffer, permitirá que los objetos se muestren en escena de forma adecuada. Los más alejados, los más cercanos, etc., superponiéndolos. En este caso, la A se debe superponer al fondo del editor de texto. En caso de que hubiese transparencias, también se tratan aquí.
  5. Presentación: ahora la imagen está preparada para mostrarse en pantalla. Pero está en digital, es decir, si se usa una interfaz o conector analógico como el que empleaban algunos antiguos monitores, entonces deberá pasar por un chip llamado RAMDAC que pasará de digital a analógico. En caso de ser una interfaz digital, no se necesitará ese paso adicional.
OpenGL vs Vulkan
Fuente: Khronos Group

Por supuesto, se necesita de una API gráfica entre el software y los controladores de la gráfica que se comunican a un nivel más bajo con la GPU. Esa API en Linux podría ser OpenGL o Vulkan. Ellas facilitarán el trazado de entidades gráficas elementales como líneas, polígonos, etc.

8 – Montior

La GPU, tras todo ese proceso, enviará una señal (digital o analógica, en función de la interfaz) a través de la interfaz a la que esté conectado el monitor (DVI, VGA, DisplayPort, HDMI,…) y el monitor refrescará su matriz de imagen actual para que aparezca la A, etc.

Isaac

Apasionado de la computación y la tecnología en general. Siempre intentando desaprender para apreHender.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

A %d blogueros les gusta esto:

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar