Dove vive il boot loader
Il boot loader è il primo software che gira all’accensione: carica il kernel e gli passa il controllo. Dove viene installato dipende dallo schema del disco e dal firmware, e l’esame chiede esattamente questo.
- Disco MBR — il primo settore da 512 byte del disco è il Master Boot Record: contiene la tabella delle partizioni e il codice di avvio. Lì ci sta pochissimo, così GRUB vi mette solo il boot code, che carica una core image piazzata nello spazio di circa 32 KB fra l’MBR e la prima partizione; da quel momento GRUB legge dal filesystem menu, configurazione e moduli.
- Disco GPT con BIOS tradizionale — la seconda parte di GRUB finisce in una BIOS boot partition dedicata.
- Firmware UEFI — il firmware carica direttamente il file
grubx64.efi(sistemi a 64 bit) ogrubia32.efi(32 bit) dalla EFI System Partition.
In /boot trovi i file che servono all’avvio, quasi tutti con il suffisso della versione del kernel: config-VERSIONE, System.map-VERSIONE, il kernel vmlinuz-VERSIONE (la z finale significa compresso) e il disco RAM iniziale initrd.img-VERSIONE. I file di GRUB stanno in /boot/grub, moduli compresi (/boot/grub/i386-pc).
Installare: grub-install vuole il disco, non la partizione
L’utility è grub-install e vale sia per GRUB 2 sia per GRUB Legacy. La regola che fa cadere più candidati: si indica il dispositivo (/dev/sda), non la partizione (/dev/sda1).
Da un sistema avviato con live CD, prima si scopre qual è la partizione di boot — fdisk -l /dev/sda la marca con un asterisco nella colonna Boot — poi la si monta e si punta grub-install alla directory di boot montata.
# fdisk -l /dev/sda
# mkdir /mnt/tmp
# mount /dev/sda1 /mnt/tmp
# grub-install --boot-directory=/mnt/tmp /dev/sda
Se il sistema non ha una partizione di boot separata ma solo la directory /boot, il comando diventa grub-install --boot-directory=/boot /dev/sda. Installare GRUB anche sull’MBR di un secondo disco è il modo più semplice per avere una posizione di avvio alternativa se il primo disco muore.
Con GRUB Legacy si può reinstallare anche dalla shell del boot loader: find /boot/grub/stage1 dice su quale partizione stanno i file, root (hd0,0) la imposta e setup (hd0) scrive il boot loader nell’MBR di quel disco.
Configurare GRUB 2: il file che modifichi non è quello che leggi
Il file di configurazione di GRUB 2 è /boot/grub/grub.cfg, ma è generato: non si modifica a mano. Il flusso corretto è modificare /etc/default/grub e poi rigenerare. Qui i due mondi divergono nel nome:
- Debian/Ubuntu —
update-grub, che è solo una scorciatoia pergrub-mkconfig -o /boot/grub/grub.cfg. - Red Hat/Fedora/SUSE — non esiste
update-grub: si usagrub2-mkconfig -o /boot/grub2/grub.cfg, e tutta la directory si chiamagrub2.
Le direttive di /etc/default/grub da conoscere: GRUB_DEFAULT= (la voce predefinita, numerata da zero, oppure un titolo, oppure saved in coppia con GRUB_SAVEDEFAULT=true per ripartire sempre dall’ultima scelta), GRUB_TIMEOUT= (secondi di attesa; 0 avvia subito senza mostrare il menu, -1 aspetta per sempre), GRUB_CMDLINE_LINUX= (parametri aggiunti a tutte le voci Linux), GRUB_CMDLINE_LINUX_DEFAULT= (solo alla voce normale, non a quella di ripristino) e GRUB_ENABLE_CRYPTODISK=y per i dischi cifrati.
Le voci personalizzate non vanno in grub.cfg ma negli script eseguibili di /etc/grub.d/, processati in ordine numerico: 40_custom è il file previsto per le aggiunte a mano. La sintassi di una voce:
menuentry "Default OS" {
set root=(hd0,1)
linux /vmlinuz root=/dev/sda1 ro quiet splash
initrd /initrd.img
}
La numerazione è la trappola classica. In GRUB 2 i dischi partono da zero e le partizioni da uno: (hd0,1) è /dev/sda1. In GRUB Legacy partono da zero entrambi: lì /dev/sda1 si scrive (hd0,0). Al posto del device puoi cercare il filesystem per UUID con search --set=root --fs-uuid UUID (l’UUID si trova con ls -l /dev/disk/by-uuid/), spesso con --no-floppy.
GRUB Legacy: menu.lst, grub.conf e il chainload
GRUB Legacy è fermo alla 0.97 del 2005, ma è ancora in programma d’esame. Qui il file di configurazione si modifica direttamente e si chiama /boot/grub/menu.lst sulle distribuzioni Debian, /boot/grub/grub.conf su quelle Red Hat (con menu.lst come collegamento). Una voce minima ha tre comandi — title, root, kernel — più l’eventuale initrd:
title My Linux Distribution
root (hd0,0)
kernel /vmlinuz root=/dev/hda1
initrd /initrd.img
Attenzione a non confondere i livelli: root (hd0,0) è un comando di GRUB e dice dove stanno i file di avvio, mentre root=/dev/hda1 è un parametro del kernel Linux e dice quale sarà il filesystem di root. Per avviare un sistema che GRUB non conosce, come Windows, si usa il chainloading: root (hd0,1), poi makeactive, chainloader +1 per caricare il primo settore di quella partizione e infine boot.
Parlare con il boot loader quando qualcosa si rompe
Al menu di GRUB 2 le frecce scelgono la voce e Invio avvia; se vedi solo un conto alla rovescia, premi Shift. e apre l’editor della voce (si avvia con Ctrl+X o F10, si torna indietro con Esc), c apre la shell grub>. Il menu non compare affatto se GRUB_TIMEOUT è 0.
Dalla shell si avvia a mano: ls elenca dischi e partizioni ((hd0,msdos1) su disco MBR, (hd0,gpt1) su GPT), poi set root=(hd0,msdos1), linux /vmlinuz root=/dev/sda1, initrd /initrd.img e boot. Se invece compare il prompt ridotto grub rescue> servono due passi in più prima: set prefix=(hd0,msdos1)/boot/grub e il caricamento dei moduli con insmod normal e insmod linux.