1.61. GRUB2-Anleitung
Es gibt etliche Anleitungen für die Benutzung von GRUB2 unter FreeBSD, die aber praktisch alle nicht über die Angabe einer Handvoll Befehle für ein Standard-Setup hinausreichen und/oder noch Altlasten von GRUB1 mitbringen.
In dieser kleinen Anleitung will ich GRUB2 ein wenig genauer unter die Lupe nehmen; GRUB1 werde ich jedoch mit keinem weiteren Wort erwähnen. Auch soll dies nicht eine komplette Installationsanleitung sein mit Partitionierung etc. pp.; dazu könnte man vielleicht den Artikel von User „nukama“ unter dem Titel „MultiBoot mit Grub2“ konsultieren.
Das FreeBSD-Paket beinhaltet eine Info-Datei (info grub
), die
Dokumentation
auf GRUBs Homepage ist ein wenig aktueller; die Dokumentationen von
Ubuntu oder Arch
Linux sind teilweise
sogar noch besser (Ubuntu führt auch *BSD auf), aber natürlich auf die
betreffende Linux-Distribution fokussiert.
Warnung
Die GRUB2-Version in den Ports (1.98_1) ist veraltet und kann den Kernel der neuesten Release (9.1) nicht direkt booten. Sobald ein neuerer Port zur Verfügung steht, werde ich diesen Hinweis entfernen. Vorerst ist nur Chainloading möglich.
1.61.1. Erste Schritte
/boot/grub/grub.cfg
(so
der Standardpfad), aber um deren Syntax dem unbedarften Nutzer zu
ersparen und sie vollautomatisch zu erzeugen, werden Tools
bereitgestellt, die sich auf eine sehr einfache
Meta-Konfigurationsdatei /usr/local/etc/default/grub
stützen. In
den gängigen Linux-bezogenen Anleitungen lautet ihr Pfad übrigens
/etc/default/grub
, das geht in FreeBSD nicht.grub.cfg
zu
bekommen, empfehle ich die Verwendung dieser Automatik. Weil der
FreeBSD-Port aber doch etwas mit heißer Nadel gestrickt ist, sollte
man die so erzeugte grub.cfg
dann auf jeden Fall manuell
nachbearbeiten.Meine /usr/local/etc/default/grub
sieht so
GRUB_DISTRIBUTOR="FreeBSD Release 9.0"
GRUB_DEFAULT=1
GRUB_SAVEDEFAULT=false
GRUB_TERMINAL=console
#GRUB_GFXMODE=1024x768
#GRUB_FONT_PATH=
GRUB_TIMEOUT=9
#GRUB_HIDDEN_TIMEOUT=5
GRUB_DISABLE_OS_PROBER=false
GRUB_DISABLE_RECOVERY=true
GRUB_INIT_TUNE="2000 128 1 192 1 288 1 432 1 648 1 972 1 1458 1 2187 1"``
Es werden nur Variablen gesetzt, die den Skripten im Verzeichnis
/usr/local/etc/grub.d
dann die Informationen liefern, um geeignete
Befehle in die grub.cfg
zu schreiben. Das Kapitel „Configuration“
in der Dokumentation listet die möglichen Variablen auf, manche
Linux-Distributionen fügen denen noch selbstgestrickte hinzu.
Der Aufruf
grub-mkconfig -o /boot/grub/grub.cfg
erstellt die eigentliche Konfigurationsdatei. Bevor wir uns an deren Nachbearbeitung machen, nun ein paar allgemeine Erklärungen.
1.61.2. Bootkonzepte
Der Bootloader besteht, ähnlich wie der von FreeBSD, aus mehreren
Stufen. Die erste paßt in einen 512-Byte-Block (ist sogar noch etwas
kleiner, da sie ggf. Platz für eine Partitionstabelle lassen muß), und
ihr Sinn und Zweck besteht einzig und allein darin, zu wissen, wo die
zweite Stufe liegt und wie sie geladen werden kann. Jene ist typisch
20-30 kB groß, hat als Datei den Namen core.img
und kann nicht aus
einem richtigen Dateisystem herausgelesen werden, weil der Code der
ersten Stufe bei weitem nicht die Intelligenz für ein Dateisystem
mitbringt. [1]
Installationsmöglichkeiten
Wo findet sich nun Platz für GRUBs core.img
? Ein FreeBSD-User hat im
wesentlichen drei Möglichkeiten:
in einer eigenen, dedizierten Partition (bzw. Slice) ohne Dateisystem oder sonstigen Inhalt. Dies wird normalerweise bei GPT-partitionierten Festplatten angewandt und ist wohl die sauberste, eleganteste Lösung. Bei Festplatten nach dem MBR-Schema könnte man theoretisch einen eigenen Slice oder sogar eine Unterpartition innerhalb eines BSD-Labels dafür verwenden, aber so etwas habe ich noch nie gesehen.
in dem für Bootcode vorgesehenen Leerraum eines BSD-Labels. Dieser ist mit 64 kiB leicht groß genug; man hat großzügig in die Zukunft geplant, obwohl der FreeBSD-eigene Bootcode ja nur 8 kiB umfaßt. Es macht auch keinen Unterschied, ob die ganze Festplatte BSD-partitioniert ist (aka dangerously dedicated) oder ob das BSDsche Partitionierungsschema nur in einen MBR-Slice hineingeschachtelt wurde, was ja bis vor kurzem der Standardweg für eine BSD-Installation war.
im MBR und den folgenden Sektoren einer MBR-partitionierten Festplatte. Dies ist der Standardweg für die Verwendung von GRUB auf MBR-Festplatten. Mit Ausnahme des MBR bleibt nämlich die erste Spur ungenutzt, d. h. wird keinem Slice zugeteilt. Eine Spur umfaßt meistens 63 Sektoren, d. i. ca. 31 kiB. GRUB ist natürlich so gestrickt, daß er die fest verplanten Teile des MBR, Partitionstabelle und Magic number, unangetastet läßt.
Eigentlich kann das Core image in jedem staubigen Winkel einer Datenträgerpartitionierung stehen, sofern es sich dort von vorgeschalteten Bootmanagern nur irgendwie hervorholen läßt.
Bootmöglichkeiten
Und wie genau wird FreeBSD nun von GRUB gebootet? Auch dafür finden sich drei Möglichkeiten:
Chainloading: Wenn der FreeBSD-eigene Bootloader vollständig da ist – also nicht im obigen Fall 2 – ruft GRUB einfach den Slice bzw. die GPT-Partition mit diesem Bootloader auf und legt alles weitere vertrauensvoll in dessen Hände. Das ist der bequemste Weg, und GRUB bedarf keiner FreeBSD-spezifischen Konfiguration.
Übergabe an
/boot/loader
: Man könnte dies als halbes Chainloading bezeichnen. Stufe 1 und 2 des FreeBSD-Bootloaders werden nicht gebraucht, deshalb verträgt sich diese Methode auch mit dem obigen Fall 2; die eigentliche Arbeit erledigt aber immer noch der „loader
“ von FreeBSD.direktes Laden der Systemdateien: GRUB muß nun die ganzen Aufgaben des FreeBSD-Loaders selbst übernehmen, insbesondere das Verarbeiten der Konfigurationsdateien
device.hints
undloader.conf
. Im einzelnen:den Kernel laden, ggf. mit Kernelparametern z. B. für serielle Konsole;
die „früh“ zu ladenden Kernelmodule laden, die sonst in der
loader.conf
aufgeführt sind, z. B. den NVidia-Grafiktreiber;die
device.hints
dem Kernel verabreichen;desgleichen für die in der
loader.conf
aufgeführten Kernel-Umgebungsvariablen und Sysctls.
Methode 3 ist natürlich die komplizierteste; aber weil sie die größte
Flexibilität bietet, ist sie diejenige, welche bei Ausführung von
grub-mkconfig
durch die Skripte des FreeBSD-Ports automatisch
eingerichtet wird.
1.61.3. Konfiguration
Wie oben angegeben, sollte man eine Prä-Konfigurationsdatei
/usr/local/etc/default/grub
anlegen und dann das Shellskript
aufrufen:
grub-mkconfig -o /boot/grub/grub.cfg
Anschließend editiert man die erzeugte Datei:
vi /boot/grub/grub.cfg
grub-mkconfig
die Datei
schreibgeschützt anlegt. Entweder entfernt man den Schreibschutz
(chmod u+w /boot/grub/grub.cfg
) oder überzeugt den Editor beim
Abspeichern, sie trotzdem zu überschreiben (in vi :w!
).load_env
“ und „save_env
“
eliminiert, weil ich von GRUB das immergleiche Verhalten erwarte und
mir nicht wohl dabei ist, wenn er bei jedem Boot etwas in eine nicht
gemountete Partition schreibt. Die insmod
-Befehle sind alle
überflüssig, weil GRUB immer von selbst weiß, wann er welches Modul
hinzufügen muß. Die locale
-Datei, z. B. für „de“, hat im
FreeBSD-Port den Pfad
/usr/local/share/locale/de/LC_MESSAGES/grub.mo
. Sie soll ggf. nach
/boot/grub/locale/de/LC_MESSAGES/grub.mo
kopiert werden, dgl. für
andere Sprachen.menuentry
-Abschnitte. Statt des einen, der nun schon automatisch
in der grub.cfg
angelegt wurde, will ich drei Menüeinträge zeigen,
die alle ein und dieselbe FreeBSD-Installation booten, und zwar
entsprechend den oben genannten Möglichkeiten 1, 2 und 3.menuentry "FreeBSD 9.0 (1)" --class freebsd --class bsd --class os {
echo Chainloading slice hd0,2 ...
chainloader (hd0,2)+1
}
menuentry "FreeBSD 9.0 (2)" --class freebsd --class bsd --class os {
set root=hd0,2,a
search --no-floppy --set --fs-uuid 42869b9f5cddfbea
echo Loading FreeBSD '"loader"' from $root ...
kfreebsd /boot/loader
}
menuentry "FreeBSD 9.0 (3)" --class freebsd --class bsd --class os {
set root=hd0,2,a
search --no-floppy --set --fs-uuid 42869b9f5cddfbea
echo Loading FreeBSD 9.0 from $root ...
kfreebsd /boot/kernel/kernel -v
kfreebsd_module_elf /boot/modules/nvidia.ko
kfreebsd_module_elf /boot/kernel/portalfs.ko
kfreebsd_loadenv /boot/device.hints
set kFreeBSD.vfs.root.mountfrom=ufs:/dev/ada0s3
#set kFreeBSD.vfs.root.mountfrom.options=rw
#set kFreeBSD.hint.acpi.0.disabled="1"
set kFreeBSD.debug.acpi.disabled="timer acad video"
set kFreeBSD.kern.hz=100
set kFreeBSD.hw.pci.do_power_nodriver=3
}
zu (1): Beim Chainloading braucht man keine Variable $root
, weil die
Angabe von Partition bzw. Slice im Kommando chainloader
selbst
erfolgen kann.
$root
wird zweimal mit einem Wert belegt, und
zwar einmal ausdrücklich und einmal über das search
-Kommando.
search
ist vorzuziehen, sofern man die UUID des Dateisystems weiß,
weil sich die genaue Partitionsbezeichnung „hd0,2,a
“ bei
Änderung der Partitionierung oder Hinzufügen (in Hardware) eines
weiteren Laufwerks ändern kann. Der ausdrückliche Wert dient nur als
Rückfalloption, falls das search
-Kommando versagt.grub-probe -t fs_uuid -d /dev/ada0s2
Die Binärdatei
/boot/loader
wird überraschenderweise mit demselben Kommando
geladen wie in (3) auch der FreeBSD-Kernel. Man könnte sagen:
/boot/loader
wird von GRUB als Kernel betrachtet. Wenn der
„loader
“ dann läuft, erledigt er alle weiteren Aufgaben:
Kernel und Kernelmodule laden, device.hints
und loader.conf
befolgen etc. Auch das Menü zeigt er an.zu (3): Beim Laden des Kernels mit kfreebsd
können dem Kernel
Kommandozeilenoptionen übergeben werden. Folgende werden von GRUB 2.00
erkannt, soweit ich dem Quellcode entnehmen konnte. Weil ich einige
davon nicht verstehe, zitiere ich sie mit den englischen
Textbausteinen:"dual" 'D' "Display output on all consoles."
"serial" 'h' "Use serial console."
"askname" 'a' "Ask for file name to reboot from."
"cdrom" 'C' "Use CD-ROM as root."
"config" 'c' "Invoke user configuration routing."
"kdb" 'd' "Enter in KDB on boot."
"gdb" 'g' "Use GDB remote debugger instead of DDB."
"mute" 'm' "Disable all boot output."
"nointr" 'n'
"pause" 'p' "Wait for keypress after every line of output."
"quiet" 'q'
"dfltroot"'r' "Use compiled-in root device."
"single" 's' "Boot into single mode."
"verbose" 'v' "Boot with verbose messages."
Angegeben werden kann
die Langform (-
-verbose
, unbedingt mit doppeltem Bindestrich!)
oder Kurzform (-v
) wie beim Kernel oben.
*.ko
lädt man mit
kfreebsd_module_elf
. GRUB will den vollen Verzeichnispfad, daher
muß man feststellen, ob ein Modul in /boot/modules
oder
/boot/kernel
steht.kfreebsd_module
(ohne _elf
); ich bin
nicht sicher, wozu er dient FIXME, eventuell für nicht ausführbare
Module wie Ramdisk-Images o. ä. Er findet normalerweise keine
Verwendung.Mit kfreebsd_loadenv
liest man eine Datei mit Umgebungsvariablen für
den Kernel ein. Das ist geeignet für device.hints
, nicht aber für
loader.conf
. Jene enthält nämlich neben Umgebungsvariablen bzw.
Sysctls noch einige andere Anweisungen:
zu ladende Kernelmodule,
Anweisungen für den FreeBSD-Bootloader selbst, z. B. bzgl. Menü oder Beastie-Bild,
Anweisungen für Kerneloptionen, die GRUB ja direkt übergibt, siehe oben.
Entweder schreibt man die Umgebungsvariablen und Sysctls also in eine
separate Datei, die man dann wie die device.hints
einliest:
kfreebsd_loadenv /boot/loader.conf.rest
set
-Befehl. Dazu muß
ihnen ein „kFreeBSD.
“ (beachte die Großschreibung)
vorangestellt werden.Bei verschiedenen Anleitungen im Internet findet sich für die
Pfadangaben in kfreebsd
und den anderen Befehlen eine Syntax der Art
kfreebsd /foo/bar@/boot/kernel/kernel
/foo/bar@
wählt man einen bestimmten
aus, also: Dataset bar
innerhalb von Dataset foo
– und dort
bitte den Pfad /boot/kernel/kernel
!Wenn etwas schiefläuft und das System so schnell rebootet, daß man die
Fehlermeldung nicht erkennt, hilft ein Befehl‘‘ sleep 7 ‚‘am Ende des
menuentry
. Damit gewinnt man 7 s Zeit.
1.61.4. Schluß
Ist alles vollständig, so wird der Bootcode installiert mit
grub-install /dev/ada0
… hier z. B. in den MBR – oder mit /dev/ada0s2
in einen Slice
anstelle des FreeBSD-Bootcodes. Für GRUB-Versionen vor 2.00 beta2 sollte
man die Option --no-floppy
angeben, weil sonst auch nach einer
Floppy gesucht wird, was die Installation verlangsamt und u. U. sogar
blockiert.
Bemerkung
Einen Wunsch noch: Könnte jemand dieses HowTo bzgl. der anderen BSDs
ergänzen? Was, außer dem einfachen Umschreiben der Befehle
(kfreebsd-->knetbsd
), ist dafür notwendig?
Wenn man GRUB erst einmal beherrscht, kann man richtig abgehobene Sachen damit machen, z. B. Boot übers Netzwerk oder aus einem Image. Der Grund, GRUB einzusetzen, sind ja gerade die exotischen Setups, die der FreeBSDsche Bootloader nicht kann.
Viel Spaß beim Experimentieren!
Zuletzt geändert: 2023-07-22