GRUB2 (GRand Unified Bootloader versión 2) es el programa que el firmware arranca antes que el kernel. Su trabajo es localizar el kernel en el disco, cargar el initramfs y pasarle el control con los parámetros que tú hayas definido. En Debian, GRUB2 es el bootloader estándar en sistemas x86/amd64 tanto con BIOS como con UEFI.
El diseño de GRUB separa la configuración en dos capas. La primera es /etc/default/grub, un archivo de variables de shell que actúa como panel de control para el usuario —simple, legible, diseñado para edición manual. La segunda es /boot/grub/grub.cfg, el archivo que GRUB lee realmente durante el arranque —generado automáticamente por update-grub a partir de esa primera capa más los scripts en /etc/grub.d/. Nunca edites grub.cfg directamente: la próxima llamada a update-grub lo sobreescribe sin avisar.
Editas /etc/default/grub cuando necesitas cambiar el comportamiento del arranque: reducir el timeout en una máquina de producción que nunca necesita menú, añadir parámetros del kernel para depurar un problema de hardware, silenciar la salida de boot para un kiosko, o fijar el kernel por defecto después de una actualización que introdujo una regresión. Si tocas esas variables y olvidas ejecutar update-grub, el cambio no existe: el archivo que lees en el editor y el archivo que lee GRUB son dos cosas distintas.
Lo que se rompe cuando fallas aquí va desde lo molesto hasta lo catastrófico. Un GRUB_CMDLINE_LINUX_DEFAULT con un parámetro mal escrito puede impedir que el kernel monte el rootfs. Un GRUB_DEFAULT apuntando a un índice que ya no existe en el menú arranca el primer entry disponible en silencio. Y si corrompes /boot/grub/grub.cfg editándolo a mano y luego el sistema pierde corriente durante el boot, necesitas un live USB para recuperarte.
# Ver la configuración actual antes de tocar nada cat /etc/default/grub # Hacer una copia de seguridad con fecha — cuesta 0 segundos, salva horas sudo cp /etc/default/grub /etc/default/grub.bak.$(date +%F) # Editar la configuración principal sudo nano /etc/default/grub
El archivo que verás tiene este aspecto por defecto en Debian Bookworm:
GRUB_DEFAULT=0 GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR=`lsb_release -i -s 2>/dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" GRUB_CMDLINE_LINUX=""
Vamos a hacer tres cambios con propósito concreto: reducir el timeout a 2 segundos, añadir un parámetro de kernel para depurar un problema de memoria tardía en el arranque, y fijar el kernel anterior como default porque la última actualización rompió el módulo de red:
# /etc/default/grub — modificado para servidor con regresión en 6.1.0-21 # Entrada del menú que arranca por defecto. # "saved" usa el último seleccionado manualmente; un número es el índice (0-based). # Usamos el nombre exacto del entry para no depender del orden. GRUB_DEFAULT="Advanced options for Debian GNU/Linux>Debian GNU/Linux, with Linux 6.1.0-20-amd64" # Segundos que espera antes de arrancar automáticamente. # En producción sin monitor, 2 es suficiente para intervenir si hace falta. GRUB_TIMEOUT=2 # Estilo de presentación del timeout: "countdown" muestra la cuenta regresiva visible. # "hidden" lo oculta y pulsar Shift lo muestra; útil en desktops para que arranque rápido. GRUB_TIMEOUT_STYLE=countdown GRUB_DISTRIBUTOR=`lsb_release -i -s 2>/dev/null || echo Debian` # Parámetros pasados al kernel en boot normal (con initramfs). # Quitamos "splash" para ver la salida real del kernel; añadimos "memtest=4" # para que el kernel reporte problemas de memoria en dmesg desde el inicio. # "loglevel=7" activa todos los mensajes del kernel, equivale a pr_debug. GRUB_CMDLINE_LINUX_DEFAULT="quiet loglevel=7 memtest=4" # Parámetros que se añaden en TODOS los modos (normal + recovery). # Aquí va lo que necesitas siempre, independientemente del entry. GRUB_CMDLINE_LINUX="" # Si tienes varios SO, os-prober los detecta. En servidores puros, desactívalo: # evita que GRUB busque en discos de datos y ralentice update-grub. GRUB_DISABLE_OS_PROBER=true
Con el archivo guardado, regeneramos grub.cfg:
# update-grub es un wrapper de grub-mkconfig -o /boot/grub/grub.cfg sudo update-grub # Verifica que el entry que pusiste en GRUB_DEFAULT aparece literalmente en el cfg # Si no lo encuentra, GRUB arrancará el entry 0 sin error visible grep "menuentry\|set default" /boot/grub/grub.cfg | head -20
Si el sistema arranca con UEFI en lugar de BIOS clásica, los archivos de GRUB están bajo /boot/efi/EFI/debian/ y el binario que ejecuta el firmware es /boot/efi/EFI/debian/grubx64.efi. update-grub sigue siendo el comando correcto; la diferencia es transparente para este flujo.
# Confirma en qué modo arrancó el sistema actual [ -d /sys/firmware/efi ] && echo "UEFI" || echo "BIOS/Legacy" # En sistemas UEFI, las entradas del firmware se gestionan con efibootmgr, no con GRUB_DEFAULT. # Para cambiar el orden de boot entre SO distintos, usa: sudo efibootmgr -v
Qué hace exactamente cada decisión del ejemplo
GRUB_DEFAULT con nombre completo: el índice numérico (0, 1, 2) corresponde al orden en que grub-mkconfig genera las entradas, y ese orden puede cambiar cada vez que instalas o eliminas un kernel. Usar el string exacto del menuentry es frágil también —el nombre tiene que coincidir carácter por carácter, incluyendo espacios y versión— pero al menos es explícito y visible. El formato "submenu>entry" que usamos en el ejemplo es necesario porque los kernels alternativos en Debian aparecen dentro del submenú “Advanced options”; si escribes solo el nombre del entry sin el prefijo del submenú, GRUB no lo encuentra.
GRUB_CMDLINE_LINUX_DEFAULT vs GRUB_CMDLINE_LINUX: la diferencia es sutil pero importante. CMDLINE_LINUX_DEFAULT se aplica solo al entry normal (el primero del menú, el que arranca automáticamente). CMDLINE_LINUX se aplica a todos los entries generados, incluyendo el modo recovery. Si añades un parámetro en CMDLINE_LINUX_DEFAULT y luego arrancas en recovery, ese parámetro no estará. Para parámetros de seguridad o de hardware que debes tener siempre —como intel_iommu=on o nomodeset— ponlos en CMDLINE_LINUX.
loglevel=7: el kernel usa niveles de 0 (emergencia) a 7 (debug). El default de Debian en boot normal es 4 (advertencias). Subir a 7 temporalmente para diagnosticar un problema de driver es legítimo; recuerda bajarlo después porque ralentiza el boot y llena el buffer del kernel más rápido de lo que dmesg puede leer.
GRUB_DISABLE_OS_PROBER=true: en Debian Bookworm, os-prober está desactivado por defecto precisamente porque en entornos cloud o con muchos discos montados puede detectar particiones de datos como sistemas operativos y generar entries incorrectos en el menú. En un equipo de escritorio con Windows en otro disco, necesitas GRUB_DISABLE_OS_PROBER=false o simplemente eliminar esa línea para que os-prober funcione.
El grep de verificación al final: update-grub no falla aunque GRUB_DEFAULT apunte a un entry inexistente. El error se manifiesta silenciosamente en el siguiente boot cuando arranca un kernel diferente al esperado. Comprobar que el string que pusiste en GRUB_DEFAULT aparece literalmente en grub.cfg es el único modo de confirmar que la configuración es correcta antes de reiniciar.
[Ubuntu]: En Ubuntu 22.04+, /etc/default/grub.d/ tiene archivos adicionales que pueden sobreescribir variables definidas en /etc/default/grub. Si un cambio no tiene efecto después de update-grub, revisa ese directorio. El wrapper update-grub es idéntico en ambos sistemas.