Distribución Linux desde Cero

Una Distribución Linux desde Cero#

Creo que, como mucha gente, uso Linux a diario. Personalmente uso NixOS. Pero al final no sé realmente cómo funciona todo bajo el capó.

Me encontré varias veces con videos de un estadounidense, creo que Nir Lichtman, que se divierte creando diferentes distribuciones Linux desde cero para diferentes casos de uso.

Un ejemplo de video:

El concepto es realmente genial y lo hace muy accesible, así que gracias a él por estos videos.

IMPORTANT

La distribución final no está destinada a ser utilizada en producción, sino solo con fines educativos.

Así que en este post voy a mostrarles lo que hice para crear una distribución Linux mínima from scratch.

Requisitos técnicos previos#

En mi caso voy a hacer esto en un contenedor docker ubuntu. Y para lanzar la VM uso QEMU, que pueden instalar fácilmente.

En NixOS simplemente lancé: nix-shell -p qemu

Para las otras distribuciones pueden ver la doc oficial de QEMU. La documentación de docker. Y de paso la documentación oficial de Linux From Scratch que está muy bien hecha.

División#

Necesitaremos tres bloques para hacer funcionar nuestra distribución:

  • kernel (el núcleo Linux)
  • User Space (BusyBox)
  • bootloader (Syslinux)

El Núcleo Linux#

Como les dije al principio, voy a usar un contenedor docker ubuntu para hacer todo esto. Así que mi primer paso es lanzarlo.

docker

docker run —privileged -it ubuntu

docker

Nos encontramos en la shell del contenedor, el primer paso es actualizar e instalar las dependencias necesarias.

Actualización e instalación de dependencias

apt update && apt upgrade -y apt install bzip2 git vim make gcc libncurses-dev flex bison bc cpio libelf-dev libssl-dev -y

update

Tenemos nuestras dependencias instaladas, ahora podemos clonar el repositorio del núcleo linux.

NOTE

Prefiero clonarlo en el directorio del usuario pero eso es como ustedes prefieran (/home/ubuntu).

Clonado del Núcleo Linux

*—depth 1 - para no tener todo el historial git del núcleo sino solo el último commit

clone-linux

Ya que vamos con una instalación x86_64 vamos a configurar el núcleo para esta arquitectura. Usamos una configuración ya hecha por los desarrolladores del núcleo.

Configuración del núcleo

make x86_64_defconfig

x86_64_defconfig

Una vez hecho podemos lanzar la compilación del núcleo, podemos usar make o make -j N donde N es el número de núcleos de su procesador para acelerar la compilación.

Yo voy a usar todos los núcleos disponibles para ir más rápido.

Compilación del núcleo

make -j $(nproc)

btop

make

