Jádro systému Linux - popis, konfigurace, kompilace

Dan Musil, fi.muni.cz, 27.9.2005, P090

Historie a vývoj jádra

Jádro Linuxu je komprimovaná binárka uložená na disku, která se po startu počítače nahraje do paměti, spustí a začne detekovat hardware a připravovat zázemí pro jeho použití, inicializovat souborový systém, připraví odkládací prostor (swap) a další součásti potřebné k běhu systému. Celý proces je závislý na ovladačích zakompilovaných v jádře. Čím více, tím lepší podpora hardware. Na druhou stranu věci navíc jádro zbytečně zatěžují a zdržují. Většina odborníků si proto kompiluje jádro podle svých potřeb.

Jádro Linuxu začal vyvíjet jako svůj domácí operační systém Linus Torvalds v roce 1992 (vyšel z Minixu). V dnešní době se spolu s ním o údržbu a začleňování stovek kódu vývojářů starají i další lidé (nejznámější je Alan Cox). Linux se tak nejen díky své architektuře, ale i dostupnosti (licence GNU/GPL) postupně stal široce používaným operačním systémem na mnoha platformách. Jmenujme například x86 (Intel, AMD), ARM (Compaq), Alpha (DEC), Sparc (SUN), M68000 (Motorola), MIPS, PowerPC (Macintosh), zkrátka cokoli, co má kompilátor.

Linux zahrnuje oba standardy BSD i Systém V, i když samotné jádro bylo implementováno zcela nezávisle. Vedoucí správci jádra se starají o důslední dodržování standardů POSIX, které definují jaké služby by měl OS poskytovat.

Informace o jádře a jádro samotné naleznete na webu kernel.org, stovkách zrdcadlech (FTP i HTTP) i na P2P sítích jako je třeba BitTorrent. V sekci people najdete nejnovější ovladače. Na webu lunixhq.com oficiální i neoficiální patche.

Popis jádra

Jádro poskytuje vrstvu mezi hardware a aplikacemi. Poskytuje aplikacím jednotné API pro používání zařízení připojených k počítači (procesor, I/O, paměť, síť a další prostředky). Velikost jádra je tak závislá na množství hardwaru, se kterým umí pracovat (je v jádře zakompilován), ale také na počtu služeb a funkcí, které poskytuje.

Díky velkém množství vznikajícího různorodého hardware a díky snaze umožnit použití jádra i počítačovým laikům vznikla možnost nepřidávat každý ovladač přímo do jádra, ale zkompilovat ho jako knihovnu, modul, která se použije až v případě reálné potřeby (více níže podkapitola Moduly). Odborníci často kompilují monolitické jádro, které nemá podporu modulů a obsahuje v sobě jen to, co skutečně potřebují k danému účelu. V masově používaných distribucích je naopak trendem poskytnout obecně používané a odladěné jádro spolu s obrovským množství modulů pro různý hardware uživatelů.

Monolitické jádro je bezesporu rychlejší a bezpečnější, na druhou stranu se v něm špatně ladí, není příliš flexibilní a obecně použitelné.

Moduly

Od verze 1.2 jádra v roce 1995 byla z výše uvedených důvodů do jádra přidána podpora pro dynamické natahování modulů dle potřeby. Často se setkáte se zkratkou LKM, která znamená Loadable Kernel Module. Modul do jádra přidává podporu pro dané hw zařízení, periférii nebo API rozhraní. Uživatel tak může své jádro naučit používat svůj USB disk, půjčenou síťovou kartu nebo připojený vzdálený souborový systém.

Každý jaderný modul nese seznam poskytovaných a požadovaných symbolů, verzi jádra, autora, název licence a seznam parametrů.

Moduly by měly být zaváděny do paměti zcela automaticky při použití podporovaného zařízení. Ne vždy se tak stane, proto existuje soubor

      /etc/modules.conf
    

který obsahuje seznam modulů načítaných již při startu systému. Dále pak spustitelné nástroje

      insmod
    

respektive

      modprobe
    

pro zavádění modulů,

      rmmod
    

pro jejich odstraňování a

      lsmod
    

pro výpis používaných modulů a jejich závislostí.

Závislosti mezi moduly řeší využívání generických modulů jinými moduly na vyšší úrovni. Princip funguje obdobně jako knihovny v programování, kdy jedna využívá druhé na nižší úrovni, která je obvykle základem pro více další knihoven.

