Ve Fedoře 16 byl Grub nahrazen novou verzí. Touto změnou jsme získali zavaděč s novými funkcemi. Vypadá to ale, že jsme tím přišli o barvy a že Grub 2 je optimalizován pouze pro černobílé monitory.

Není tomu tak. Grub 2 barvy umí, jen si je tam musíme přidat sami.

Barevný Grub

První možností, jak přinutit Grub něco obarvit, je použití proměnných color_normal, color_highlight, menu_color_normal a menu_color_highlight, které nastavují barvu popředí a pozadí pro text, zvýrazněný text, menu a jeho položky a vybranou položku v menu. Lze použít následující barvy:

white (bílá) blue (modrá) magenta (fialová) cyan (tyrkysová)
light-gray (světle šedá) yellow (žlutá) red (červená) light-magenta (sv. fialová)
dark-gray (tmavě šedá) green (zelená) light-blue (sv. modrá) light-red (sv. červená)
black (černá) light-cyan (sv. tyrkysová) light-green (sv. zelená) brown (hnědá)

Pro dosažení výsledku na obrázku je potřeba editovat soubor /boot/grub2/grub.cfg a zadat tam následující řádky:

set menu_color_normal=white/blue
set menu_color_highlight=green/red
set color_normal=yellow/black
set color_highlight=green/dark-gray

Třeba hned nahoru pod komentář s varováním, abyste needitovali tento soubor. Jak je napsáno v komentáři, tak tento soubor je skutečně generován nástrojem grub2-mkconfig s použitím šablon. Při instalaci nového jádra ale soubor (aktuálně) není přegenerováván, nýbrž editován skriptem. O změny se tedy nepřijde.

Běžně se používá postup, při kterém se výše uvedené proměnné nastaví v souboru /etc/default/grub, kde jméno proměnné je původní jméno proměnné zadané velkými písmeny a s prefixem GRUB_, tedy například GRUB_MENU_COLOR_NORMAL. Bohužel, šablony ve Fedoře tyto proměnné nepodporují. Pokud je tedy do souboru zadáte, nijak se neprojeví.

Pomocí těchto proměnných nejde dosáhnout plného obarvení Grubu. Barva pozadí normálního textu se totiž aplikuje pouze tam, kde je nějaký text vypsán. Ostatní pozadí zůstane černé. Pouze v případě menu se jeho základní barva aplikuje na celý box. Tedy i tam, kde žádný text vypsán není.

Grafický režim

Kromě základních barev textového režimu umí Grub i grafický režim. Ten musíme použít, pokud chceme vložit na pozadí obrázek. Grub podporuje obrázky ve formátech png, tga a jpg. Vždy je nutné po přidání obrázku přegenerovat konfigurační soubor, protože Grub si načítá jen ty moduly, které budou potřeba. Obrázek by pak mohl být nedostupný, protože by chyběl modul na práci s obrázkem použitého formátu.

Pro lepší grafické úpravy použijeme Grub v grafickém režimu. Přestože systém, kde by grafický režim nefungoval, bude asi velkou vzácností, je lepší podporu nejprve ověřit. Toto se provede v konzoli Grubu. Při startu Grubu stiskněte klávesu 'c' a dostanete se do zmíněné konzole. V konzoli zadejte příkaz 'vbeinfo' a Grub vypíše podporované grafické režimy. Rozlišení 640x480 a 800x600 bude fungovat nejspíše všude. Zadáním příkazu 'exit' se vrátíme do původního menu, odkud nastartujeme systém.

Ještě před tím, než nastavíme grafický režim, připravíme si soubory s písmem. U Grubu lze přidat pozadí jen v grafickém režimu a grafický režim musí mít explicitně zadané písmo. Buď lze použít písmo, které běžně najdete na systému (například DejaVu Sans), nebo použít unifont z http://unifoundry.com/unifont.html. První varianta funguje dobře při použití celého grafického motivu.

Při použití jen obrázku na pozadí nefungují fonty DejaVu Sans dvakrát dobře, protože znaky pro rámec menu nejsou úplně vhodné. Rámec pak vypadá jako nakreslený přerušovanou čárou. Soubory s písmem a obrázky umisťuji do adresáře /boot/themes, který je potřeba vytvořit. Písmo si připravíme takto:

