GRUB howto

Uno dei primi HOW-TO pubblicati dal MajaGLUG, a cura di Giovanni Mazzamati

GRUB

Premessa

Avverto i lettori che questo HOWTO è nato per essere diviso in due puntate e che quindi è stato unito in un solo testo molto velocemente per poterlo pubblicare.

Non appena potrò verranno apportate le correzioni del caso.

Giovanni Mazzamati

GRUB sta per GRand Unified Bootloader GNU.

Probabilmente molti di voi già lo conoscono ed altri si stanno chiedendo invece cos'è un bootloader.

Chi conosce solo sistemi Win9x non comprenderà bene quali benefici possa trarre da un bootloader come GRUB, invece chi ha già esperienze con WinNT o con i sistemi Linux sa che un bootloader serve per caricare un sistema operativo.

Infatti, appena accendiamo il nostro caro computer parte il cosiddetto 'boot a freddo': il BIOS (Basic Input Output System) effettua un controllo dell'hardware presente, che viene abilitato solo nel caso che il check sia stato positivo e procede al caricamento del sistema operativo.

Per fare ciò passa il controllo al programma che si trova nel MBR (Master Boot Record) del dispositivo da noi scelto per il boot.

Nel caso di Win9x viene caricato direttamente il sistema operativo senza possibilità di scelta degli altri sistemi eventualmente installati.

Con un bootloader le cose cambiano, infatti con esso è possibile caricare tutti i sistemi operativi disponibili e guarda caso Linux è fra questi. [eh-eh... ma guarda un po'!!! :-)]

Va precisato che se abbiamo un floppy di boot in cui sia stato installato GRUB è possibile utilizzarlo per far partire, per esempio, Win98 qualora il MBR fosse danneggiato (floppy con GRUB come disco di soccorso).

Ma bando alle ciance ed iniziamo. ;-P

Presumo che chi voglia provare GRUB abbia a disposizione una macchina su cui sia stata installata una qualsiasi distribuzione Linux.

Installazione

Ovviamente per installare un programma dobbiamo prima procurarcelo, quindi andiamo su ftp://alpha.gnu.org/gnu/grub e da lì scarichiamo l'ultima versione disponibile (al momento della stesura di questo articolo la versione stabile più recente è la 0.93).

Appena finito il download apriamo un terminale ed andiamo nella directory contenente il pacchetto chiamato grub-versione.tar.gz (dove versione è il numero della versione che abbiamo scaricato) e lanciamo il classico comando per scompattare un TAR compresso:

$ tar xvfz grub-0.93.tar.gz

viene così creata una directory dal nome grub-0.93,
quindi entriamo in essa con il comando:

$ cd grub-0.93

e da qui diamo i canonici comandi per la compilazione ed installazione di un programma in forma sorgente:

$ ./configure
$ make

ora siamo pronti per l'installazione quindi acquisiamo i privilegi di root (perchè finora siamo stati un utente comune vero?):

$ su
# make install

Il nostro GRUB è correttamente installato in /usr/local/share/grub/i386-pc/.

Ed ora?, direte voi. Beh, adesso, per divertirci un pò, andremo a creare un floppy di boot con il nostro caro GRUB appena installato: per fare questo possiamo recuperare un vecchio floppy dal fondo di un cassetto, oppure ne usiamo uno nuovo, che come tale sarà più affidabile (io ne ho recuperato uno... ;-P). GRUB supporta molti filesystem, ma per rendere il floppy leggibile dal maggior numero di sistemi operativi possibile conviene formattarlo FAT16 che è un filesystem abbastanza semplice (avete mai provato a leggere un fylesystem ext2 o ext3 da win?). Sempre da terminale digitiamo:

# fdformat /dev/fd0
# mkfs -t msdos /dev/fd0

Montiamo il nostro floppy appena formattato nel punto del filsystem linux a noi più congeniale, che può essere /mnt/floppy, come più comunemente specificato in fstab:

# mount /dev/fd0

creiamo questa directory

# mkdir -p /mnt/floppy/boot/grub

e copiamo dentro i due file stage di GRUB stage_1 e stage_2:

# cp /usr/local/share/grub/i386-pc/stage* /mnt/floppy/boot/grub

Smontiamo il floppy senza toglierlo dal drive:

# umount /dev/fd0

Ora installiamo GRUB nel MBR del floppy stesso e per far ciò lanciamo GRUB digitando il comando:

# grub

ci si presenterà la shell (prompt dei comandi) di GRUB:

grub>

digitiamo:

grub> root (fd0)
grub> setup (fd0)
grub> quit

Il primo boot...

Benissimo, il nostro GRUB è pronto per mettersi al lavoro, proviamo a fare il reboot con il nostro floppy di boot nuovo nuovo e alla shell di GRUB digitiamo:

grub> rootnoverify (hd0,0)
grub> makeactive
grub> chainloader +1
grub> boot

Ho dato per assunto che abbiate un'installazione di un Win9x sulla prima
partizione del primo dispositivo del primo canale IDE (oppure il primo dispositivo
SCSI), ossia il classico "C:".

Dischi secondo GRUB

La prima cosa da mettere in evidenza è come GRUB gestisce i dischi.

Opzioni di boot

Ora diamo un'occhiata  ad alcune delle opzioni di boot che GRUB ci offre.

Nell'esempio appena descritto sono state usate delle opzioni che ora andiamo
a descrivere.

rootnoverify (hd0,0)

...

Prime conclusioni

La prova appena sopra descritta ci è servita per fare un piccolo test,
ma anche per ceare un floppy di boot che potrebbe tornare utile, vi assicuro che a me ha salvato la vita più di una volta. ;-P

Proseguiamo il percorso...

Bene, se siete arrivati fin quì vuol dire che l'argomento ha stuzzicato la vostra curiosità.

Prima di continuare devo fare una piccola panoramica su dischi e dintorni.

Dischi e partizioni secondo GRUB.

In commercio esistono essenzialmente due tipi di periferiche per la gestione e lo stoccaggio di dati (CD-ROM, FLOPPY HARD DISK), i quali sono IDE o SCSI.

La maggior parte dei computer in giro oggi ha montato un disco IDE di più o meno alta qualità, ma pochi utilizzano SCSI.

GNU/Linux vede i dispositivi, e non solo, come un file, essi si trovano in /dev e per quanto ci riguarda vediamo come definisce i dischi...

Nel nostro caro PC ci sono, di solito, due canali IDE (canale primario e secondario) e su ogni canale IDE sono installabili due dispositivi (uno master ed uno slave) per un totale di quattro dispositivi.

Per quanto riguarda SCSI, su ogni BUS sono installabili 8 dispositivi (numerati da 0 a 7).

I dispositivi IDE vengono definiti come hdXN, dove X va da a a d e N va da 1 a 32. X definisce il dispositivo IDE ed N la partizione. Le partizioni primarie vanno da 1 a 4 le logiche da 5 in poi.

Con un'esempio di certo mi potrò far capire meglio. Nel mio PC sul primo canale IDE ho montati due dischi, uno master /dev/hda ed uno slave /dev/hdb, sul secondo canale ci sono CD-ROM e masterizzatore /dev/hdc e /dev/hdd.

Per quanto riguarda i dischi sono anche partizionati e questo è l'output di fdisk

# fdisk -l /dev/hda

Disk /dev/hda: 4324 MB, 4324561920 bytes
15 heads, 63 sectors/track, 8938 cylinders
Units = cylinders of 945 * 512 = 483840 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/hda1   *         1      6023   2845836    c  Win95 FAT32 (LBA)
/dev/hda2          6024      8938   1377337+   5  Extended
/dev/hda5          6024      6170     69426   83  Linux
/dev/hda6          6171      8938   1307848+  83  Linux
#

Come potete vedere, il disco contiene: una partizione primaria di tipo fat32 (che prima o poi cambierà destinazione...); una partizione estesa nella quale sono contenute due partizioni logiche di tipo Linux e più precisamente reiserfs.
Per fare un altro esempio...

# cat /etc/fstab
/dev/hdb1        swap             swap        defaults         0   0
/dev/hda6        /                reiserfs    defaults         1   1
/dev/hda5        /oboot           reiserfs    defaults         1   2
/dev/hdb2        /ohome           ext3        defaults         1   2
/dev/hdb3        /olinux          ext3        defaults         1   2
/dev/hda1        /win             vfat        noauto,user      1   0
/dev/sr0         /sr0             iso9660     noauto,user,ro   0   0
/dev/cdrom       /cdrom           iso9660     noauto,user,ro   0   0
/dev/fd0         /floppy          auto        noauto,user      0   0
devpts           /dev/pts         devpts      gid=5,mode=620   0   0
proc             /proc            proc        defaults         0   0
#

Anche questa volta un'esempio vale molto più...
Per quanto riguarda i dischi SCSI le cose sono simili, il suffisso cambia in sdXN, quindi sda sda1 sda2...
Le cose possono cambiare se utilizzate devfs, ma noi stiamo parlando di GRUB.
In FreeBSD le cose sono un pochino diverse, in parole povere le partizioni vengono divise ulteriormente, ma io non ho le conoscenze tali da poter nemmeno abbozzare una spiegazione base, quindi evito di andare oltre. ;-P
Dopo questa breve panoramica andiamo oltre e vediamo cosa ci interessa davvero.
Ma a noi interessa sapere come vengono gestiti i dischi dal nostro GRUB! (direte voi)
Si si ora inzio. ;-))
In GRUB i dischi vengono visti tutti come hdN,M dove N identifica il dispositivo ed M la partizione, con la differenza che per identificare dispositivi e partizioni vengono usati numeri da 0 in su, anticipo la mia configurazione di GRUB per potermi spiegare con un'esempio pratico... non fate caso al disordine... ;-PP

# cat /oboot/boot/grub/menu.lst
# menu.lst by Giovanni Mazzamati
#
default=3
timeout=10
splashimage=(hd0,4)/boot/grub/splash.xpm.gz
title Mandrake Linux 9.1 Bamboo (2.4.21)
        root (hd1,2)
        kernel /boot/vmlinuz-2.4.21 ro root=/dev/hdb3 vga=788 quiet hdd=ide-scsi
        initrd /boot/initrd.img
title Salckware 9.0 (2.4.20-custom)
        root (hd0,5)
        kernel /boot/vmlinuz-2.4.20 ro root=/dev/hda6 vga=791 hdd=ide-scsi
title Win 98 SE
        rootnoverify (hd0,0)
        chainloader +1
title failsafe
        kernel (hd1,2)/boot/vmlinuz root=/dev/hdb3 failsafe hdd=ide-scsi
        initrd (hd1,2)/boot/initrd.img
#

Preciso che il dispositivo di boot è il master del primo canale IDE (/dev/hda) e che GRUB (stage2, menu.lst, ecc...) sono contenuti nella partizione /dev/hda5, una piccola partizione in cui tengo la mia installazione del boot loader ed alcuni kernel Linux.
Come si vede dal menu.lst alla riga 5 la mia /dev/hda5 viene vista come hd0,4, chiaro no?
Di conseguenza ragionandoci un pò su si nota come GRUB vede dischi e partizioni.
Torniamo all'utilizzo di GRUB.
Nello scorso articolo abbiamo visto velocemente una prova di boot

grub> rootnoverify (hd0,0)
grub> makeactive
grub> chainloader +1
grub> boot

Il primo comando "rootnoverify (hd0,0)" indica quale partizione deve essere letta da ora in poi, ma senza verificare che tipo di filesystem vi è scritto.
"makeactive" rende la partizione attiva, cosa richiesta da alcuni sistemi operativi per fare boot.
Il terzo comando "chainloader +1" indica a GRUB che non deve caricare un kernel specifico, ma quello che trova nel primo settore di boot della partizione (BPR).
Infine "boot"... indovinate? ;-P
Il modo su esposto è utile pe far caricare un sistema win9x, ma ho verificato che funziona anche con winNT.
Se volessimo caricare un kernel Linux dovremmo dare i seguenti comandi:

grub> root (hd0,5)
 Filesystem type is reiserfs, partition type 0x83

In questo caso abbiamo usato il comando "root" e GRUB ha riconosciuto correttamente la partizione ed il suo filesystem.

grub> kernel /boot/vmlinuz-2.4.20 root=/dev/hda6 ro vga=791 hdd=ide-scsi
   [Linux-bzImage, setup=0x1400, size=0x1225f4]

Il comando kernel trova il kernel da caricare al quale è possibile passare i parametri per fare un corretto boot, tipo la partizione di root (/dev/hda6) che deve essere usato il framebuffer della scheda video a 1024x768 (vga=791) e che il mio masterizzatore IDE deve essere emulato SCSI.

grub> boot

E come al solito con questo comando viene caricato il nostro kernel.

Facile vero? ;-) Provate più volte per fare pratica e vedrete come è semplice caricare qualsiasi OS.
Ma fare boot per lo stesso kernel sempre attraverso la linea di comando non è il massimo, ma possiamo automatizzare il tutto con il file testo menu.lst che dovremmo porre nella dir /boot/grub, il formato del file lo avete già visto sopra, non dovete far altro che ricalcare la stessa struttura, ma di questo parleremo più avanti.

Un uso correto (forse) della minimal-shell

Una cosa che vale la pena di menzionare è il fatto che la shell di GRUB minimale di tipo bash-like e quindi supporta il completamento automatico dei comandi, faccio un piccolo esempio e per renderlo più semplice indicherò la tabulazione con "<tab>" e l'invio con "<invio>":

grub> r
 Possible commands are: read reboot root rootnoverify

ho semplicemente digitato una "r" e di seguito una tabulazione, la shell mi ha suggerito i comandi disponibili che iniziano con r

grub> ro

ho aggiunto una "o" e la schell ha aggiunto "ot" e mi avvisa che ci sono due possibili alternative

grub> root
 Possible commands are: root rootnoverify
grub> rootn

con l'aggiunta di una "n" seguita da una tabulazione...

grub> rootnoverify

Basta inserire i paramentri ed il gioco è fatto

grub> rootnoverify (hd0,1)

grub>

Continuo con l'esempio senza commentare ulteriormente...

grub> kernel /b
 Possible files are: bin boot

grub> kernel /boot/
 Possible files are: System.map config System.map-ide-2.4.20 vmlinuz config-ide
-2.4.20 vmlinuz-ide-2.4.20

grub> kernel /boot/vmlinuz
 Possible files are: vmlinuz vmlinuz-ide-2.4.20

grub> kernel /boot/vmlinuz
   [Linux-bzImage, setup=0x1400, size=0x11c584]

grub>

Questo è uno dei modi di utilizzare GRUB in modo semplice senza troppi sforzi dover ricordarsi per forza a memoria i comandi e la loro sintassi.

Come abbiamo menzionato poco sopra è possibile creare un file di configurazione nel quale inserire le nostre possibili scelte. Il file in questione è il già citato "menu.lst", che verrà utilizzato da GRUB al boot per creare un menu testuale per poter effettuare le scelte all'avvio senza dover inserire comandi e parametri.

Questo ne è un'ulteriore esempio:

default=1
timeout=10
title Red Hat Linux (2.4.20-18.9)
        root (hd0,5)
        kernel /boot/vmlinuz-2.4.20-18.9 ro root=LABEL=/ vga=791 hdd=ide-scsi
        initrd /boot/initrd-2.4.20-18.9.img
title Slackware Linux 9.0 (2.4.20-custom)
        root (hd1,2)
        kernel /boot/vmlinuz-2.4.20 ro root=/dev/hdb3 vga=791 hdd=ide-scsi
title Mandrake Linux 9.1
        root (hd0,4)
        kernel /boot/vmlinuz-2.4.21-0.13mdk ro root=/dev/hda5 vga=791 hdd=ide-scsi
        initrd /boot/initrd-2.4.21-0.13mdk.img

Una volta adattato alle vostre esigenze salvatelo nella dir /boot/grub e fate un reboot.

Un'altra cosa che volevo dirvi è' il fatto che esiste una patch (scaricabile da http://linuxfromscratch.org/~gerard/grub-0.92-vga16.patch) per GRUB per permettergli l'inserimento di una immagine di splash in background all'avvio. Per far ciò una volta scompattati i sorgenti dovete applicare la patch, quindi entriamo nella dir dei nostro sorgenti, dove abbiamo posto anche il file appena scaricato ed eseguiamo:

patch -Np1 -i grub-0.92-vga16.patch
echo "#define VGA16 1" >> config.h.in

ora è possibile eseguire i classici comandi:

./configure
make
su
make install

e questa volta vi indicherò come installare (se vi aggrada) il nostro caro GRUB nel MBR del vostro HD.

grub> root (hd0)
grub> setup (hd0)
grub> quit

È praticamente la stessa procedura che abbiamo già utilizzato la scorsa volta per installare GRUB su floppy, quindi va creata la dir /boot/grub e vi vanno copiati i file stage:

cp /usr/local/share/grub/i386-pc/stage* /boot/grub

ponete nella stessa dir il vostro menu.lst e inserite questa come terza riga:

splashimage=(hd0,5)/boot/grub/splash.xpm.gz

ovviamente anche qui dovete adattare la riga appena esposta alla vostra configurazione.

Devo precisare inoltre che l'immagine deve essere 640x480 pixel e 16 colori e di tipo XPM compresso, potete trovarne di vario genere nella grande rete.

Conclusioni

GRUB supporta il boot in vari modi e per vari sistemi ed inizialmente pensavo di sperimentarne più di uno per poterli poi esporre, ma il tempo a mia disposizione non è molto, quindi vi rimando alla documentazione ufficiale per eventuali approfondimenti.




Giovanni Mazzamati

Revisori: Chiara Bianchi, Antonio Bracaglia, Daniela Chiari e Ferdinando Ferranti.



Bibliografia:

http://www.gnu.org/software/grub

Linux Journal n° 18 (lug-ago 2001)


ML linux@ml.oltrelinux.com - dove ho appreso il modo di applicare la patch ai sorgenti per lo splash (GIAn)