Sistema de archivos con Raspberry Pi

Publicado por Loli Diéguez en

En este articulo te enseño los sistemas de archivos en Raspberry Pi y cómo se utilizan para iniciar Linux desde una tarjeta SD. Este es el único método de arranque compatible oficialmente disponible en Raspberry Pi y, aunque está escrito específicamente con Raspberry Pi en mente, muchas otras placas pueden funcionar de manera similar. 

Para comenzar, debemos comprender los conceptos básicos de los sistemas de archivos, ya que la tarjeta SD contiene varias particiones con diferentes tipos de sistemas de archivos. 

En los sistemas operativos Linux y Unix, la utilidad df se puede usar para verificar el espacio en disco, los puntos de montaje y los tipos de sistemas de archivos, entre otras cosas. Es una herramienta muy útil para saber qué sistemas de archivos están disponibles y dónde está montado cada uno, ya que algunos de estos pueden variar según la distribución o la plataforma. 

Ejecutando el df -Th (-Th le dice a df que muestre los tipos de sistemas de archivos y el tamaño en formato legible por humanos, respectivamente) en la Raspberry Pi, podemos ver que hay varios sistemas de archivos diferentes montados.

Comprender la salida de df es importante para comprender cómo funciona Linux. Lo primero que debes tener en cuenta de la salida es que hay un punto de montaje llamado /boot . La existencia de este punto de montaje indica que lo más probable es que el dispositivo haya arrancado desde un sistema de archivos. En muchos sistemas integrados, el sistema operativo arranca directamente desde la memoria flash sin procesar. Admitir un enfoque basado en el sistema de archivos hace que sea más fácil de actualizar y más difícil de bloquear. El usuario solo necesita actualizar los archivos en la tarjeta SD, reiniciar y listo. 

Ahora, es posible que te estés preguntando cómo arrancó Raspberry Pi desde un sistema de archivos. Si es así, entonces echemos un vistazo.

Sistemas de archivos: descripción general

Un sistema de archivos es una pieza de software, generalmente parte del sistema operativo (pero no necesariamente) que almacena datos en algún tipo de memoria no volátil. 

Traduce las llamadas genéricas del sistema operativo, como abrir/cerrar/leer/escribir, etc., a su propio formato y luego almacena los datos en los medioso memoria.

Hay muchos tipos diferentes de sistemas de archivos, algunos de los cuales están diseñados para uso general, mientras que otros son para tipos específicos de hardware (flash, disco duro, etc.) o requisitos de rendimiento (servidores y centros de datos).

Empecemos por ver algunos ejemplos de diferentes medios: 

En los sistemas integrados, la memoria de elección típica es flash, por lo que nos concentraremos en esto. Sin embargo, hay muchos tipos de flash. Las dos categorías principales son flash sin procesar y flash administrada.

En la categoría de memoria flash sin procesar, los dos tipos más comunes son NAND y NOR. Por lo general, vienen con una interfaz en serie, como SPI, o una interfaz paralela. Aunque NAND y NOR son tecnologías fundamentalmente diferentes, ambas funcionan utilizando el concepto de sectores o bloques (sector es para NOR, bloque es para NAND).

Un bloque es la sección más pequeña de la memoria que se puede borrar a la vez. En este tipo de dispositivos, no puede escribir sobre los datos existentes. Cuando es necesario escribir datos, primero se debe borrar el bloque, lo que establece todos los bits en '1'.

Como puedes imaginar, escribir en un dispositivo de memoria sin procesar requiere algún software adicional para poder manejar todos estos detalles. Esto puede degradar el rendimiento y es extremadamente complejo. Para empeorar las cosas, borrar un bloque puede llevar mucho tiempo, del orden de segundos.

Finalmente, ambos tienen un número limitado de ciclos de borrado. Cuando se borran demasiadas veces, los bloques pueden dañarse y ya no se pueden borrar o pueden corromper los datos cuando se escriben o leen, este por ejemplo, es uno de los parametros importanes que tienes que considerar cuando compras discos SSD 

En un dispositivo flash NOR, los ciclos de borrado son típicamente más de 100000 ciclos, mientras que en algunos dispositivos NAND de mayor densidad puede ser tan bajo como 3000 ciclos de programa/borrado.

