Linus Torvalds napsal linux 0.01 v roce 1991 se slovy:
Hello everybody out there using minix - I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones.
Od té doby se linux změnil, stal se velkým a profesionálním pro nejen x86 mašiny, do dnešní podoby – linux řady 2.6, o které je tento referát.
Jedna z verzí vzniku jména linux (ISBN 0-7382-0333-5):
“Linux was my working name,” Linus says, “but if I actually used it as the official one, people would think that I was an egomaniac and wouldn't take it seriously. So I chose this very bad name: Freax” - free + freak + x. “Sick, I know.” Ari Lemmke, who ran the FTP site (myslí se funet.fi), decided he didn't like the Freax label, so he used the working name instead.
Trvalo dlouhou dobu, než vznikla 1. opravdu multiplatformní, funkční řada 2.x.
Nynější jádra jsou číslována trochu odlišně od starších, nedávno doznalo číslování malých změn. Ještě na začátku května popisoval číslování Linus takto:
- 2.6.<even>: even at all levels, aim for having had minimally intrusive patches leading up to it (timeframe: a week or two) - 2.6.<odd>: still a stable kernel, but accept bigger changes leading up to it (timeframe: a month or two). - 2.<odd>.x: aim for big changes that may destabilize the kernel for several releases (timeframe: a year or two) - <odd>.x.x: Linus went crazy, broke absolutely _everything_, and rewrote the kernel to be a microkernel using a special message-passing version of Visual Basic. (timeframe: "we expect that he will be released from the mental institution in a decade or two").
Dnes si ale můžete v archivu jader všimnout, že
existují i jádra 2.x.y.z, kde z je nějaké malé číslo. Takové verze jádra
obsahují malé změny, které bylo nutné opravit třeba kvůli funkčnosti. Souběžně
jsou vytvářeni kandidáti na další uvolnění celku – 2.x.(y+1)-rcz jádra.
Po dostatečném testování se uvolní jádro 2.x.(y+1) a dále zase jeho podverze a
-rc na další verzi.
Očekávaná verze 2.6.14, je „sudá” a Linus slibuje větší
stabilitu, měla by vyjít během 14 dní.
Nejnovější jádra lze získat z odkazů kernel.org. Od doby vzniku po současnost se vytvořilo mnoho obrazů primárního ftp serveru, odkud je možné jádro získat, mezi ně patří i naše fakulta, na adrese ftp.muni.cz, resp. ftp.linux.cz. Další možností je použít rsync a git/cogito (můžu doporučit, jsou to nástroje typu CVS, SVN).
Po stažení jádra jej můžeme dekomprimovat standardní cestou:
tar jxf linux-verze.tar.bz2
která nám vytvoří v pracovním adresáři adresář s rozbaleným, novým, jádrem.
Tím, že jsme stáhli a rozbalili jádro, máme vanilla verzi, kterou vydává Linus a má číslovaní popsané výše. S malým zpožděním se k vanilla jádrům (a jejich -rc) vydávají patche, které spravují různí lidé. Mezi nejpoužívanější mezi kernel hackery patří -mm jádro vydávané Andrew Mortonem (akpm@osdl.org). Další je -ac vydávané chlapíkem s červeným (RedHat) klouboukem, Alanem Coxem. Mezi ty méně známé patří -gh (nebo -gk?), které vydává Greg Kroah-Hartmann a další (-ck, -rt, …).
Důležité jsou také -git patche, což jsou snapshoty z git databáze, ve které se jádro vyvíjí.
Pokud chcete nebo potřebujete nějaký patch, stáhněte jej, rozbalte a změňte pracovní adresář do jádra, na jehož verzi se dá patch aplikovat. Poté stačí:
patch -p1 -i <cesta k patchi>
Patche na vanilla jádra se aplikují na poslední 2.x.y stabilní verzi před
patchem. Pokud si nejste jisti, na co se dá patch aplikovat, je nejlepší
spustit něco podobného jako
grep '+++ b/Makefile' -A10 patch
. Řádky začínající
- jsou stará verze, + potom nová (kterou známe z názvu patche).
Nezapomínejte, že patch(1)
má parametr --dry-run.
make help
vidět, je možné využít několik rozhraní pro
konfiguraci. To nejjednodušší je textové (make config
), kde
odpovídáte na otázky stiskem y,
n, m nebo ? pro nápovědu. Další, textové, tentokrát ale s výběrem v menu je
make menuconfig
make xconfig
nebo make gconfig
To je asi nejčastější otázka, kterou není lehké
zodpovědět. Nejlépe je najít konfigurační soubor odpovídající mé konfiguraci,
tedy aspoň přibližně, někde na Internetu (nejčastější zbůsob tvorby jádra pro
notebooky, kde jsou konfigurace u jednotlivých modelů podobné). Pokud je
hledání takové konfigurace neúspěšné, přijdou na řadu nástroje, z nichž lze
současně používané ovladače vyčíst. Jednak můžeme zjistit aktuálně načtené
moduly pomocí lsmod(8)
, jednak využijeme výstup
dmesg(8)
současného jádra, v neposlední řadě můžeme zjistit typ
HW pomocí lspci(8)
. V žádném případě není dobré brát konfiguraci
z distribučních jader. Systém vám sice bude fungovat, ale jádro bude obrovské
a všechny ovladače budou jako moduly, což ubírá na rychlosti.
Pokud již známe konfiguraci, stačí zaškrtat v konfigurační utilitě odpovídající ovladače. Není na škodu zakompilovat config.gz do jádra, což se stalo novinkou v jednom z posledních jader, to pro pozdější účely – kompilace novějšího jádra.
Tím jsem se dostal k další vymoženosti, kterou je
make oldconfig
který provedeme po upgradu jádra, popřípadě jeho napatchování. Konfigurátor
se zeptá pouze na rozdílné věci, ty stejné použije z předchozího konfiguračního
souboru .config
, který se hledá buď v adresáři se zdrojovými
kódy, nebo v adresáři nastaveným pomocí O=.
V neposlední řadě je třeba zmínit možnost O=<cesta>, čímž řekneme překladači, aby adresář se zdrojovými kódy zůstal nezměněn, naproti tomu, vše potřebné ke kompilaci a vytvoření výsledného obrazu se bude ukládat do <cesta>.
V adresáři je také možné provést
make clean
nebo make mrproper
což vyčistí náš strom od přeložených věcí, v
druhém případě i s konfiguračím souborem. Ve starších verzích jádra bylo nutné
spouštět clean prakticky před každou kompilací. V jádře 2.6 jsou závislosti
vyřešeny daleko lépe a nutné to (v 97,283 %) není. Minulostí je také
make dep
, který řešil závislosti ve starých jádrech.
Konfigurační řádka může tedy vypadat takto:
make menuconfig
mkdir ../xyz && make O=../xyz xconfig
Modul je soubor s příponou .ko, do jádra se vloží
příkazem insmod(8)
s cestou, popřípadě sofistikovanějším
modprobe(8)
, který nahraje i moduly, na kterých ten námi
požadovaný závisí. Moduly podporují i parametry, o této možnosti se
můžete více dočíst v manuálové stránce. Po odstranění závislostí (např.
zastavením síťového
rozhraní, odmountováním disku) lze zase modul odebrat příkazem
rmmod(8)
. Jako modul se doporučuje kompilovat věci jednak
nestabilní (při pádu je jádro stále schopné běhu), jednak ty málo používané,
např. wi-fi. modinfo(8)
potom vypisuje informace o modulu včetně možných parametrů.
Při samotné konfiguraci je dobré (ne vždy nutné k běhu; generic drivery sice
fungují, ale bez HW akcelerace) dát do jádra ovladače odpovídající přímo
HW.
scripts/extract-ikconfig
)rmmod
pro
modulyMožnosti, u kterých si nejste jisti ani po přečtení nápovědy, nechejte nastavené tak, jak radí v nápověde (např. If unsure, say N.).
Přeji příjemně strávené hodiny u konfigurace, neboť to je většinou věc, která trvá na svém prvním jádře nejdéle.
To první je věc jednoduchá na provedení, složitější na čas. Pro překlad v podstatě stačí příkaz
make <O=…> all modules_install
all
znamená přeložit vše, tedy vytvořit obraz i moduly (viz
make help|grep ^*
).
modules_install
zkopíruje moduly
do /lib/modules/x/ a vytvoří závislosti. x vyjadřuje verzi jádra, v novějších
jádrech může také obsahovat řetězec popisující aktuální snapshot z databáze.
Tím jsme odbyli i první fázi instalace – moduly. Nyní je třeba nastavit systém tak, aby akceptoval a spustil naše nové jádro. Důležité je nakopírovat jádro tam, kde ho bude moci přečíst námi používaný zavaděč. Na většině systémů by to měl být adresář /boot. Provedeme tedy něco jako
cp <`…' z O=…>/arch/<naše architektura>/boot/bzImage /boot/<cokoliv>
kde cokoliv je
většinou vmlinuz-<verze jádra>, avšak např. vyznavači powerpc mají raději
vmlinux-<verze>. Dále je nutné upravit konfiguraci
zavaděče a pokud budeme chtít použít initramdisk, tak vytvořit i jej pomocí
mkinitrd(8)
, pidinávod
zde.
Celý proces instalace za nás může udělat /sbin/kernelinstall, který spustíme
pomocí make <O=…> install
, pokud ho distribuce
obsahuje.
To je celý proces, po rebootu by mělo jádro fungovat (v některých případech nebude, čtěte časté chyby).
Některé nedostatky/přebytky lze doladit parametry jádra, jejichž neúplný výčet
je v Documentation/kernel-parameters.txt. Pro přesný výčet je nejlepší se vždy
podívat do zdrojových kódů (i v případě, že vám nějaký parametr nefunguje).
K těm základním patří root=, init=, ro, rw, které po řadě nastavují kořenový
svazek, program, který se má spustit jako init, mountování kořenového svazku
jen pro čtení a pro zápis v ranné fázi, distribuční skripty popř. později
provedou přemountování do rw.
Je soubor, který se kopíruje také do /boot a neobsahuje nic jiného, než
tabulku převádějící adresy na symboly.
Ve většině případů je System.map linkem na nějaký System.map-verze.
Na dobře nastaveném jádře by kompilace neměla přesáhnout půl hodiny (v
závislosti na procesoru, samozřejmě). Nezapomínejte na přepínač -j, který
umí make(1)
.
verze=2.6.13 # například wget ftp://ftp.muni.cz/pub/linux/kernel/v2.6/linux-$verze.tar.bz2 tar jxf linux-$verze.tar.bz2 mkdir build cd linux-$verze make O=../build menuconfig make O=../build -j3 all make O=../build modules_install cp ../build/arch/i386/boot/bzImage /boot/vmlinuz-verze vim /boot/grub/menu.lst # přidat záznam a nahradit LABEL= /DEV/... # mount --move ... [viz časté chyby], pokud je třeba reboot
Soubory s dokumentací jsou umístěny v adresáři Documentation
jádra. Nachází se zde i soubor 00-INDEX
, ve kterém je stručný
popis (téměř) všech souborů z tohoto adresáře.
Pro zasvěcenější stojí za zmínku ManagementStyle, CodingStyle (ten je pro
všechny, každý správný céčkař by se měl těmito radami řídit),
SubmittingDrivers a SubmittingPatches. Dále je možné generovat DocBook
nápovědu k API, která je stále ve vývoji, takže spousta věcí chybí, tak, že
zadáte make htmldocs
(xmldocs, psdocs, pdfdocs, mandocs). V
adresáři Documentation/DocBook by poté měly být vygenerované
soubory s příponou, kterou požadujete.
Jako každý rozsáhlý projekt, i Linux má své vši. Pokud se vám podaří na nějakou přijít, nebo lépe, vyřešit ji, podělte se s ostatními. Bugy můžete zadávat na bugzilla.kernel.org, což je všeobecně známý, ucelený systém na bugtracking. Popřípadě můžete poslat patch, který vyhovuje CodingStyle na linux-kernel@vger.kernel.org s CC lidem, kteří mají odpovídající úsek na starost (viz MAINTAINERS v adresáři jádra), popřípadě na akpm, pokud není možné nalézt odpovídající osobu (ovladač není pod správou).
Některé distribuce mají vanilla jádro upravené tak, aby fungovaly některé věci:
Vanilla jádro nepodporuje LABEL
pro nastavení kořenového
svazku. Je tedy nutné nastavit konkrétní /dev/[hs]d* svazek.
Jádro skončí s chybou nemožnosti namountovat svazek. (hned po zavaděči) Někdy je příčína v tom, že udev vytváří speciální soubory až je jádro načtené (protože je to user-level démon), ale jádro před tím potřebuje /dev/console a /dev/null. V tom případě je nutné tyto soubory vytvořit:
mkdir /tmp/dev mount --move /dev /tmp/dev # to funguje jen na jádře 2.6, se staršími si musíte poradit jinak cd /dev mknod initctl p mknod console c 5 1 mknod null 1 3 mknod zero 1 5 for cnt in 0 1 2 3 4 5 6 7 8; do mknod tty$cnt c 4 $cnt done
V /dev by se měly objevit speciální soubory, které jsme vytvořili a můžeme
přesunout udev dev zpět do /dev příkazem mount --move /tmp/dev
/dev
.
Jádro skončí s chybou nemožnost namountovat kořenový svazek. (těsně před načtením a spuštěním initu) Většinou jste zapomněli dát nějaký ovladač přímo do jádra. Pokud nepoužíváte initramdisk, musí být filesystém kořenového svazku a ovladač řadiče disku v jádře! Zkuste číst generovaný text při startu systému, jestli opravdu jádro našlo váš disk (Ctrl+S, Ctrl+Q funguje i zde).
Některé z těhto věcí jsem zachytil na diskuzích před delší dobou, zdroje už bohužel nevím (je možné, že zdrojem byly i stránky Fedory).
Zkompilovat na míru lze i jiná jádra. Např.
NetBSD,
FreeBSD (ssys.*).
NetBSD se konfiguruje editací textového souboru, pomocí utility
config(8)
se vytvoří adresář, ve kterém se překládá –
spustí se make dep
a make
. Hotové jádro se uloží do
souboru netbsd, který lze bootovat jako kernel ze zavaděče. [pro získání
představy, jak to chodí v jiných jádrech].
kernel.org – domovská stránka jádra
Linuxu
fakultní zrcadlo
mkinitrd
– jak na to
Linux Device Drivers – kromě
toho, jak psát ovladače jsou zde dobré připomínky a páky, které lze na jádro
použít
Podobných návodů je na Internetu jistě spousta, já jsem se pokusil zachytit mé
zkušenosti, které doufám pomohou. Přeji hodně štěstí při kompilaci jader.
Aktuální verzi bude možné najít
zde. Následující
sekce je (v tomto předmětu) spíše pro zajímavost.
Téměř v každém adresáři je soubor Makefile
, jako v každém
projektu. Před samotnou konfigurací jádra se zkompiluje vámi zadaný
konfigurátor nad TUI/GUI, který jste vybrali. Pod ním existuje řada funkcí,
které parsují .config
, Kconfig
, zapisují konfiguraci
jako definice do hlavičkových souborů a mnoho dalších. Nikomu nic nebrání v
tom napsat vlastní royhraní, které bude volat funkce a bude postavené nad jeho
oblíbeným prostředí (třeba konfigurovat jádro psaním kódu v base64).
Zmínil jsem soubor Kconfig
, není jeden, ale téměř v každém
adresáři jako Makefile
. V něm jsou texty, odpovídající každému
ovladači a také obsahují nastavení, jak se mají chovat funkce pod
konfigurátorem, jak mají řešit závislosti, co mají vybrat, když zvolíte nějaký
ovladač, co vám nedovolí vybrat, když nemáte v jádře něco jiného a pod.
Po uložení je vygenerován jednak soubor, podle kterého se orientuje
make
a překládá jen to, co jste zvolili a jednak hlavičkový
soubor, který obsahuje tytéž informace, podle kterých jsou nastaveny podmínky
ve zdrojových kódech (např. pokud máte procfs, vytvoří tam ovladač svůj
adresář).
Samozřejmě podle vybrané architektury se vytvoří adresář include2 a v něm jsou
odkazy na hlavičkové soubory závislé na architektuře, aby mohl developer
jednoduše udělat #include <asm/cokoliv.h>
.
To je v podstatě vše, v Makefiles jsou skupiny -m, -y a -n odpovídající
modulu, do jádra, nebo vůbec ne. Potom se čistým jazykem c, resp.
zašpiněným gcc (jiným překladačem jádro nepřeložíte) verze aspoň 2.9x,
překládá -m a -y; -m se potom linkuje do samostatného .ko, -y v každém adresáři
do built-in.o, všechny nejnadřazenější built-iny do monolitu spolu se zaváděcí
oblastí. Monolit se může zmenšit kompresí (z Image, nebo big z Image). K
dispozici vám také zůstane vmlinux
, což je nekomprimovaná verze,
kterou můžete spolu s /proc/kcore předhodit gdb
(a vytisknout si
třeba jiffies
– p jiffies
).