cd /tmp
wget http://unifoundry.com/unifont-5.1.20080907.ttf.gz
gunzip unifont-5.1.20080907.ttf.gz
grub2-mkfont --output /boot/themes/unifont.pf2 unifont-5.1.20080907.ttf
rm unifont-5.1.20080907.ttf.gz

Alternativně lze místo unifontu použít DejaVu Sans Mono (z balíčku dejavu-sans-mono-fonts), kde přegenerované písmo získáme pomocí:

grub2-mkfont --output=/boot/themes/DejaVuSansMono.pf2 /usr/share/fonts/dejavu/DejaVuSansMono.ttf

Nyní nastavíme grafický režim v souboru /etc/default/grub, zvolíme si nějaký obrázek na pozadí a řekneme o tom Grubu uložením cesty k obrázku do proměnné GRUB_BACKGROUND v témže souboru:

GRUB_TERMINAL_OUTPUT=gfxterm	# nastavuje graficky rezim
GRUB_GFXMODE=800x600	  	# pozadovane rozliseni
GRUB_FONT=/boot/themes/unifont.pf2	# alternativne /boot/themes/DejaVuSansMono.pf2
GRUB_BACKGROUND=/boot/themes/discworld.png	# zvolene pozadi

Nyní je potřeba přegenerovat soubor /boot/grub2/grub.cfg. Buď pomocí příkazu grub2-mkconfig -o /boot/grub2/grub.cfg, což ale může udělat v položkách menu Grubu nepořádek, nebo vygenerovat menu do nového souboru a jen prohodit úvodní část souboru - tu mezi řádky '### BEGIN /etc/grub.d/00_header ###' a '### END /etc/grub.d/00_header ###'. To lze udělat i méně pracně pomocí následujícího skriptu.

GRUBCFG=/boot/grub2/grub.cfg
GRUBCFG_NEW=$(mktemp)

sed '/^### BEGIN \/etc\/grub.d\/00_header ###/,$d' <$GRUBCFG >$GRUBCFG_NEW
grub2-mkconfig | sed -n '/^### BEGIN \/etc\/grub.d\/00_header ###/,/^### END \/etc\/grub.d\/00_header ###/p' >>$GRUBCFG_NEW
sed '0,/^### END \/etc\/grub.d\/00_header ###/d' <$GRUBCFG >>$GRUBCFG_NEW
cat $GRUBCFG_NEW >$GRUBCFG
rm -f $GRUBCFG_NEW

Grafický režim s pozadím lze kombinovat s volbou barev textu a pozadí. Jedinou změnou je, že černá u pozadí má význam průhledná – u textu nebude pozadí černé, ale bude vidět obrázek pozadí. Nastavení barev se opět musí přidávat ručně. Tentokrát nestačí umístit jej kamkoliv. Dobré místo pro umístění je třeba hned pod řádek 'terminal_output gfxterm'. Výsledkem může být třeba Grub na následujícím obrázku. Pro ukázku čárkovaného okraje menu je zde varianta s písmem DejaVu Sans Mono. Při použití písma unifont by čára přerušovaná nebyla.

Grafické motivy

Grub nabízí ještě více možností grafického přizpůsobení - použití grafických motivů. Motiv se popisuje do textového souboru. Základní parametry motivu jsou (v závorce uvedeny výchozí hodnoty):

title-text titulek Grubu (GRUB Boot Menu)
title-font písmo titulku (Unknown Regular 16)
message-font písmo obecného textu v Grubu (Unknown Regular 16)
message-color barva obecného textu v Grubu (white)
message-bg-color barva pozadí textu v Grubu (black)
desktop-image obrázek pozadí
desktop-color barva pozadí, pokud není použit obrázek (white)
terminal-box šablona jmen souborů pro dekoraci terminálu (pouze černý obdélník)
terminal-font písmo použité v terminálu (Fixed 10)

Barvy se zde nezadávají ve tvaru popředí/pozadí jako u ostatních variant, ale jednotlivě. Je možné je zadávat třemi způsoby:

  • názvem (např. "black")
  • ve formátu HTML #rrggbb (např. "#00afff")
  • ve formátu RGB (např. "0,175,255")

Písmo se zadává ve tvaru "Název Typ Velikost". Typ může být Regular, Bold či Obligue tedy normální, tučný či kurzíva. Například "DejaVu Sans Bold 16".