La física detrás de los bloques defectuosos es diferente entre las dos tecnologías, pero el punto es que se requieren algoritmos especiales para distribuir las escrituras en el dispositivo para que un bloque específico no se borre continuamente. Estos algoritmos se denominan nivelación de desgaste. Tanto la nivelación del desgaste como el seguimiento de los bloques defectuosos es responsabilidad del sistema de archivos. Ejemplos de sistemas de archivos para dispositivos de memoria flash sin procesar son UBIFS, YAFFS.

La otra categoría de tecnología de memoria flash es la memoria administrada. Si bien la mayoría de las veces la memoria subyacente se basa en NAND, estos dispositivos administran los bloques defectuosos y la nivelación del desgaste sin ninguna interacción con el software. Tienen su propio controlador de memoria y firmware integrados que se encargan de la nivelación del desgaste y la gestión de bloques defectuosos por ti.

Las tarjetas SD, así como las llaves (e)MMC y USB son ejemplos de memoria administrada. Debido a que la memoria administrada maneja todo lo específico de flash en el hardware, puede ejecutar cualquier sistema de archivos genérico en el dispositivo con una confianza razonable.

Las tarjetas SD suelen utilizar el sistema de archivos FAT. FAT significa tabla de asignación de archivos, que se refiere a la forma en que el sistema de archivos almacena metadatos para el volumen. FAT tiene algunos formatos diferentes que dependen del tamaño del dispositivo, como FAT16, FAT32 y exFAT.

FAT32 es el estándar de facto para la mayoría de los dispositivos de memoria masiva, como llaves USB, tarjetas SD y MMC. Esto se debe a que es bien conocido y relativamente fácil de entender e implementar, especialmente para entornos con recursos limitados. FAT a veces se denomina vfat, o un sistema de archivos DOS.

La partición de arranque de Raspberry Pi

Los dispositivos como Raspberry Pi no solo arrancan directamente en Linux. Tienen un gestor de arranque que se ejecuta primero y carga el sistema operativo. Sin embargo, lo que quizás no sepas es que en realidad hay varias etapas del gestor de arranque que se ejecutan, cada una de las cuales es responsable de configurar alguna función de hardware específica en preparación para la siguiente etapa. Esto es muy común en otros dispositivos de esta clase, como el Beaglebone.

El cargador de arranque de primera etapa a menudo se denomina arranque de ROM porque el firmware se graba directamente en el chip durante la fabricación, por lo que no se puede actualizar. Por lo tanto, tiene sentido que los diseñadores de chips y los ingenieros de firmware admitan un sistema de archivos muy conocido, ampliamente implementado y fácil de implementar como FAT. El arranque de ROM en Raspberry Pi en realidad se ejecuta en la GPU, no en la CPU, y su trabajo es leer el sistema de archivos FAT32 de la tarjeta SD, buscar un archivo llamado bootcode.bin, carga ese archivo en la memoria (caché en este punto) y luego ejecútalo. Abriendo el directorio /boot que vimos usandodf , podemos comenzar a ver cómo funciona el proceso de arranque.

Podemos ver aquí en el directorio /boot que hay un archivo llamado bootcode.bin. Este es el cargador de arranque GPU de segunda etapa. Es responsable de configurar la SDRAM y cargar el firmware de la GPU desde la tarjeta SD. Se requiere SDRAM en este punto probablemente porque el caché no es lo suficientemente grande para cargar el firmware de la GPU. El otro componente de bootcode.bin es un cargador ELF. Esto es necesario porque el firmware de la GPU es start.elf. 

Un archivo ELF es un tipo de archivo de objeto que se crea fuera del compilador. Contiene el código de máquina pero también contiene información sobre dónde cargar cada sección de código en la memoria.

El firmware de la GPU es responsable de leer los datos de configuración de la tarjeta SD y cargar el kernel. Hay varios archivos en el directorio que forman parte de este proceso:

  • kernel.img: el propio kernel en el formato de archivo zImage, un tipo de imagen comprimida
  • fixup.dat: divide la SDRAM entre la GPU y la CPU.
  • *.dtb: el árbol de dispositivos blobs y superposiciones (en el directorio de superposiciones)
  • cmdline.txt: los parámetros de la línea de comandos del núcleo
  • config.txt: más configuración del sistema operativo

