Správa linuxového serveru: Kompilace jádra a modulů prakticky

Minule byla probrána kompilace jádra a modulů teoreticky, dnes se na ni budete moci podívat z praktického pohledu a zjistit, jak při kompilaci jádra nebo modulů postupovat.

Na úvod opět připomenu, že byste si měli projít přinejmenším minulý díl. Dozvíte se v něm mnoho podstatného a užitečného pro díl dnešní.

Kompilace modulů

Jaderný modul představuje obvykle určitou funkcionalitu. Ve většině případů se jedná o ovladač zařízení, ale stejně tak se může jednat o modul zpřístupňující určitý souborový systém, upravující či přidávající bezpečnostní model jádra, nějakou vlastnost atd. Pokud se dostanete do situace, kdy se vám nějaký modul zalíbí, ale ve vašem distribučním jádře nebude, naštěstí nebudete muset projít kompilací jádra – postačí zkompilovat jen samotný modul a ušetřit si tak práci. Předesílám však, že bude nutné tento proces opakovat při každé změně jádra (např. po aktualizaci na novou či opravenou verzi).

Abyste mohli zkompilovat jaderný modul, potřebujete hlavičkové soubory jádra. Pokud je nemáte, musíte je nainstalovat. V Debianu se příslušný balíček jmenuje linux-headers, ale musíte vybrat ten, který patří vašemu jádru. Můžete také použít metabalík, který zajistí automatickou instalaci hlavičkových souborů, ale i těchto metabalíků je více v závislosti na architektuře, kterou využíváte. Pro 32bitové systémy bude přicházet v úvahu:

aptitude install linux-headers-2.6-686

Pro 64bitové pak:

aptitude install linux-headers-2.6-amd64

Potřebujete také nástroje pro kompilaci, popřípadě další nástroje a komponenty, které daný modul vyžaduje (dokumentace napoví). Nástroje pro kompilaci v Debianu nainstalujete prostřednictvím metabalíku build-essentail:

aptitude install build-essential

Samotný proces kompilace modulu představuje rozbalení zdrojového balíčku a jeho kompilaci:

tar xvf jaderny_modul.tar.gz
cd jaderny_modul
make

V některých případech je třeba specifikovat verzi jádra, ke které chcete modul sestavit, jinde se automaticky použije aktuálně běžící jádro. Specifikace jiného jádra má pak obvykle podobu nastavení příslušné proměnné, kterou stačí nastavit pro nástroj make, např. takto:

KVER=2.6.32-5-amd64 make

Posledním krokem je instalace modulu a aktualizace závislostí mezi moduly:

make install
depmod -a

Modul se obvykle usadí v /lib/modules/verze_jádra. Zavést jej můžete pomocí modprobe:

modprobe modul

Odstranit jej z běžícího jádra můžete příkazem:

modprobe -r modul

Chcete-li, aby se modul zaváděl při každém spuštění počítače, přidejte jeho název na prázdný řádek do souboru /etc/modules (platí pro Debian).

Proces kompilace modulu se může lišit a mít svá specifika u každého jednotlivého modulu, tudíž určitě nejprve nahlédněte do dokumentace. Samozřejmě až potom, co se podíváte do repozitářů, jestli tam už váš modul není k dispozici. V Debianu naleznete dva typy balíků příslušejících jaderným modulům, a sice balíček se zdrojovým kódem, který můžete využít ke kompilaci (takový má přídomek -source), nebo -dkms balíček, který se o kompilaci pro aktuální jádro postará sám, a postará se i v případě aktualizace jádra (předpokladem je dostupnost hlavičkových souborů nového jádra).

Debian také obsahuje nástroj Module assistant (balíček module-assistant), který usnadňuje kompilaci a instalaci řady modulů.

Kompilace jádra

Jestli nemáte všechny nástroje potřebné pro sestavení jádra, tak si je nainstalujte:

aptitude install kernel-package libncurses5-dev fakeroot wget bzip2

Jako první je třeba, abyste si opatřili zdrojové kódy jádra. To můžete učinit buď prostřednictvím balíčkovacího systému (balíček linux-source), nebo si je stáhnout přímo ze zdroje na kernel.org. Bohužel, tento server se v době psaní článku stále zotavuje z bezpečnostního incidentu, tudíž pokud vám tato stránka momentálně nefunguje, budete si muset zdrojové kódy jádra opatřit jinde, třeba na GitHubu.

Zdrojové kódy rozbalte:

tar xvf linux-2.6.32.tar.gz

Následně (pro jistotu) zdroj vyčistěte:

cd linux-2.6.32
make mrproper

Aplikace patchů

Chcete-li aplikovat nějaký patch (pro příslušnou teorii vás odkazuji na minulý díl), nyní je vhodná doba. Patch můžete po rozbalení aplikovat nejlépe podle instrukcí na webu příslušného projektu, nebo pomocí nástroje patch, nějak takto:

patch -p1 < muj_patch.patch

Při zadávání tohoto příkazu byste se měli nacházet v adresáři s rozbaleným zdrojovým kódem jádra.

Konfigurace jádra

Dalším krokem je konfigurace jádra. Ta zahrnuje jak nastavení řady parametrů, tak určení toho, co se zakompiluje přímo do jádra a co zůstane jako modul, který lze do jádra za běhu nahrát nebo vyjmout. Tento proces je velmi komplikovaný a není vůbec těžké zapomenout na nějaký modul, bez kterého se jádro na příslušném hardwaru nerozběhne. Pokud začnete s konfigurací jádra od začátku, prozkoumejte důkladně veškerý hardware (lshw) a nahrané moduly (lsmodmodinfo), a volte příslušné moduly v nastavení jádra podle toho. Modul zakompilovaný do jádra bude fungovat, jakmile jádro naběhne. To, co bude k dispozici jako externí modul, musí přijít do iniciálního ramdisku, je-li to důležité pro zavedení systému.

Pomocnou ruku vám v této situaci poskytne aktuální konfigurace jádra, kterou můžete použít jako vzor. Konfigurace aktuálního jádra bývá k dispozici v /proc/config.gz (je-li tato funkčnost zakompilována do jádra). Toho pak můžete využít:

cd linux-2.6.32
cp /proc/config.gz .config.gz
gzip -d .config.gz
make oldconfig

V Debianu zrovna prohlížení nastavení jádra prostřednictvím /proc/config.gz dostupné není, je tedy třeba zvolit alternativní postup:

cd linux-2.6.32
cp /boot/config-`uname -r` ./.config
make oldconfig

Poslední příkaz přizpůsobí konfigurační soubor aktuálnímu jádru, což bude nejspíše zahrnovat mnoho dotazů, na které budete muset odpovědět. Poté bude konfigurace hotova a vy ji následně můžete upravit:

make menuconfig

Výše zmíněným příkazem spustíte textový konfigurační nástroj jádra. Těchto nástrojů je více, nemusíte tedy nutně používat menuconfig, můžete použít xconfig nebo jiné varianty (dostupné možnosti zjistíte pomocí make help). Pomocí těchto nástrojů vytvořte nebo upravte nastavení jádra. Až budete hotovi, uložte nastavení a opusťte nástroj.

Pojmenování vámi upravené verze jádra

Abyste odlišili svou verzi jádra od jádra, které máte nainstalované, v nastavení jádra General setup - local version vyplňte příponu, kterou chcete použít, např. -custom. Pokud tak neučiníte a jádro budete instalovat ručně bez správce balíčků, hrozí, že si přepíšete distribuční jádro!

Sestavení jádra

Nechcete-li využívat správce balíčků, zkompilujte jádro následujícím příkazem:

make all

Následně nainstalujte zkompilované externí moduly do /lib/modules:

make modules_install

Poté zkopírujte obraz jádra do /boot:

cp arch/x86/boot/bzImage /boot/vmlinuz-verze_jadra

Zde musíte řetězec verze_jadra nahradit za celý název verze jádra (můžete se orientovat dle názvu adresáře v /lib/modules, který odpovídá vámi zkompilovanému jádru).

Následně vygenerujte iniciální ramdisk:

mkinitramfs -o /boot/initrd.img-verze_jadra verze_jadra

Zde nahraďte řetězec verze_jadra za stejný řetězec, který jste použili v příkazu pro zkopírování obrazu jádra do /boot.

Posledním krokem je úprava zavaděče:

update-grub

Budete-li chtít zužitkovat zbylé zdrojové kódy (např. pro pozdější kompilaci modulů), pusťte v adresáři s nimi toto:

make clean

Pokud jste kompilovali jádro někde bokem a ne v adresáři, kde byste chtěli zdrojáky ponechat, pak po jejich přemístění nezapomeňte upravit symbolický odkaz /lib/modules/verze_jadra/build tak, aby ukazoval na jejich nové umístění.

Sestavení jádra v Debianu

Debian má vlastní nástroje, které vám pomohou sestavit jádro a začlenit jej do balíčkovacího systému. Místo výše uvedeného postupu tedy můžete použít následující. Po konfiguraci jádra proveďte:

make-kpkg clean
fakeroot make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers

V příkazu výše upravte parametr --append-to-version podle toho, jakou příponu pro název vámi sestaveného jádra chcete použít. Až kompilace skončí, podívejte se do /usr/src, kde se měly vygenerovat příslušné balíčky. Ty pak nainstalujte pomocí dpkg:

cd /usr/src
dpkg -i linux-image-verze_jadra.deb
dpkg -i linux-headers-verze_jadra.deb

Iniciální ramdisk by se měl vygenerovat automaticky, totéž by mělo platit o nastavení zavaděče. Tím by měla být instalace nového jádra hotova.