Kernel: arch/x86/boot/bzImage is ready (#1) Una vez terminada la compilación podemos ver la imagen del núcleo en el directorio arch/x86/boot/bzImage.

Creamos un directorio boot-files en la raíz y copiamos la imagen del núcleo dentro.

Copia del núcleo

mkdir /boot-files mv arch/x86/boot/bzImage /boot-files

Terminado con el núcleo, pasamos al espacio de usuario.

Espacio de Usuario - BusyBox#

La documentación oficial de BusyBox.

Volvemos al espacio de usuario /home/ubuntu y clonamos el repositorio de busybox.

Clonado de BusyBox

cd /home/ubuntu git clone —depth 1 https://git.busybox.net/busybox cd busybox

Es el mismo principio que para el núcleo, configuramos y compilamos.

Para inicializar la configuración por defecto usamos make defconfig.

Configuración de BusyBox

make defconfig

Nosotros queremos la versión de busybox en modo static para que todo esté en un solo binario. Así que modificamos la configuración en settings, hay que desmarcar la sección Build static binary (no shared libs) para eso hay que lanzar el comando:

Modificación de la configuración

make menuconfig

Una vez en el menú, vamos a Settings (enter).

settings libs

Una vez desmarcado no ha terminado porque con las versiones recientes de ubuntu hay que desactivar tc, para hacer esto vamos a Networking Utilities y desmarcamos tc (8.3 kb) (puede ser otro valor Xkb).

tc

Una vez hecho hacemos exit y guardamos la configuración. Luego construimos busybox de la misma manera que el núcleo.

Compilación de BusyBox

make -j $(nproc)

busybox

En el directorio que creamos anteriormente /boot-files creamos un directorio initramfs y copiamos el binario de busybox dentro (mkdir /boot-files/initramfs).

Instalamos busybox en este directorio usando el comando make install con la variable CONFIG_PREFIX que apunta al directorio de instalación.

Instalación de BusyBox

make CONFIG_PREFIX=/boot-files/initramfs install

busybox-install

Nuestro sistema aún no tiene shell, vamos a crear un script init que será el primer proceso lanzado por el núcleo. Lo gracioso en el archivo init es que le decimos que se use a sí mismo como shell.

NOTE

Hay que crear bien el archivo init en el directorio /boot-files/initramfs y darle los derechos de ejecución con el comando chmod +x init.

Antes creamos las carpetas importantes en el directorio initramfs.

Creación de carpetas

mkdir /boot-files/initramfs/{proc,sys,dev}

#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
echo "Bienvenido a mi distribución"
exec /bin/sh

Todavía en el directorio /boot-files/initramfs creamos un archivo cpio comprimido que será utilizado por el núcleo al inicio.

Creación del archivo cpio

cd /boot-files/initramfs find . | cpio -o -H newc > ../init.cpio

Es todo para el espacio de usuario, pasamos al bootloader.

Bootloader - Syslinux#

Aquí vamos a usar Syslinux como bootloader, la doc oficial está aquí.

Lo instalamos ya que no está instalado por defecto.

Instalación de Syslinux

cd /boot-files # volvemos al directorio boot-files apt install syslinux -y

Entonces una vez instalado, vamos a crear un archivo de 50Mo que servirá de disco duro virtual para nuestra distribución.

Creación del disco duro virtual

dd if=/dev/zero of=boot bs=1M count=50

bootloader

Necesitamos dosfstools para formatear el archivo en FAT32.

Formateo del disco duro virtual

apt install dosfstools -y mkfs -t fat boot syslinux boot

Aquí montamos el disco duro virtual, lo formateamos e instalamos syslinux en él.

Creación de una carpeta random

mkdir m mount boot m

Copiamos los archivos necesarios#

cp bzImage m cp init.cpio m

Listo, ahora tenemos un archivo boot que contiene nuestra distribución linux mínima. El objetivo es lanzarla en una máquina virtual.

Dado que estamos en un contenedor docker hay que transferir el archivo boot al host. Para hacer esto usamos el comando docker cp.

En otro terminal en el host.

Transferencia del archivo boot

docker cp <container_id>:/boot-files/boot .

cp

Ahora hay que lanzar la máquina virtual con QEMU usando el archivo boot como disco duro.

Lanzamiento de la VM

qemu-system-x86_64 boot

qemu

Pero tenemos un problema, nos dice No configuration file found. No hay problema, vamos a darle manualmente el archivo de configuración que creamos anteriormente.

así que en boot escribimos:

WARNING

El teclado está en QWERTY

/bzImage -initrd=/init.cpio

boot

Presionamos enter y ya está, tenemos nuestra distribución linux mínima.

shell-final

NOTE

Vemos bien nuestro mensaje personalizado “Bienvenido a mi distribución”

Ahora pueden jugar con su distribución linux mínima. Pueden escribir comandos como ls, cd, pwd, etc.

Así es a grandes rasgos cómo funciona, por supuesto existen otros bootloaders, otros espacios de usuario, y muchas otras cosas que agregar para hacer la distribución más completa pero para empezar no está mal.

Gracias a Nir Lichtman por la inspiración.

¡Gracias por leerme! Si tienen preguntas no duden en hacérmelas en X.

Distribución Linux desde Cero
https://blog.ce-dev.eu/posts/es/linux-distro-from-scratch/
Author
Cedev
Published at
2026-01-28
License
CC BY-NC-SA 4.0