Některé proprietární moduly jsou výrobcem hardware z licenčních důvodů dodávány pouze v binární formě. Takové jsou závislé na konkrétní verzi jádra (nemůžeme je překompilovat), dále se s nimi pracuje stejně jako s ostatními. Typickým příkladem jsou oba majoritní dodavatelé grafických karet na desktopech PC.

Stažení a číslování

Jádro najdete na HTTP + FTP serveru kernel.org, stejně jako na spoustě zrcadel, která pomáhají rozkládat zátěž při zveřejnění nového jádra. Pro nás nejbližšími zrcadly jsou například ČVUT a linux.cz.

Poslední stabilní verze jsou 2.6.13 a 2.4.31. V současnosti jsou vyvíjeny obě větve paralelně, především kvůli aktualizacím běžících zařízení a konzervativním uživatelům, kteří větev 2.6 stále považují za neodladěnou. 2.6 přináší řadu vylepšení (viz. Báječný svět Linuxu 2.6).

Možná si nejste jisti, co znamenají ta tři čísla ve verzi jádra. První z nich je major verze jádra, která už se dlouhou dobu drží na dvojce. Změní se až nastane nějaký opravdu revoluční krok v kódu. U druhého čísla je důležité rozdělit cifry na liché a sudé. Lichá čísla jsou považovány za vývojové verze a málokdo si takové instaluje. Je to mezikrok mezi těmi sudými, považovanými za stabilní. Druhé číslo se změní, pokud v kódu jádra nastane výrazný pokrok. Třetí číslo označuje release jádra a čísluje se inkrementálně. Obvykle obsahuje různé opravy, drobná vylepšení a bezpečnostní záplaty. Za verzí jádra může následovat nějaký dodatek ve formátu -pre, -rc, -test, který blíže specifikuje jádro a označuje jej za téměř dokončené.

Do jádra existuje nepřeberné množství patchů, ať už bezpečnostních (LIDS, GrSecurity) nebo třeba pro podporu dalšího hw, API. Patch stáhneme, aplikujeme příkazem

      patch -p1 < soubor.patch
    

(vždy dle dokumentace k patchi). Kompilace pak probíhá standardním způsobem a patch většinou přidá některé konfigurační volby do konfigurace jádra.

Změny v jádře lze sledovat buď na oficiálních serverech nebo v souboru Documentation/CHANGES přibaleném k jádru, pěkné shrnutí zveřejňují na abclinuxu.cz, inspirativní jsou blogy, příspěvky v diskuzních skupinách a mnoho informací lze nalézt i na kanálech IRC.

Struktura souborů rozbaleného jádra (cca 200MB, pro kompilaci nutných dalších cca 300MB) vypadá přibližně takto:

Konfigurace a kompilace

Proč kompilovat?

Proč nekompilovat?

Jádro rozbalujeme do adresáře /usr/src. Symbolický link /usr/src/linux pak odkazuje na aktuálně zpracovávané jádro.

Ke kompilaci potřebujeme několik věcí: gcc, make, glibc, binutils, util-linux, module-init-tools. Také záleží na jejich verzi (viz. Documentation/README).

Cestu k vlastnímu modulu nám zpřístupní jediný Makefile v hlavním adresáři jádra. Pomocí různých parametrů jemu předávaných ovlivňujeme činnost, kterou provádí a pomocí několika málo kroků tak získáme vlastní jádro.

1. krokem bývá vyčištění předchozích pokusů o konfiguraci nebo kompilaci (byla-li prováděna). K tomu slouží příkazy

      make clean
    

pro odstranění binárních výstupů (kompilace). Důkladnější verzí je

      make mrproper
    

který uveden zdrojáky jádra do stavu po rozbalení.

2. krokem je spuštění konfigurace, ve které si zvolíme, co všechno bude jádro obsahovat, co z toho bude zkompilováno jako modul a co vůbec nepotřebujeme. Vývojem vzniklo několik možností, jak si výsledný .config obsahující naše nastavení vytvořit:

Nesmíme vynechat nic důležitého, jinak jádro nepojede. K tomu nám pomáhají zavaděče jako je LILO nebo GRUB, které nám umožňují zachovat možnost zavedení starého, funkčního, jádra. Druhou možností je pak v případě nouze použít nějaký rescue systém (floppy, CD, ...).