Entraremos en esto con un poco más de detalle en breve, pero para terminar con el firmware de la GPU, una vez que ha cargado todos estos archivos en la memoria, entonces es cuando el control se transfiere de la GPU a la CPU.

Árbol de dispositivos

Todos los archivos con la extensión .dtb son blobs de árbol de dispositivos (.dtb). 

El árbol de dispositivos es un estándar abierto que se utiliza para describir el hardware. Usando un árbol de dispositivos, se puede compilar una sola imagen del kernel que puede soportar múltiples placas usando el mismo procesador. En versiones anteriores del kernel, había un archivo C que describía el hardware, lo que significa que el soporte del hardware se compilaba directamente en el kernel. 

Existen múltiples archivos .dtb para admitir las múltiples revisiones y tipos de placas Raspberry Pi. El gestor de arranque elige el archivo que se aplica a la placa en la que se ejecuta y lee el árbol de dispositivos correcto de la tarjeta SD.

Luego se pasa al kernel de Linux, que al arrancar, carga los controladores apropiados según lo que encuentra en el árbol de dispositivos. Los árboles de dispositivos se escriben en texto sin formato. Hay muchas especificaciones según la arquitectura, el tipo de controlador, etc. El archivo de árbol de dispositivo de texto sin formato que escriben los humanos tiene la extensión .dts. Se compila en un archivo binario .dtb mediante un compilador de árbol de dispositivos.

Dentro del directorio de arranque hay otro directorio llamado 'superposiciones'. Este contiene varias superposiciones de árboles de dispositivos que se pueden habilitar mediante el archivo config.txt. El firmware de la GPU combina el blob del árbol del dispositivo base con cualquier superposición que se haya definido en config.txt. Esto le permite agregar fácilmente soporte para otros periféricos de hardware, suponiendo que el soporte compatible para ellos esté compilado en el kernel (o incluido como módulos del kernel).

Sistema de archivos raíz

Hay un componente crucial más requerido por el kernel de Linux para arrancar: el sistema de archivos raíz (rootfs). La imagen del kernel solo incluye los componentes de bajo nivel: el kernel real, los controladores y algunas utilidades. Por sí mismo, es bastante inútil.

El rootfs contiene todo lo demás en lo que pensamos cuando usamos una distribución de Linux: todas las funciones de nivel de usuario y las utilidades del sistema. Después de que el kernel cargue todos los controladores, busca en rootfs y llama al programa init. Dependiendo de la distribución construida, la inicialización puede cambiar sustancialmente, pero básicamente cargará todas las funciones que enfrenta el usuario, como la consola y la línea de comandos, soporte para el usuario, una interfaz gráfica si la hay, etc. Todas las utilidades estándar de Linux que usamos  se construyen bases diarias como parte de rootfs.

Volviendo a nuestra salida de df una vez más, podemos ver que la primera entrada es /dev/root , que está montada en / . Este es el sistema de archivos raíz. Sin embargo, una cosa a tener en cuenta aquí es que /dev/root no es en realidad un dispositivo. Los parámetros de la línea de comandos del kernel nos dicen que el dispositivo real está en /dev/mmcblk0p7, donde mmblk0 representa la interfaz de la tarjeta SD y p7 representa la partición en ese dispositivo.

Recuerda cómo dijimos anteriormente que la tarjeta SD estaba formateada con FAT32. Bueno, en realidad solo había una partición. El instalador de NOOBS en realidad divide la tarjeta SD en varias particiones. Esta partición es para rootfs y tiene el formato ext4. Ext4 es un sistema de archivos específico de Linux, un sistema de archivos de diario que se usa comúnmente en casi todas las distribuciones principales de Linux. ¿Pero esto se está ejecutando en una tarjeta SD, dices? Sí, es cierto, una tarjeta SD, como vimos anteriormente, es memoria administrada. Por lo tanto, podemos tratarlo como lo haría con un disco duro normal. De hecho, las unidades de estado sólido (SSD) utilizan la misma tecnología de memoria que las tarjetas SD... pero hay mucho más.

Entonces, ¿qué hay en rootfs? Bueno, rootfs está definido por el Estándar de jerarquía del sistema de archivos (FHS), que fue creado por la Fundación Linux para ayudar a estandarizar las distribuciones. 

Echemos un vistazo:

A continuación muestro una breve descripción de cada uno, parafraseada de la especificación con algunos de mis propios comentarios:

