6 puntos por GN⁺ 2026-03-30 | 2 comentarios | Compartir por WhatsApp
  • Define initrd como una unidad de programa que el kernel interpreta y ejecuta directamente, reinterpretando Linux como una especie de intérprete
  • Usa kexec, base64 y cpio para construir una distribución Linux recursiva que se reinicia a sí misma, donde el initrd se vuelve a ejecutar solo
  • Si el script /init hace que imprima su propia imagen cpio, se forma un initrd autorreplicante con forma de Quine
  • Explica, a través de la estructura de ejecución ELF, ld.so y binfmt_misc, una arquitectura donde las capas de intérpretes se extienden hasta el kernel
  • Con kexec o QEMU, es posible ejecutar otro Linux sobre Linux de forma recursiva en cola, ampliando de manera experimental los límites entre kernel, virtualización e intérpretes

Ingeniería inversa de rkx.gz y estructura de initrd autorrecursiva

  • El comando curl https://astrid.tech/rkx.gz | gunzip | sudo sh descarga y ejecuta un script de shell codificado en base64 de 20 MB
    • El script verifica permisos de root y comprueba la existencia de kexec, base64 y cpio
    • Decodifica los datos base64 para crear un archivo cpio llamado r, y extrae de él una imagen de kernel llamada k
    • Usa kexec para cargar y ejecutar k como kernel y r como ramdisk
  • Dentro de r.cpio están incluidos /bin, /init y el archivo k; k es una imagen del kernel Linux 6.18.18, y /init tiene forma de script de shell
    • /init monta /proc, empaqueta el sistema de archivos actual como cpio en /r, y luego vuelve a ejecutar /k y /r con kexec
    • El resultado es una distribución Linux recursiva que se reinicia continuamente a sí misma

La perspectiva de ver el kernel Linux como un intérprete

  • initrd no es solo un ramdisk de arranque, sino que puede verse como un programa que el kernel Linux interpreta y ejecuta
    • Igual que curl | sh o python3 script.py, initrd también es una forma de programa de entrada ejecutado por el kernel
    • Por lo tanto, el kernel Linux funciona como un intérprete que interpreta initrd
  • Esta estructura se parece a la optimización de recursión de cola (tail-call optimization)
    • kexec no sobrescribe el kernel anterior, sino que carga y ejecuta uno nuevo en un espacio de memoria nuevo
    • Cada kernel no conserva el estado previo, sino que es reemplazado por un nuevo “stack frame”

Quine y autorreplicación de initrd

  • Un Quine es un programa que imprime su propio código
    • Si el script /init ejecuta cat /r al final, imprimirá un cpio idéntico a sí mismo
    • En este caso, se forma un Quine del intérprete initrd de Linux
    • Como todos los archivos existen en tmpfs en RAM, no se produce I/O real de disco

ELF, ld.so y las capas del intérprete

  • Un ejecutable ELF incluye en su encabezado la ruta del intérprete (ld-linux-x86-64.so.2)
    • Al ejecutarse, el kernel lanza primero ld.so, y ld.so carga las bibliotecas dinámicas del ELF antes de ejecutar el programa
    • Por eso, ELF también puede verse como una especie de lenguaje interpretado
  • /bin/sh es interpretado por ld.so, y ld.so es interpretado directamente por el kernel
    • Como ld.so es un ELF enlazado estáticamente, el kernel puede ejecutarlo directamente
    • Así se forma el caso base de la jerarquía de intérpretes

Ejecutar CPIO mediante binfmt_misc

  • Con binfmt_misc se puede ejecutar con un intérprete definido archivos con bytes mágicos específicos
    • Comando de registro de ejemplo:
      echo ':cpio:M::\x30\x37\x30\x37\x30\x31::/path/to/my/script.sh:' > /proc/sys/fs/binfmt_misc/register
      
    • Con esta configuración, un archivo CPIO con chmod +x puede ejecutarse directamente
  • Se puede registrar como intérprete un script que ejecute CPIO como initrd usando QEMU
    • QEMU arranca una máquina virtual usando el kernel y el initrd especificados
    • Como resultado, el intérprete del archivo CPIO pasa a ser el kernel Linux ejecutado por QEMU

Intérpretes recursivos y “el bucle más extraño”

  • Un intérprete basado en QEMU crea un nuevo stack frame de entorno Linux
    • Es una estructura donde Linux ejecuta otro Linux, y puede anidarse hasta el límite de memoria
    • Si se reemplaza por un intérprete basado en kexec, se hace posible una ejecución recursiva de Linux optimizada como llamada de cola
  • Si en /init se registra binfmt_misc y se configura para ejecutar /r, se completa un initrd que se ejecuta a sí mismo
    • /r es el siguiente proceso init en formato CPIO y, al ejecutarse, vuelve a interpretarse a sí mismo

Conclusión

  • initrd no es solo una herramienta de arranque, sino una unidad de programa que el kernel Linux interpreta
  • Con kexec y binfmt_misc, es posible ejecutar Linux de forma recursiva como si fuera su propio intérprete
  • Esta estructura es un concepto experimental que difumina los límites entre kernel, virtualización, intérpretes y programas autorreplicantes
  • El código fuente relacionado está publicado en el repositorio de GitHub ifd3f/rekexec

2 comentarios

 
github88 2026-03-31

