piscreen-overlay.dtb w1-gpio-pullup-overlay.dtb
i2c-rtc-overlay.dtb pitft28-resistive-overlay.dtb
La descripción completa del código fuente del árbol de dispositivos para la distribución del RPi está en el código fuente del resto del libro en el directorio /chp03/dts.
Espacio del núcleo y espacio de usuario
El núcleo de Linux se ejecuta en una área de la memoria del sistema llamada espacio del núcleo (kernel space), mientras que, por su parte, las aplicaciones normales se ejecutan en el espacio de usuario (user space). Una separación estricta entre ambos espacios en memoria evita que las aplicaciones de usuario accedan al espacio y los recursos requeridos para el funcionamiento del núcleo de Linux. Esto ayuda a evitar que el núcleo se cuelgue a causa del código de usuario mal desarrollado, así como que las aplicaciones de un usuario interfieran en la ejecución de las aplicaciones de otro e invadan su espacio. También proporcionan un grado más elevado de seguridad.
El núcleo de Linux es "propietario" y tiene acceso pleno a toda la memoria física y al resto de los recursos del RPi. Así pues, debemos ser muy cuidadosos y solo permitir que el código más estable y comprobado se ejecute en el espacio del núcleo. Puede observar las arquitecturas e interfaces ilustradas en la figura 3-2, donde las aplicaciones de usuario emplean la librería GNU C (glibc) para comunicarse con la interfaz de llamadas del núcleo del sistema. Luego, los servicios del núcleo se ponen a disposición del espacio de usuario de manera controlada mediante el uso de llamadas del sistema.
Figura 3-2: Las arquitecturas del espacio de usuario y del espacio del núcleo de Linux.
Un módulo del núcleo (kernel module) es un archivo objeto que contiene código binario y que se puede cargar y descargar del núcleo bajo demanda. En muchos casos, el núcleo puede incluso cargar y descargar módulos mientras se está ejecutando, es decir, "en caliente", sin necesidad de reiniciar el RPi. Por ejemplo, si enchufamos un adaptador WiFi USB en el RPi, es posible que el núcleo utilice un LKM (Loadable Kernel Module o módulo cargable del núcleo) para hacerlo funcionar. Sin esta capacidad modular, el núcleo de Linux sería extremadamente grande, puesto que tendría que dar soporte a todos los controladores que el RPi pudiera llegar a necesitar. Asimismo, tendríamos que recompilar el núcleo cada vez que quisiéramos añadir un nuevo hardware. Una desventaja de los LKM es que los archivos de controlador se deben mantener para cada dispositivo. La interacción con los LKM se describe a lo largo de todo el libro, y en el capítulo 16 veremos cómo escribir nuestros propios LKM.
Como se indica en la figura 3-1, las etapas del gestor de arranque (bootloader stages) ceden el control al núcleo después de que este haya finalizado su descompresión en la memoria. Después, el núcleo monta el sistema de archivos raíz. El último paso del núcleo durante el proceso de arranque es la llamada a systemd init (/sbin/init en un RPi con Raspbian Jessie), que es el primer proceso de usuario que se inicia, y también el siguiente tema que vamos a tratar.
El gestor de sistema y servicios systemd
Un gestor de sistema y servicios (system and service manager) inicia y detiene servicios (por ejemplo, servidores web, servidor SSH) dependiendo del estado actual del RPi, es decir, si se está iniciando, apagando, etc. El gestor de sistema
y servicios systemd se ha añadido recientemente, y no sin controversia, a Linux y tiene como objetivo sustituir al gestor System V (SysV) init, al tiempo que mantiene la compatibilidad hacia atrás. Una desventaja grave de SysV init es que inicia los servicios en serie, es decir, que espera a que una tarea finalice antes de comenzar la siguiente, lo que puede alargar el tiempo de arranque del dispositivo. El gestor systemd está activado de forma predeterminada en Debian 8/Raspbian 8 (Jessie) y permite iniciar los servicios del sistema en paralelo, lo que reduce, obviamente, los tiempos de arranque, sobre todo en procesadores multinúcleo como los de los RPi 2/3. De hecho, podemos mostrar la duración de dicho proceso del siguiente modo:
pi@erpi ~ $ systemctl --version
systemd 215 +PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT
+ACL +XZ -SECCOMP -APPARMOR
pi@erpi ~ $ systemd-analyze time
Startup finished in 2.230s (kernel) + 6.779s (userspace) = 9.009s
ADVERTENCIA Si observa el mensaje “command not found” (comando no encontrado) en este punto, lo más probable es que esté usando una distribución Raspbian 7, que emplea SysV init. Para más información, visite la página web de este capítulo: www.exploringrpi.com/chapter3/.
Además de ser un gestor de sistema y servicios, systemd incluye software para gestión de inicios de sesión, archivos de log, gestión de dispositivos, sincronización de tiempos, etc. Los críticos de systemd insisten en que su proyecto de desarrollo ha traspasado sus propios límites y ha ido invadiendo áreas alejadas de su propósito fundamental. Hasta cierto punto, esta invasión de otras áreas ha supuesto que systemd resulte ahora básico para el futuro del propio Linux, hasta el punto de eliminar las posibilidades de elegir de los propios usuarios. Sin embargo, parece claro que systemd goza de una amplia aceptación por parte de las distribuciones Linux y que está aquí para quedarse.
Podemos utilizar el comando systemctl para inspeccionar y controlar el estado de systemd. Si lo invocamos sin argumentos, nos ofrecerá una lista completa de servicios en ejecución en el RPi (para pasar a otra pantalla, pulse la barra espaciadora, y para salir, Q):
pi@erpi ~ $ systemctl
networking.service loaded active exited LSB: Raise network interfaces
ntp.service loaded active running LSB: Start NTP daemon
serial-getty@ttyAMA0 loaded active running Serial Getty on ttyAMA0
ssh.service loaded active running OpenBSD Secure Shell server
getty.target loaded active active Login Prompts ...
El comando systemd uses archivos de servicio (service files), que presentan una extensión service, para definir el comportamiento de los diferentes servicios durante su inicio, apagado, recarga, etc. Véase el directorio /lib/systemd/system.
El servicio del protocolo NTP (Network Time Protocol, protocolo de tiempo de red) se ejecuta por defecto con la propia instalación. El gestor systemd sirve para manejar tales servicios en el RPi. Por ejemplo, podemos identificar el número exacto del servicio y obtener su estado actual del siguiente modo:
pi@erpi:~$ systemctl list-units -t service | grep ntp
ntp.service loaded active running LSB: Start NTP daemon
pi@erpi:~$ systemctl status ntp.service
• ntp.service - LSB: Start NTP daemon
Loaded: loaded (/etc/init.d/ntp)
Active: active (running) since Mon 2016-01-02 13:00:48 GMT; 2h 21min ago
Process: 502 ExecStart=/etc/init.d/ntp start (code=exited, status=0/ SUCCESS)
CGroup: /system.slice/ntp.service
├─552 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:112
└─559 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:112
Podemos detener el servicio ntp con el comando systemctl, momento a partir del que dejará de actualizar el reloj con el tiempo de la red.
pi@erpi:~$ sudo systemctl stop ntp
pi@erpi:~$ systemctl status ntp
• ntp.service - LSB: Start NTP daemon
Loaded: loaded (/etc/init.d/ntp)
Active: inactive (dead) since Mon 2017-01-02 17:42:26 GMT; 6s ago
Process: