Come installare Ubuntu su un hard disk esterno USB
Introduzione:
Con l'arrivo sul mercato di memorie USB
dell'ordine del GB ed in particolar modo con alcuni dischi rigidi esterni mi
sono chiesto: sarebbe possibile installare una distribuzione Linux su questi
supporti ed esse 15415n1323p re in grado di avviarla su qualsiasi macchina? Dopo varie prove
ho raggiunto il mio obiettivo e in questo tutorial cerchero' di spiegare come
ho fatto.
Prima di addentrarmi nei dettagli implementativi desidero sottolineare alcuni
vantaggi che porta questa soluzione:
A queste tre caratteristiche ne vanno aggiunte altre di natura secondaria ma pur sempre rilevanti come:
Ho optato per un disco rigido piuttosto che una memoria flash in quanto
quest'ultima ha un numero predefinito di scritture, limite inaccettabile
per un S.O. che deve continuamente scrivere log files, aggiornare il database
dei file ecc...
Scelta della distribuzione:
La scelta e' ricaduta su Xubuntu perche':
piu' nello specifico la release che ho usato
e' Xubuntu 6.06.1 (Dapper Drake)
update: dove necessario ho specificato le modifiche nel caso utilizziate la
nuova Edgy Eft.
Installare Xubuntu sul disco esterno USB:
La fase di installazione non presenta
particolari accorgimenti rispetto ad una normale installazione di Xubuntu, per
questo vi rimando alla Ubuntu Installation Guide che trovate sul CD
di installazione sotto doc/install/manual/en/index.html o al wiki in italiano
Le varie fasi dell'installazione sono:
user@ubuntu:~$
fdisk -l
Disk /dev/sda: 10.0 GB, 10000005120 bytes
255 heads, 63 sectors/track, 1215 cylinders
Units = cilindri of 16065 * 512 = 8225280 bytes
Dispositivo Boot
Start
End Blocks Id System
/dev/sda1 1
1215 9759456 b W95 FAT32
Eventuali ambiguita' possono essere risolte con il comando dmesg | less
che visualizza i messaggi del kernel, nel mio caso mostra:
user@ubuntu:~$
dmesg | less
....
usb 4-6: new high speed USB device using ehci_hcd and address 2
Initializing USB Mass Storage driver...
scsi0 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 2
usb-storage: waiting for device to settle before scanning
usbcore: registered new driver usb-storage
USB Mass Storage support registered.
Vendor:
Model: TOSHIBA MK2006GA Rev: BY30
Type: Direct-Access
ANSI SCSI revision: 00
usb-storage: device scan complete
Driver 'sd' needs updating - please use bus_type methods
SCSI device sda: 19531260 512-byte hdwr sectors (10000 MB)
sda: assuming drive cache: write through
SCSI device sda: 19531260 512-byte hdwr sectors (10000 MB)
sda: assuming drive cache: write through
sda: sda1
sd 0:0:0:0: Attached scsi disk sda
sd 0:0:0:0: Attached scsi generic sg0 type 0
.....
Solitamente i dischi USB vengono visti come dischi SCSI col nome sda, sdb,
sdc ecc.., mentre le partizioni all'interno di un disco sono viste come sd?1
sd?2 ecc..
Per una guida al partizionamento consultate Partizioni per Ubuntu Desktop
Come configurazione ho scelto:
user@ubuntu:~$
fdisk -l
Disk /dev/sda: 10.0 GB, 10000005120 bytes
255 heads, 63 sectors/track, 1215 cylinders
Units = cilindri of 16065 * 512 = 8225280 bytes
Dispositivo Boot
Start
End Blocks Id System
/dev/sda1
1
62 497983+ 82 Linux swap / Solaris
/dev/sda2
63 488
3421845 83 Linux
/dev/sda3
489 1215
5839627+ b W95 FAT32
Boot del sistema:
Se il BIOS lo
supporta e' possibile fare il boot da USB. In tali bios sono presenti le
opzioni di boot usb-hdd, usb-fdd e usb-zip.
N.B. Si deve usare l'opzione usb-hdd, per ulteriori spiegazioni rimando a
The
proper mode to boot a USB key drive in is "USB-HDD". That is
the
ONLY mode in which the C/H/S geometry encoded on the disk itself
doesn't have to match what the BIOS thinks it is. Since geometry on
USB drives is completely arbitrary, and can vary from BIOS to BIOS,
this is the only mode which will work in general.
Altrimenti e' necessario fare il boot da floppy/CD.
L'idea e' quella di fare il boot da floppy/CD del kernel Linux
presente sul disco USB (chain load).
Attualmente non e' disponibile "in modo esplicito" un boot loader che
riesca a fare un chain load verso dispositivi USB.
Alcuni risolvono questo problema copiando su un CD l'immagine del kernel +
l'initram e poi facendo il boot da CD. Qusto comporta 2 svantaggi: in primo
luogo con ogni aggiornamento del kernel e' necessario rimasterizzare il CD di
boot, secondariamente, poiche' la dimensione del kernel + l'initram superano
abbondantemente la capacita' di un floppy, su quei sistemi che non supportano
il boot direttamente da CD e' necessario bootare da floppy (chain load) ad
esempio con Smart Boot Manager
Io ho risolto il problema grazie a kboot.
kboot is a proof-of-concept implementation of a Linux boot loader based on kexec.
Praticamente ho creato un piccolo Linux composto dal solo kernel (
con supporto alla Tastiera, USB, CPU, Video Testuale e poco piu' ) e
l'initram, il quale, una volta avviato da floppy o da CD, e' in
grado tramite kexec di caricare il Linux presente sul disco
esterno.
kexec is a set of systems call that allows you to
load another kernel
from the currently executing Linux kernel.
Mi sto' dilungando troppo per i dettagli relativi a questo metodo, forse faro'
un tutorial piu' avanti.
Per ora scaricate l'archivio kboot_usb.tar.gz
e estraetelo.
Alcune note:
Come pre-bootloader ho usato Grub. Il mio metodo prevede che sul disco USB
siano presenti, nella root della partizione indicata dal parametro usbboot,
i file:
vmlinuz
initrd.img
vmlinuz.old
initrd.img.old
Nel caso di Ubuntu dovrebbero esistere di default come link all'ultimo kernel e
al precedente.
Se come parametro viene passato oldkernel viene caricato vmlinuz.old
Inoltre i parametri che iniziano con t_ (target) verranno passati al
kernel residente sul disco USB senza il prefisso t_
Quindi in generale si tratta di editare il file menu.lst e impostare
usbboot=nome partizione che contiene i file
vmlinuz ecc..
root=/dev/nome partizione radice del sistema
Nel mio caso, avendo fatto un'unica partizione per Linux, coincidono e sono
sda2.
Come dicevo, dopo averlo estratto, troverete una cartella bootcd e
un'immagine di un floppy floppy.img
Come creare il CD di avvio:
user@ubuntu:~$ mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o bootcd.iso bootcd
mkisofs fa parte del pacchetto cdrecord
Come creare il floppy di avvio:
user@ubuntu:~$ dd if=floppy.img of=/dev/fd0
oppure da win usate rawwrite
Riavviate facendo il boot dal CD o dal floppy.
Vi si presenta la schermata di Grub con le seguenti opzioni:
Fatta la scelta, carica kboot e vi presenta una shell
kboot:
aspettate che trovi il disco usb
kboot: sda: assuming drive cache: write through
sda: assuming drive cache: write through
e poi premete invio. Se tutto e' andato bene dovrebbe caricare Ubuntu.
Rendere il nuovo sistema autoconfigurabile come una distribuzione Live:
Dopo un po' di reverse engineering/ricerche ho
capito come funziona il boot di Ubuntu:
Alcuni link interessanti che spiegano il funzionamento di initramfs e come
usarlo sono:
Qui di seguito riassumo brevemente: all'avvio il boot loader carica il kernel,
il quale controlla la presenza del parametro initrd= che specifica
qual'e' l'initial root filesystem.
Se e' presente viene scompattato in RAM e montato come radice del sistema
"/" . A questo punto se il filesystem in RAM contiene un programma
chiamato "/init" il kernel lo esegue come primo programma.
Fino a qui il comportamento e' il medesimo per tutte le distribuzioni che usano
il kernel 2.6.X.
Cio' che cambia da distribuzione a distribuzione e' il comportamento dettato
dal file init.
Una prima cosa utile da sapere č che Ubuntu usa la funzione log_begin_msg per
stampare i messaggi che appaiono durante il boot nella splash screen.
Diversamente da quello che si potrebbe pensare la diversita' tra l'avvio della
versione Live rispetto a quella normale risiede nel parametro di avvio boot=casper
il quale, dopo essere analizzato dallo script init, fa si che BOOT
assuma il valore "casper" sovrascrivendo il valore di default
"local" ( /conf/initramfs.conf ) in questo modo init carica le
funzioni contenute nel file /scripts/casper al posto di /scripts/local
file: init
...
boot=*)
BOOT=$
;;
...
. /scripts/$
...
Nella splash screen all'avvio appare
|
||
Loading essential drivers... |
||
|
||
Preparing restricted drivers... |
Per vedere i messaggi nella Edgy Eft bisogna togliere il parametro del kernel quiet.
come si puo' notare fino a Mounting root file system... il comportamento
č uguale
file: init
...
maybe_break mount
log_begin_msg "Mounting root file system..."
mountroot
log_end_msg
...
Dopo aver stampato il messaggio Mounting root file system..., chiama mountroot
, funzione che č definita sia in /scripts/casper che in /scripts/local
Quella in casper monta la root / in ram mentre quella in local monta il
filesystem presente su disco.
In modo astratto il compito che svolgono č lo stesso, cambia perō verso la fine
dove
file: scripts/local
...
[ "$quiet" != "y" ] && log_begin_msg "Running
/scripts/local-bottom"
run_scripts /scripts/local-bottom
[ "$quiet" != "y" ] && log_end_msg
...
file: scripts/casper
...
maybe_break casper-bottom
[ "$quiet" != "y" ] && log_begin_msg "Running
/scripts/casper-bottom"
caso Dapper Drake
PATH=/root/usr/bin:/root/usr/sbin:/root/bin:/root/sbin:$PATH run_scripts /scripts/casper-bottom
caso Edgy Eft
pulsate
run_scripts /scripts/casper-bottom
[
"$quiet" != "y" ] && log_end_msg
...
Uno esegue gli script presenti in /scripts/local-bottom e l'altro quelli in
/scripts/casper-bottom
se osserviamo local-bottom č vuoto mentre casper-bottom contiene tutti gli
script che eseguono le
varie autoconfigurazioni. Di questi a noi interessano:
14locales
19keyboard
20xconfig
23etc_modules
23networking
gli altri sono utili solo ad una live.
Una volta eseguito mountroot il flusso di esecuzione torna al file init il
quale verso la fine esegue /sbin/init
file: init
....
export init=/sbin/init
....
exec run-init $ $ "$@" <$/dev/console
>$/dev/console
....
/sbin/init fa parte del metodo classico di inizializzazione di Linux (System V
initialization)
per una spiegazione riguardo al suo funzionamento man init
Questo era vero fino alla Dapper Drake, dalla Edgy Eft il nuovo sistema di
inizializzazione e' upstart
Upstart is an event-based replacement for the /sbin/init daemon which handles starting of tasks and services during boot, stopping them during shutdown and supervising them while the system is running.
In entrambi i casi comunque il risultato č che vengono eseguiti gli scripts
presenti sul disco USB in /etc/rcS.d
Da tutta questa analisi ricaviamo che il pacchetto responsabile di rendere
live Ubuntu e' casper. Quindi non dobbiamo far altro che:
installare casper, copiare i file di interesse in /scripts/casper-bottom,
fare qualche modifica a /init e ricreare l'initram.
Modifiche da apportare a /usr/share/initramfs-tools/init ( vanno aggiunte le parti in grassetto )
....
export debug=
export autoconfigure=
....
for x in $(cat /proc/cmdline); do
.....
debug)
debug=y
exec >/tmp/initramfs.debug 2>&1
set -x
;;
autoconfigure)
autoconfigure=y
;;
break=*)
break=$
;;
.....
if [ "$autoconfigure" = "y" ]
then
readonly=n
fi
.....
mountroot
log_end_msg
if [ "$autoconfigure" = "y" ]
then
maybe_break autoconfigure
[ "$quiet" != "y" ] &&
log_begin_msg "Running /scripts/autoconfigure"
caso Dapper Drake
PATH=/root/usr/bin:/root/usr/sbin:/root/bin:/root/sbin:$PATH run_scripts /scripts/autoconfigure
caso Edgy Eft
pulsate
run_scripts /scripts/autoconfigure
[ "$quiet" != "y" ] &&
log_end_msg
fi
maybe_break bottom
....
In questo modo quando all'avvio aggiungiamo il parametro autoconfigure
verā fatta l'autoconfigurazione altrimenti verranno tenute le ultime
impostazioni
Ora va creata la cartella
/etc/mkinitramfs/scripts/autoconfigure ( caso Dapper Drake )
/etc/initramfs-tools/scripts/autoconfigure ( caso Edgy Eft )
e al suo interno vanno copiati i file
14locales
19keyboard
20xconfig
23etc_modules
23networking
prendendoli da /usr/share/initramfs-tools/scripts/casper-bottom/
In fine, per ricreare l'initramfs aggiornato:
user@ubuntu:~$ sudo mkinitramfs -o /boot/initrd.img-`uname -r` /lib/modules/`uname -r`
Nel caso di boot da floppy/CD avevo gia' previsto una voce in menu.lst che
avvia Ubuntu eseguendo l'autoconfigurazione. Mentre per l'avvio diretto da USB
bisogna modificare il file /boot/grub/menu.lst ad esempio duplicando la voce
dell'ultimo kernel installato, a cui va aggiunto il parametro autoconfigure.
Nel mio caso risulta:
title
Ubuntu, kernel 2.6.15-27-386
root (hd0,0)
kernel
/boot/vmlinuz-2.6.15-27-386 root=/dev/sda2 ro quiet splash
initrd
/boot/initrd.img-2.6.15-27-386
savedefault
boot
title Ubuntu,
kernel autoconfigure 2.6.15-27-386
root (hd0,0)
kernel
/boot/vmlinuz-2.6.15-27-386 root=/dev/sda2 ro quiet splash autoconfigure
initrd
/boot/initrd.img-2.6.15-27-386
boot
|