Dicen que la ignorancia da valentía... Ojalá se evitaran este tipo de artículos.

 
GN⁺ 2026-03-30
Comentarios en Hacker News
  • Me dolió leer este artículo por la cantidad de malentendidos que tiene
    Un archivo cpio no es un sistema de archivos. El autor usa initramfs, que está basado en tmpfs. Linux puede extraer cpio a tmpfs. Un archivo de archivos y directorios no es, por sí mismo, un programa
    Que dos cosas se parezcan no significa que sean lo mismo. Un programa binario se ejecuta en la CPU, y si hay un intérprete, está oculto en el entorno de hardware. Eso queda fuera del alcance del kernel
    Para ejecutar un script de shell hace falta un shell que interprete ese script. El autor omite esa parte y confunde el kernel con el programa shell
    Linux puede compilarse sin initramfs ni ramdisk, y aun así puede ejecutar un userland desde el sistema de archivos
    La expresión “Linux initrd interpreter” es una descripción realmente equivocada

    • Un archivo ELF tampoco tiene por qué ser, por sí solo, un programa. Algunos ELF son bibliotecas dinámicas y no tienen punto de entrada. Así como algunos ELF son ejecutables, también puede decirse que algunos CPIO lo son. En última instancia, que ld.so cargue un ELF en memoria y ejecute el punto de entrada, y que el kernel desempaquete un initramfs y ejecute el punto de entrada, son conceptos similares
    • El archivo init dentro del cpio es el programa que realmente se interpreta, y el resto de los archivos actúan como memoria que ese programa usa
    • Un programa binario se ejecuta en la CPU, pero el archivo del programa en sí es una estructura de archivo compuesta por varias secciones. La CPU no entiende directamente el archivo del programa. Linux configura el espacio de direcciones donde se ejecutará el programa y luego salta a la dirección a la que apunta el contador de programa. Las secciones de metadatos de ELF definen ese proceso
    • Al menos consuela que no parece un texto escrito por IA
  • ¿No hacen todos los OS el papel de intérprete de código máquina con privilegios de kernel?

    • Yo diría que no. El OS no interpreta cada instrucción directamente, sino que se la pasa a la CPU para que la ejecute
    • El OS es una interfaz que permite usar los recursos del sistema. La CPU interpreta el código máquina, y el OS puede indicarle a la CPU qué ejecutar
    • En este caso, podría verse como un intérprete para archivos CPIO
  • Este artículo funciona si se toma como un modelo mental de “Linux es un intérprete”, pero es incorrecto si se toma literalmente
    Tiene más sentido verlo no como interpretación al nivel de instrucciones de CPU, sino como el papel del kernel coordinando formatos ejecutables como ELF, scripts con shebang e initramfs. La confusión parece venir de mezclar dos significados distintos de “intérprete”

  • El punto central no es si la analogía es correcta, sino mostrar hasta qué punto el concepto de ejecución depende del entorno

  • “¿Todo es un intérprete?”

    • Sí, pero el compilador es la excepción
  • El Theta Combinator de Turing

    • No me queda claro qué relación tiene eso con este artículo. No estoy familiarizado con los conceptos de programación funcional
  • En una entrada anterior de la serie, el autor dijo que no quería usar el object storage de Contabo, así que se armó sus propias imágenes de VPS
    Creo que hay un punto de equilibrio entre gastar 50 horas para ahorrarte 1.50 dólares al mes y gastar 250 mil dólares en tokens.
    Si no puedes cubrir los costos de infraestructura, quizá el problema sea más de factores sociales que de capacidad técnica. Obsesionarse con correr Doom desde curl no me parece productivo

    • Yo también era así antes. Me parecían demasiado caros 5 euros al mes por un VPS, así que apagaba la instancia y hacía backup del sistema de archivos raíz en la laptop de mi mamá hasta juntar dinero. Después instalé Terminal IDE en un Kindle para jugar con busybox y gcc. Gracias a Spartacus Rex por haberme dado el comienzo de mi carrera
    • Lo que dijo el autor era una broma. La razón real está justo en el siguiente párrafo: “Me pareció un truco divertido, y pensé que si lo publicaba en el blog, yo aprendía, los lectores aprendían y además ganaba puntos de internet: un win-win
    • Aunque a algunos les parezca improductivo, disfrutar de intereses especiales es importante para la salud mental. En mi caso, con TDAH, de hecho es una actividad necesaria
    • Decir “si no puedes pagar 1.50 dólares no eres profesional” suena raro. A un profesional lo define si le pagan, no cuánto gasta
  • Si lees man ld.so, se indica explícitamente que se ejecuta el enlazador dinámico almacenado en la sección .interp de ELF. El nombre mismo de la sección es interesante

  • Linux es muy útil como interfaz programable. Windows también puede serlo, pero siento que Linux se presta más para eso
    Creo que Windows es mejor en GUI, pero GNOME y KDE también me resultan incómodos. Por eso uso fluxbox, icewm y a veces xfce o mate-desktop. Últimamente prefiero entornos simples y rápidos. La mayor parte del trabajo la hago desde la línea de comandos y editando código

    • Si quieres un entorno rápido y simple, la combinación Sway + foot está muy bien. Si organizas los workspaces con atajos de teclado, se puede usar muy cómodamente incluso sin escritorio
    • No estoy de acuerdo con que la GUI de Windows sea mejor. GNOME y KDE tampoco me gustan, pero en Windows no puedes escapar del WM complejo de Microsoft. Personalmente, me parecen mucho mejores las interfaces de estilo mpx/mux (por ejemplo, 9wm, cwm, dwm) que las de línea Xerox. Están más cerca de la filosofía de Engelbart y en general son mucho más limpias