# Linux a dieta. Reducción de los requisitos de RAM de Bodhi Linux Hay muchas tareas que son más fáciles de resolver en GNU/Linux que en otros lugares, por lo que las máquinas virtuales de Linux son comunes en estos días. Y cuanto menos ocupe una máquina virtual de este tipo en el disco y en la memoria, mejor. En este artículo, tomaré la distribución Bodhi Linux como base y mostraré cómo reducir sus requisitos de RAM para que se ejecute en máquinas con 512 MB en lugar de los 768 MB requeridos oficialmente. Las recomendaciones descritas son relevantes para todas las versiones modernas de Ubuntu. Bodhi Linux 6.0 es una distribución un tanto idiosincrásica, pero fue la que elegí. ¿Por qué? Primero, está basado en Ubuntu 20.04 LTS, lo que te da acceso a una gran cantidad de programas en los repositorios oficiales de Ubuntu. En segundo lugar, Ubuntu tiene una gran comunidad a la que recurrir. En tercer lugar, me gustó el entorno gráfico ligero de Moksha Desktop . Sí, ella tiene matices en la configuración, pero solo necesitas lidiar con ellos una vez. Y en cuarto lugar, esta distribución es minimalista, pero contiene herramientas de Build Essential que te permiten compilar algo rápidamente. Por lo tanto, Bodhi Linux requiere 768 MB de RAM para instalarse, que se puede reducir a 384 MB en un sistema en ejecución y aún utilizable. Esta economía le permite crear un conjunto decente de máquinas virtuales, por ejemplo, para simular configuraciones de red. Si puede ajustar la cantidad de memoria en una máquina virtual en unos segundos, entonces para instalar Bodhi Linux en una computadora obsoleta con 512 MB de RAM, tendrá que buscar e instalar una barra de memoria adicional en algún lugar. Y al final, ¿por qué Bodhi Linux (y muchas otras distribuciones modernas) son tan glotones en la etapa de instalación, aunque luego pueden funcionar en un entorno mucho más modesto? Para responder a esta pregunta, debe ver cómo se carga Bodhi Linux desde los medios de distribución (en el diagrama a continuación). En primer lugar, el cargador del sistema operativo coloca el kernel de Linux con el contenido empaquetado del sistema de archivos mínimo (MFS) de los medios en la RAM , forma el entorno del kernel con parámetros de línea de comandos y transfiere el control al kernel. El kernel recibe parámetros del entorno y los tiene en cuenta, determina e inicializa el hardware principal de la computadora, luego de lo cual desempaqueta el MFS e inicia el proceso de inicio, cuyo texto del script está contenido en el archivo del sistema de archivos desempaquetado ./casper/vmlinuz/casper/initrd.gz/init Uso de RAM al arrancar Bodhi LinuxUso de RAM al arrancar Bodhi Linux La tarea principal del proceso de inicio en esta etapa es encontrar la imagen del sistema de archivos principal en los medios , cambiar a ella desde el MFS y comenzar su continuación. Esto puede requerir módulos de kernel con controladores de dispositivos que sirvan a los medios de distribución y brinden comprensión de su sistema de archivos. Estos controladores, si no están integrados en el kernel, deben estar disponibles en el MFS./casper/filesystem.squashfs WWW Usando el disco RAM inicial (initrd) Ramfs, rootfs e initramfs Después de cambiar al sistema de archivos principal, el MFS ya no es necesario y la memoria RAM que ocupa se libera. El sistema de archivos squashfs le permite trabajar con él en modo de solo lectura directamente desde el archivo de imagen. A partir de ahora, la memoria RAM se utiliza principalmente para los siguientes fines: almacenar el código de los procesos en ejecución y los datos que procesan; almacenar los cambios que ocurren en el sistema de archivos principal (esto se implementa usando el mecanismo overlayfs: el árbol de directorios del sistema de archivos virtual tmpfs creado en RAM se superpone al árbol de directorios del sistema de archivos principal squashfs); otros cachés y búferes del sistema. WWW Sistema de archivos de superposición tmpfs ¿En qué etapa surge el problema en la secuencia de estos pasos? Para averiguarlo, iniciemos Bodhi Linux en una máquina virtual con 512 MB de RAM. Y casi inmediatamente después de seleccionar Probar Bodhi o Instalar ahora en el menú de arranque, aparece una pantalla negra de la muerte con muchos mensajes de diagnóstico. A pesar de que el veredicto final suena como "Kernel panic - not syncing: No working init found" ("Error al desempaquetar initramfs: error de escritura"). Esto significa que el kernel no pudo descomprimir el MFS debido a la falta de RAM.initrd.gz CAUSA DEL PROBLEMA ¿Por qué no había suficiente memoria? En general, en esta etapa, el kernel y el MFS archivado están en la RAM. Durante el arranque, el kernel de Linux asigna, mueve y libera activamente áreas de memoria. Si no es un desarrollador del kernel, es bastante difícil hacer un seguimiento de todas las acciones realizadas. Afortunadamente, cuando la situación se estabiliza, el kernel genera un mensaje informativo y puede averiguar el "puntaje final" usando el comando $ dmesg | grep ']\sMemory' A continuación se muestran los resultados de su ejecución para el rango de RAM de 384 a 1024 MB en incrementos de 128 MB: 384 Мб: [ ] Memory: 263248K/392760K available (14339K kernel code, 2400K rwdata, 5008K rodata, 2732K init, 4972K bss, 129512K reserved, 0K cma-reserved) 512 Мб: [ ] Memory: 392272K/523832K available (14339K kernel code, 2400K rwdata, 5008K rodata, 2732K init, 4972K bss, 131560K reserved, 0K cma-reserved) 640 Мб: [ ] Memory: 520528K/654904K available (14339K kernel code, 2400K rwdata, 5008K rodata, 2732K init, 4972K bss, 134376K reserved, 0K cma-reserved) 768 Мб: [ ] Memory: 649552K/785976K available (14339K kernel code, 2400K rwdata, 5008K rodata, 2732K init, 4972K bss, 136424K reserved, 0K cma-reserved) 896 Мб: [ ] Memory: 778576K/917048K available (14339K kernel code, 2400K rwdata, 5008K rodata, 2732K init, 4972K bss, 138472K reserved, 0K cma-reserved) 1024 Мб: [ ] Memory: 907600K/1048120K available (14339K kernel code, 2400K rwdata, 5008K rodata, 2732K init, 4972K bss, 140520K reserved, 0K cma-reserved) Con base en esta información, podemos concluir que la cantidad de memoria ocupada por el proceso del kernel con segmentos de código (código del kernel), constantes (rodata), datos mutables no inicializados (rwdata) e inicializados (bss) es constante y es de 29.451 KB o aproximadamente 29 MB. La cantidad de memoria adicional reservada por el kernel depende en cierta medida de la cantidad total de RAM en la computadora, pero está determinada principalmente por el tamaño del archivo . Podemos decir que el valor reservado es la suma del tamaño del proceso del kernel (29 MB), el archivo (87 MB) y las estructuras del sistema (10-20 MB).initrd.gzinitrd.gz Cómo contar la memoria si no es suficiente Para obtener el registro de mensajes del núcleo a 384 MB y 512 MB de RAM, cuando el núcleo no puede descomprimir el MFS, redirija la consola al puerto serie ttyS0 agregando opciones del núcleo en la línea de comandos del cargador de arranque: console=ttyS0 console=tty0 ignore_loglevel Y el puerto en sí se redirige a un archivo configurando la máquina virtual VirtualBox, como se muestra en la figura. En otros casos, cuando hay suficiente RAM para descomprimir el MFS, puede asignar una interrupción al proceso de inicio después de cargar suficientes controladores para montar las unidades. Para hacer esto, debe agregar break=mount. Cuando aparece el símbolo del sistema de BusyBox, puede montar manualmente la unidad principal en el MFS y guardar la información necesaria en él. Ahora podemos calcular que la cantidad de RAM libre en esta etapa es 512 - 128 = 384 MB. Esto es bastante, considerando que la única tarea del núcleo es descomprimir el MFS de un archivo comprimido por el algoritmo LZ4. Ahora es el momento de recordar que al descomprimirse, este sistema de archivos ocupa 242 MB, y para almacenarlo, se debe restar esta cantidad al espacio libre disponible: 384 - 242 = 142 MB. Pero sigue siendo un margen decente. La máquina de estado implementada en el módulo init/initramfs.c se ocupa de desempaquetar y al mismo tiempo formar el MFS . Asigna memoria de búfer según sea necesario, que se libera por completo solo después de completar su trabajo. Por lo tanto, en las condiciones descritas, la RAM libre se agota en el momento de la formación de 384/2 = 192 MB MFS de los 242 MB necesarios. IDEA PARADÓJICA ¿Qué sucede si no archiva el bloque cpio con el MFS? La idea es paradójica, pero entonces el kernel no tendrá que asignar memoria para el desempaquetado y la distribución se ejecutará en sistemas con 512 MB de RAM. Naturalmente, este método tendrá desventajas. Primero, el tamaño de la imagen aumentará en 242 - 83 = 159 MB. Esto puede aumentar el tiempo de arranque si el medio de la imagen no es muy eficiente, como un DVD-ROM o una unidad flash USB 2.0. Pero lo peor es que este método es completamente inviable, porque debido al aumento en el archivo, la cantidad de memoria libre se reducirá en 159 MB, después de lo cual, en lugar de 384 MB, habrá 225 MB, que no puede caber en un MFS de 242 MB. Pero, de hecho, resulta que la transferencia de contenido del bloque cpio al MFS también se realiza a través de la memoria intermedia, lo que provoca un aborto del proceso después de procesar aproximadamente 112 MB. Por lo tanto, debemos buscar otras formas.initrd.gz ESTUDIAMOS LA COMPOSICIÓN DEL FS MÍNIMO El único objeto cuya modificación puede ayudar a ahorrar memoria en la etapa inicial de carga es el MFS. No es difícil determinar cuánto volumen ocupan sus partes: basta con ejecutar el comando dentro de los directorios de interés. $ du -shm * | sort -rn | head Cuenta y muestra visualmente los tamaños de los subdirectorios en el directorio actual. El resultado es un mapa de las mayores instalaciones de MFS. Elementos del MFS con indicación de su tamañoElementos del MFS con indicación de su tamaño La gran mayoría de MFS son archivos binarios proporcionados por fabricantes de dispositivos y módulos de kernel con controladores de dispositivos. Sería bueno saber de qué paquetes provienen: $ dpkg-query -S /lib/firmware wireless-regdb, linux-firmware, intel-microcode, amd64-microcode: /lib/firmware $ dpkg-query -S /lib/modules linux-modules-extra-5.4.0-72-generic linux-modules-5.4.0-72-generic linux-headers-5.4.0-72-generic /modules Resulta que las fuentes de la masa de archivos que se “hinchan” son solo unos pocos paquetes. Es decir, agruparlos según sus funciones y eliminar los innecesarios no funcionará. Dejemos este problema por ahora e intentemos averiguar si todos estos paquetes son necesarios para iniciar el sistema operativo. Para responder a esta pregunta, debe recurrir al script , que se encuentra en la raíz del MFS y coordina todas las acciones realizadas en esta etapa.initrd.gz/init EXAMINANDO EL SCRIPT /INIT Primero, este script inicializa la variable de entorno PATHpara tener acceso a las utilidades del sistema: export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin Luego aumenta el sistema de archivos con directorios para acercarlo al estándar de jerarquía del sistema de archivos. Algunos directorios están montados de una manera especial para mostrar sistemas de archivos virtuales en ellos: /dev /root /sys <--- mount -t sysfs -o nodev,noexec,nosuid sysfs /sys /proc <--- mount -t proc -o nodev,noexec,nosuid proc /proc /tmp /var/lock /dev <--- mount -t devtmpfs -o noexec,nosuid,mode=0755 udev /dev /dev/pts <--- mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts Luego se forma el entorno, en el que marcamos la variable RUNSIZE. Determina la cantidad de RAM que se reservará para el sistema de archivos virtual . El valor de esta variable se recupera del archivo de configuración y por defecto es 10%./run/conf/initramfs.conf Después de conectar las subrutinas de la biblioteca , se inicia un ciclo de análisis de los parámetros pasados ​​al kernel de Linux desde la línea de comandos del gestor de arranque:/script/functions for x in $(cat /proc/cmdline) case $x in ... ИмяПараметра=*) ИМЯПАРАМЕТРА="${x#ИмяПараметра=}" ;; ... initramfs.runsize=*) RUNSIZE="${x#initramfs.runsize=}" ;; boot=*) BOOT=${x#boot=} ;; break=*) break=${x#break=} ;; break) break=premount ;; ... esac done Básicamente agrega o modifica variables de entorno. RUNSIZEPor ejemplo, se puede influir en el valor de una variable especificando una opción del núcleo . La variable BOOT es un indicador del método de arranque del sistema operativo: local, nfs o casper. Más tarde se usa en el comando de vista para incluir secuencias de comandos para montar el sistema de archivos principal.initramfs.runsize. /scripts/${BOOT} (https://www.femeuro.com/la-botnet-glupteba-vuelve-a-estar-activa-y-sigue-utilizando-la-cadena-de-bloques/)