Šablona jmen souborů s obrázky pro dekoraci se uvádí ve tvaru "/cesta/jméno_souboru*.přípona", například "/boot/themes/terminal_*.jpg". Grub pak bude hledat soubory se jmény terminal_n.jpg, terminal_ne.jpg, terminal_e.jpg, ... Vždy místo hvězdičky doplní konkrétní požadované umístění obrázku. Umístění jsou označena značkou zeměpisného směru, střed je označen 'c'.

levý horní roh
nw
horní hrana
n
pravý horní roh
ne
levá hrana
w
střed
c
pravá hrana
e
levý dolní roh
sw
dolní hrana
s
pravý dolní roh
se

Horní a dolní hranu Grub roztáhne ve vodorovném směru, levou a pravou hranu roztáhne svisle a střed roztáhne pro kompletní vyplnění středové části. Soubory stačí jen ty, které opravdu chcete, není potřeba použít všechny. Lze tedy vynechat střed nebo například použít jen okraje vlevo a vpravo.

Menu má vlastní styly, které jsou ohraničeny blokem "+ boot_menu { ..... }". Vlastnosti, kterými lze dekorovat menu, jsou (v závorce výchozí hodnoty):

visible zda je menu viditelné (true)
left jak daleko od levého okraje začíná menu
top jak daleko od horního okraje začíná menu
width šířka menu
height výška menu
icon_height výška ikony u položky menu (32)
icon_width šířka ikony u položky menu (32)
item_color barva textu položky menu (black)
item_font písmo pro položky menu (Unknown Regular 16)
item_height výška položky menu (42)
item_icon_space mezera mezi ikonou a textem položky (4)
item_padding mezera mezi okrajem menu a položkou menu (14)
item_spacing mezera mezi položkami menu (16)
menu_pixmap_style šablona jmen souborů pro dekoraci menu
selected_item_color barva vybrané položky (black)
selected_item_font písmo vybrané pložky (stejný jako item_font)
selected_item_pixmap_style šablona jmen souborů pro dekoraci vybrané položky
scrollbar zda zobrazit posuvník (true)
scrollbar_frame šablona jmen souborů pro dekoraci posuvníku
scrollbar_thumb šablona jmen souborů pro dekoraci jezdce posuvníku
scrollbar_width šířka posuvníku

Jak napovídají proměnné v menu, Grub umí používat u položek i ikony. Ikony nemusí mít přesnou velikost. Grub si je dokáže sám zvětšit či zmenšit. Pokud se však ikony zmenšují či zvětšují výrazněji, je lepší je upravit v grafickém editoru, kde budou po změně velikosti díky lepším algoritmům vypadat lépe.

Ikony musí mít správné jméno souboru. K položkám v menu se totiž přiřazují automaticky na základě třídy. Definice běžné položky v konfiguračním souboru vypadá takto:

menuentry 'Fedora (3.3.4-5.fc17.x86_64)' --class gnu-linux --class gnu --class os {

Položka tedy patří do tříd gnu-linux, gnu, os. Grub se podívá do adresáře s ikonami a zkusí najít popořadě některou z ikon: gnu-linux.*, gnu.*, os.* a použije první, co mu přijde pod ruku. Ikony Grub hledá v adresáři icons/ umístěném v adresáři použitého motivu.

Pokud používáte jen Fedoru a Windows, můžete ikonku Fedory pojmenovat třeba gnu-linux.png a není třeba více řešit. Pokud používáte více distribucí Linuxu, budete muset upravit konfigurační soubor a před ostatní třídy přidat ještě --class Fedora.

Kromě menu má Grub ještě speciální blok progress_bar pro zobrazení informace o odpočtu do výběru výchozí položky v menu. Tato informace nemusí být jen textová, může se jednat o klasický grafický ukazatel průběhu. Vlastnosti bloku progress_bar jsou:

id identifikátor ukazatele průběhu, tato hodnota musí být nastavena na "__timeout__"
visible zda se ukazatel průběhu zobrazí (true)
left jak daleko od levého okraje začíná
top jak daleko od horního okraje začíná
width šířka
height výška
bg_color barva pozadí, pokud není použita dekorace obrázky ("128,128,128")
fg_color barva popředí (část, která již uplynula), pokud není použita dekorace obrázky ("200,200,200")
border_color barva okraje, pokud není použita dekorace obrázky (black)
show_text zda zobrazit text o odpočtu
text text, který zobrazit na ukazateli průběhu. Kromě libovolného textu je možné zadat některou ze speciálních hodnot:
- @TIMEOUT_NOTIFICATION_SHORT@ = ?s
- @TIMEOUT_NOTIFICATION_MIDDLE@ = ?s remaining.
- @TIMEOUT_NOTIFICATION_LONG@ = The highlighted entry will be executed automatically in ?s.
text_color barva textu (black)
font použité písmo (Unknown Regular 16)
bar_style šablona jmen souborů pro dekoraci ukazatele průběhu
highlight_style šablona jmen souborů pro dekoraci uplynulé části ukazatele průběhu

Dále jsou k dispozici čtyři obecné bloky: label, image, vbox a hbox. Všechny tyto bloky podporují vlastnosti id, top a left s jejich obvyklým významem.

Bloky hbox a vbox již žádné další vlastnosti neobsahují. Tyto bloky jsou určeny jako kontejnery. Pokud do bloku vbox dáte několik jiných bloků, budou všechny zarovnané pod sebe a všechny budou mít stejnou šířku - šířku nejširšího vnořeného bloku. Obdobné platí pro hbox, kde se bloky řadí za sebe zleva doprava a všechny mají stejnou výšku. Blok image má dále vlastnosti widht, height a file udávající jeho šířku, výšku a soubor s obrázkem.

Blok label je určený k zobrazování textu. Kromě základních (id, left, top, width, height) vlastností s obvyklým významem dále podporuje vlastnosti:

text zobrazovaný text
align zarovnání textu - left, center, right
font písmo použité k zobrazení textu (Unknown Regular 16)

Experimentování

Toto byla nezbytná suchá teorie a nyní se lze pustit do praktického experimentování. Nastavíme v souboru /etc/default/grub použití našeho nového motivu:

GRUB_TERMINAL_OUTPUT=gfxterm
GRUB_GFXMODE=800x600
GRUB_FONT=/boot/themes/discworld/DejaVuSans.pf2
GRUB_THEME=/boot/themes/discworld/discworld.txt

V souboru musí být odkázáno alespoň jedno písmo, Grub ale automaticky načte všechna písma, které se nacházejí v adresáři, kde je uložen odkazovaný soubor s motivem.

Motiv jsme pojmenovali discworld. Umístíme jej do nového adresáře /boot/themes/discworld/. Vytvoříme si pro Grub dvě písma - jedno obyčejné, jedno tučné - a přegenerujeme je do formátu, který používá Grub:

grub2-mkfont --output=/boot/themes/discworld/DejaVuSans.pf2 /usr/share/fonts/dejavu/DejaVuSans.ttf
grub2-mkfont --output=/boot/themes/discworld/DejaVuSans-Bold.pf2 /usr/share/fonts/dejavu/DejaVuSans-Bold.ttf

Můžeme již začít s vytvářením motivu /boot/themes/discworld/discworld.txt:

#text titulku, pismo a barva
title-text: "Great A'Tuin"
title-font: "DejaVu Sans Bold 16"
title-color: "yellow"

#obrazek na pozadi
desktop-image: "/boot/themes/the_discworld.png"
# obrazek pochazi puvodne z http://www.elfwood.com/~jonas72/Great-ATuin.2866907.html
# a je licencovan pod CC Public Domain

#menu s polozkami
+ boot_menu {
  # vodorovne zarovnane na stred, sirka 80 %, 15 % od horniho okraje obrazovky, vyska 65 % obrazovky
  left = 10%
  top = 15%
  width = 80%
  height = 65%

  # pismo a barva polozek v menu
  item_font = "DejaVu Sans Bold 16"
  item_color = "lightgrey"

  # barva vybrane polozky
  selected_item_color = "yellow"

  # ramecek menu, soubor border_c.png nepouzijeme, nechceme zadne pozadi
  menu_pixmap_style = "border_*.png"

  # polozky budou 10 pixelu od ramecku menu
  item_padding = 10

  # polozky budou mit mezi sebou mezeru 10 pixelu
  item_spacing = 10

  # mezi ikonou a textem polozky bude mezera 10 pixelu
  item_icon_space = 10 

  # ikony budou zvetsene/zmensene na 44 x 44 pixelu
  icon_width = 44
  icon_height = 44

  # vyska polozky bude 45 pixelu
  item_height = 45
}

# informace o zbyvajicim case do automatickeho zvoleni predvybrane polozky
# zde to bude bez textu, pouzijeme jen grafickou verzi
+ progress_bar
{
   # id pole vcetne jeho hodnoty je povinne
   id = "__timeout__"

   # prvek umistime uplne na dolni okraj obrazovky, pres celou sirku
   left = 0
   width = 100%
   top = 98%
   height = 2%
   # barva popredi (uplynula cast) a pozadi
   fg_color = "#CCF"
   bg_color = "#66B"
}

# ukazka vbox-u, pokud chcete zobrazit v Grubu i "navod k obsluze", tak nasledujici cast odkomentujte
#+ vbox {
#    left = 10%
#    top = 80%
#    width = 80%
#    height = 13%
#    # vypsat text
#    + label {
#      text = "Use the Up and Down keys to select which entry is highlighted."
#      color = white
#      font = "DejaVu Sans Regular 12"
#    }
#    #mezery radkovani je dobrovolne
#    + label { text = "Press enter to boot the selected OS, 'e' to edit the " color = white font = "DejaVu Sans Regular 12" }
#    + label { text = "commands before booting, or 'c' for a command-line." color = white font = "DejaVu Sans Regular 12" }
#}

V motivu jsme použili i ikony, musíme je tedy dát Grubu k dispozici. V našem případě patří do adresáře /boot/themes/discworld/icons.

Teď již zbývá jen přegenerovat soubor /boot/grub2/grub.cfg pomocí příkazů uvedených výše. Výsledek bude vypadat takto:

Vše vypadá podle našich představ až do chvíle, než dojde na spuštění systému. Uprostřed obrazovky se objeví ošklivý čtverec s řádky informujícími o spouštění vybrané varianty. Kde se vzal? Jedná se o terminál Grubu. Zbavit se ho bohužel není možné. Není možné jej ani přesunout někam jinan ani změnit jeho velikost. Vždy je umístěn na střed obrazovky a jeho strany jsou vždy široké/vysoké 70 % šířky/výšky obrazovky.

Jediný postup, jak terminál znenápadnit, je použití pozadí. Generátor konfiguračního souboru s touto volbou nepočítá (motiv a ještě základní pozadí), takže nestačí přidat volbu GRUB_BACKGROUND, jako tomu bylo v předchozím případě. Musíme jej do souboru přidat ručně. Konfigurace v /boot/grub2/grub.cfg bude vypadat nějak takto:

...
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root d184f7c3-f1c8-414c-874e-bcb3e003d09b
insmod gfxmenu
loadfont ($root)/boot/themes/discworld/DejaVuSans-Bold.pf2
loadfont ($root)/boot/themes/discworld/DejaVuSans.pf2
insmod png
set theme=($root)/boot/themes/discworld/discworld.txt
set timeout=5
...

pak před řádek "set theme=...." vložíme příkaz pro použití obrázku jako pozadí:

background_image -m stretch ($root)/boot/themes/discworld/discworld_center.png 

Při použití samostatného oddílu pro /boot se část ($root)/boot z cesty k souboru nepoužije.

Aby toho nebylo málo, soubor s pozadím musí být speciálně upraven kvůli posunutí rohu obrázku a škálování dle rozměru obrazovky. Stručně, musíte vzít původní obrázek pozadí, zkopírovat středových 70 % a vložit je do levého horního rohu obrázku při zachování původních rozměrů obrázku. Vhodné je třeba i obrázek o něco ztmavit. Jednak aby bylo ve výsledku jasné, že se jedná o plochu terminálu, a také proto, že bez odlišení by to vypadalo, jako by se jen vymazala středová část menu, přestože okraje by tam zůstaly. Pokud chcete využít tento efekt vymazávání, lze to dobře použít, pokud menu nebude větší než těch 70 %, které překryjí terminál.

Stáhněte si kompletní motiv: discworld_theme.tar.gz.

To by bylo asi tak vše k běžné konfiguraci vzhledu Grubu. Pokud se chcete dozvědět více, můžete si o tom počíst třeba v The Definitive Guide To Theming GRUB2.