Důležitými volbami jsou například Loadable module support --> Enable loadable module support (podpora dynamických modulů nebo ne?), File systems (dostupné souborové systémy, včetně virtuálních a síťových), Procesor type and features (optimalizace pro daný procesor), High memory support (podpora velké paměti, nad 960MB). Důslednou pozornost je také nutné věnovat podpoře hardware a u serverů podpoře více jader (SMP).

Může se stát, že budeme chtít jako modul i věc, která je nutná pro zavedení systému. Typicky nějaký souborový systém, který musí jádro znát, aby mohlo moduly načítat. Takové moduly se umisťují na virtuální ramdisk, který má jádro k dispozici během startu. Viz. příkaz

      mkinitrd -h
    

3. krokem je vytvoření závislostí dle naší konfigurace. Příkaz

      make dep
    

4. krok následuje kompilace. Tedy

      make bzImage
    

nebo méně používané

      bzDisk
    

pro vytvoření obrazu jádra, tj. binárního komprimovaného souboru.

      make modules
    

nám k němu dokompiluje jaderné moduly. A nakonec

      make modules_install
    

nám tyto moduly připraví do adresáře

      /lib/modules/$verze ($verze je verze jádra)
    

kde je hledá jádro při připojování modulů.

5. krokem je ruční přesunutí obrazu jádra do bootovací oblasti /boot a nastavení zavaděče LILO či GRUB (/etc/lilo.conf, /boot/grub/grub.conf). Jádro naleznete v adresáři

      /usr/src/linux/arch/i386/boot/
    

jmenuje se bzImage a stačí jej zkopírovat do /boot.

Poznámka: u jader 2.6 stačí

      make
      make modules_install
    

Lze tedy vynechat krok 3. a 4. a nahradit je pouhým příkazem

      make
    

(viz. Gentoo Handbook).

System.map

Soubor je nejčastěji umístěný v /boot ve formátu /boot/System.map-$verze ($verze je verze jádra), přičemž /boot/System.map je symlink na aktuální jádro. Obsahuje seznam funkcí dostupných v jádře, tedy jakousi převodní tabulku mezi názvy a adresami těchto funkcí. Po nabootování by měl být dostupný k /proc/ksyms (v mé distribuci chybí).

Vypadá asi následovně:

      ...
      c0493d20 t alsa_sound_exit
      c0493ec0 T snd_minor_info_oss_done
      c0493e00 T snd_info_done
      c0493e70 t snd_info_version_done
      c0493fc0 t alsa_pcm_exit
      ...
    

Používají ho aplikace jako ps, uptime, top a klogd k reportování svých záležitostí. V textu se už neobjevují adresy, ale jsou nahrazovány textovou reprezentací inkriminované části jádra.

Vybrané parametry jádra

Při zavádění jádra mu lze předat parametry. Ty se zadávají ve formátu "parametr=hodnota parametr ...". a výrazně ovlivňují chování jádra. Lze je použít pro zjišťování problému, ladění nebo třeba pro podporu právě připojeného zařízení. Seznam parametrů ke svému jádru najdete v souboru Documentation/kernel-parameters.txt.

Vybral jsem několik důležitých a zajímavých parametrů:

Dalšími jsou mem, nfsroot, debug, panic, vga, video, ideo0, quiet, ...

Vybrané volby konfigurace jádra

U většiny voleb lze vyžádat nápovědu, která vysvětlí dopad volby a doporučí vhodné nastavení. Bohužel u těch voleb, které jsou pro odborníky opravdu problémové, a help by se hodil jako sůl, není vůbec vyplněn.

BSD systémy

Na BSD systémech se konfigurace a kompilace liší. Bohužel jádro BSD jsem osobně nikdy nekompiloval, vždy jsem přišel k hotovému. Pro začátek svého zkoumání můžete využít třeba jeden z referátů z minulých let.

Shrnutí a odkazy

archív jader
oficiální i neoficiální patche
Linux kernel HOWTO
seriál Triky pro Začátečníky Leoše Literáka
Překládáme jádro Zdeňka Pytely
seriál Báječný svět Linuxu 2.6
Kompilace jádra
Kompilační parametry jádra Linux
Compiling the Linux Kernel
Archív referátů
google