/bin : directorio donde van los ejecutables del sistema (como los comandos) y están disponibles para todos los usuarios.

/boot : contiene todos los archivos requeridos por el gestor de arranque para iniciar el kernel.

/dev : este directorio en realidad no es parte de rootfs, se crea cada vez que se inicia y contiene archivos que representan cada uno de los dispositivos a los que se puede acceder en el espacio del usuario (mira la salida de df para ver que es un especial tipo de sistema de archivos llamado devtmpfs).

/etc : donde se almacenan los archivos de configuración del sistema y de la aplicación.

/home : contiene otro directorio 'privado' para cada usuario. Todos los archivos personales del usuario normalmente se almacenan aquí. Mis documentos, escritorio, descarga, etc., todos forman el directorio /home de un usuario.

/lib : el directorio donde se almacenan las bibliotecas compartidas y los módulos del kernel. Cuando compila y necesita vincular bibliotecas, este es un directorio al que normalmente apuntaría el vinculador.

/media : el punto de montaje predeterminado para dispositivos extraíbles; por ejemplo, si conectas una llave USB

/mnt : es el punto de montaje predeterminado para sistemas de archivos temporales (es decir, recursos compartidos de red)

/opt : Solía ​​ser donde se instalaban algunas aplicaciones de terceros, supuestamente para aplicaciones complementarias.

/proc : otro directorio virtual que no es realmente parte del sistema de archivos raíz. En él se encuentran archivos que representan cada uno de los procesos del sistema.

/root : el directorio de inicio para root

/run : un directorio para que las aplicaciones almacenen datos durante el tiempo de ejecución. En realidad, esto no es parte de rootfs, es un directorio temporal creado en tiempo de ejecución.

/sbin : contiene ejecutables como el directorio /bin, pero normalmente solo los usan el sistema y el administrador.

/sys : otro sistema de archivos virtual que expone algunas de las interfaces de hardware en el kernel. Proporciona una forma de ver la configuración del kernel del hardware. Aunque no se recomienda, puede acceder a algún hardware a través de esta interfaz (es decir, leer/escribir GPIO, LED, etc.)...

/tmp : un sistema de archivos temporal, que en realidad no forma parte del sistema de archivos. Esencialmente, un disco RAM que pueden usar las aplicaciones y el sistema para almacenar archivos temporales

/usr : un directorio donde se almacenan los archivos binarios, las bibliotecas, los archivos de encabezado y la documentación de la aplicación del usuario. Por lo general, los archivos aquí son todos de solo lectura. En algunas distribuciones, este directorio está en una partición separada del sistema de archivos raíz.

/var : otro directorio donde se puede almacenar la información del tiempo de ejecución de la aplicación para que no termine en el directorio /usr. Normalmente se utiliza para registros, cerraduras. Algunas funciones reemplazadas por el directorio /run pero mantenidas por compatibilidad.

Una cosa importante a tener en cuenta es que diferentes distribuciones, aplicaciones, etc… gestionan y utilizan estos directorios de forma diferente. No siempre es tan simple, y para mantener la compatibilidad, muchos mantenedores de distribución prefieren mantener los archivos y directorios heredados en lugar de desaprobarlos.

La especificación FHS contiene pautas sobre cómo las aplicaciones deben usar estos directorios, pero eso no significa que todos los desarrolladores de aplicaciones las sigan. Es solo una guía y variará incluso de una versión a otra de la misma distribución o aplicación.

Lo importante de todo esto es que el sistema de archivos raíz es imprescindible para el funcionamiento de Linux. Puede iniciar el kernel, pero no pasará mucho después. El sistema de archivos se puede construir para satisfacer tus propias necesidades: incluir utilidades específicas, aplicaciones, etc., lo que te da la libertad de tener un sistema de archivos realmente grande, como el de Ubuntu, que requiere 4 GB directamente desde el primer momento, a un sistema de archivos realmente pequeño.

Bueno, despues de este articulo seguro que ya sabes un poco mas sobre el sistema de archivos de la Raspberry Pi y Raspbian, espero que tengas menos dudas al respecto

SI QUIERES LEER MAS, AQUI TIENES OTROS ARTICULOS INTERESANTES


Compartir esta publicación



← Publicación más antigua Publicación más reciente →