Kernel


"Kompajliranje Kernela"
Originalni autor: Amila Akagic, bono@linux.org.ba (Objavljeno u INFO Magazinu)

# v0.1      ~ 2002, bono, prva verzija
# v0.2     01.2004, M.Mehanovic, dopune, ispravke
# v0.3  29.09.2004, Vedran, jezičke sitnice
# v0.4  15.03.2005, M.Mehanovic, dopuna datoteka .config
# v0.5  19.06.2005, M-Mehanovic, dopuna Patch kernela
# v0.6  27.06.2005, Adis, totalna konverzija na 2.6 kernel, restuktuiranje teksta
# v0.9  27.11.2005, Adis, mislim da je dokument zreo za jedan snapshot (i verziju 1.0)
                    u budućim verzijama (1.2 i sl.) akcent će biti na samoj konfiguraciji
                    kernela (make menuconfig)
# v1.0  31.01.2005, Adis, RC1 (komentari?)


Ovaj dokument namijenjen je svima onima koji žele saznati kako kompajlirati, instalirati i konfigurisati kernel. Ukoliko imate pitanja vezana za ovaj dokument, pišite na info@linux.org.ba.


Sadržaj

[izmijeni] Zašto novi kernel ?

Najvažniji dio bilo kojeg operativnog sistema je kernel. Možemo reći da je to veza između hardverskog i softverskog svijeta. Kernel je, recimo, zadužen za podršku za TCP, IP, PPP i druge protokole. Kompajliranje kernela bi trebalo biti najlakši dio korištenja Linuxa, međutim iz iskustva mogu reći da je ovo jedna od najtežih tema za početnike. Tako pri pomenu kernela, mnogi će reći "aaa ne... ne želim upropastiti ovo što imam".

Današnje distribucije sadrže već gotove, sređene kernele tako da većinom nije potrebno kompajliranje novog kernela. Postavlja se pitanje: u kojim situacijama je potrebno kompajlirati kernel?

  • Ne možete pokrenuti ili koristiti određeni hardver; mrežne, zvučne, video kartice itd., a poznato vam je da su sa novim kernelom podržane.
  • Želite dodatnu funkcionalnost, koja ne postoji u vašem kernelu , npr. želite koristiti ReiserFS 4 ili Software Suspend V2
  • Želite brz i vitak kernel koji se brzo podiže. Kompajliranjem možete isključiti standardno podržane komponente koje u vašem sistemu nisu potrebne. Recimo ako koristite samo IDE uređaje, mogli biste isključiti podršku za SCSI hard diskove. Obično ćete jako teško primjetiti razliku između modularnog kernela ili kernela koji manje ili uopšte ne koristi module. Postoji jako velika mogućnost da zaboravite uključiti module koji su vam potrebni. U našem IDE/SCSI primjeru zaboravili smo vam spomenuti da Linux USB uređaje (memorijske stickove) tretira kao SCSI diskove, krajni rezultat jeste da vaš memorijski stick ne bi radio. Da ne duljim, ovo obično nije dobar razlog za kompajliranje novog kernela; a ako "znate šta radite", možda ste jednostavno prerasli ovaj dokument ;-)
  • U slučaju da jednostavno želite saznati kako je građen novi Linux kernel i kako se kompajlira.


[izmijeni] Prije nego što počnemo

[izmijeni] Šta je to kompajler

Kompajler je program ili skupina programa koja izvorni kod nekog programa pretvara (kompajlira) u izvršni (mašinski) kod, koji se zatim može pokrenuti na datom računarskom sistemu (arhitekturi). U našem slučaju, Linux kernel je taj (veliki) program, a izvorni kod velikom većinom pisan u programskom jeziku C, uz nešto asemblera.


[izmijeni] Šta je to kernel modul

Modularan kernel? To znači da je moguće dijelove kernela izdvojiti u posebne funkcionalne cjeline koje nazivamo "kernel moduli". Prilikom kompajliranja kernela možete odabrati koje module želite, a koje ne. Još jedna prednost jeste što se kernel moduli mogu kompajlirati odvojeno od ostatka kernela, tako da možete raditi upgrade dijelova kernela bez ponovnog kompajliranja čitave cjeline. Za razliku od nekih drugih operativnih sistema, moguće je učitati novi kernel modul ili zamijeniti stari bez potrebe za restartom računara. Kernel modul koji omogućava rad nekog hardverskog uređaja obično nazivamo drajver (eng. driver).


[izmijeni] Šta je to patch?

Patch (eng.) = Zakrpa.

Prije nego što objasnimo šta je to patch moramo prvo spomenuti diff. diff je komanda koja prikazuje razliku između dvije tekstualne datoteke, npr.

$ diff verzijal.txt verzija2.txt

(Na terminalu ćete vidjeti razlike između date dvije datoteke.) Značaj ove komande je u tome što ne morate zbog manjih izmjena izvornog koda isporučivati čitave datoteke (ili ručno računati "razlike"), već napravite diff svoje development verzije, npr. za gore navedeni primjer:

$ diff verzija1.txt verzija2.txt > verzija2.diff

Pretpostavimo da je datoteka 'verzija1.txt' velika 50KB, te da ste izmijenili 20-30 linija teksta. Umjesto da vaše kolege, koje imaju datoteku 'verzija1.txt' moraju ponovo skidati čitavu datoteku 'verzija2.txt' (koja je također velika 50KB), oni mogu skinuti datoteku 'verzija2.diff' i "primjeniti" (eng. apply) je sa komandom patch na 'verzija1.txt' te dobiti 'verzija2.txt'

$ patch < verzija2.diff

(Recimo da je 'verzija2.diff' velika 1KB)

U realnom životu ćete se susretati sa hiljadama izmenjenih datoteka, tako da se gornja "ušteda" od malih ~49KB može povećati 10 puta i više.

Još jedna važna osobina "diff" datoteka jeste da je jako lako uočiti sitne ispravke u odnosu na prethodnu verziju (malo zreliji projekti obično nemaju velikih izmjena). Na taj način, diff datoteke postaju svojevrsni dnevnik rada.


[izmijeni] Koju verziju kernela trenutno koristim?

Sa naredbom uname -a možete saznati koju verziju kernela trenutno koristite. Opcija -a prikazuje sve podatke, a -r samo verziju kernela.

# uname -r
2.6.5-7.151-default


[izmijeni] Mjere predostrožnosti

NAPOMENA: Neovisno od toga da li kompajlirate novi kernel ili ne, uvijek je preporučljivo da imate backup vaših podataka.

Potrudite se da napravite jednu boot disketu sa kojom je moguće podići vaš sistem (isprobajte je). Umjesto boot diskete možete koristiti i instalacijski CD vaše Linux distribucije u tzv. "Rescue modu".

Sada ćemo osigurati datoteku u kojoj se nalazi konfiguracija boot-managera LILO, a to je datoteka '/etc/lilo.conf'. Ako koristite GRUB napravite backup datoteke '/boot/grub/menu.lst':

 cp /etc/lilo.conf /etc/lilo.conf.backup
 cp /boot/grub/menu.lst /boot/grub/menu.lst.backup

Sada se možemo posvetiti kompajliranju kernela.

[izmijeni] Kompajliranje novog kernela

Kratak pregled koraka:

  1. Download izvornog koda
  2. Raspakivanje
  3. Konfiguracija
  4. Kompajliranje
  5. Instalacija
  6. Testiranje

NAPOMENA: Sve korake, ukoliko nije drugačije naglašeno, radite kao običan korisnik. (Običan korisnik ima u promptu '$', root '#').


[izmijeni] Download izvornog koda

Izvorni kod Linux kernela možete skinuti sa sa kernel.org, odnosno sa FTP servera ftp.kernel.org

Dobra ideja jeste provjeriti da li na CD-ovima/DVD-ovima vaše Linux distribucije dolazi izvorni kod neke starije verzije kernela, te da li ste instalirali paket sa izvornim kodom. To možete provjeriti naredbom (ovisno o ditribuciji):

# rpm -q kernel-source
kernel-source-2.6.11

ili

# dkpg -p linux
linux-2.6.11

ili eventualno pogledati u /usr/src/ folder:

$ ls /usr/src

ili da vidite lokaciju izvornog koda trenutno pokrenutog kernela

$ ls -la /lib/modules/`uname -r`/source

Budući da veliki broj Linux distribucija dolazi sa jako modificiranim kernelima (a time i sa jako modificiranim izvornim kodom), preporučujemo skidanje izvornog koda sa Interneta.

Izvorni kod se isporučuje u dva formata:

  • "Čitav kernel", npr. linux-2.6.12.2.tar.bz2 (veličine oko 30MB)
  • "Kernel patch", npr patch-2.6.12.bz2 (obično veličine oko 4-5 MB)

Ukoliko imate izvorni kod nekog starijeg kernela (npr. 2.6.11), skinuli biste patch-2.6.12.bz2 i time uštedjeli 25MB. Pretpostavićemo da već od prije imamo izvorni kod za 2.6.11 kernel, pa ćemo skinuti patch.


[izmijeni] Raspakivanje kernel arhive

Prvo trebamo odrediti lokaciju gdje ćemo raspakovati i smjestiti izvorni kod našeg kernela. Nešto stariji dokumenti (i stare verzije ovog HOWTO), zagovaraju smještanje izvornog koda u /usr/src, raspakivanje novog kernela (tako da dobijemo /usr/src/linux-2.6.11), te kreiranje simboličkog linka /usr/src/linux -> /usr/src/linux-2.6.11 Uz svaki 2.6 kernel, u README datoteci eksplicitno stoji da to NE TREBA raditi, tako da ćemo se držati zvanične preporuke koja ima smisla iz više razloga.

  • Update naše Linux distribucije može prepisati sadržaj /usr/src direktorija.
  • Neke kritične komponente sistema (GNU C Library) ovise o kernel header datotekama koje su došle uz našu distribuciju, a obično se nalaze na '/usr/src/linux/include'.

Kao root:

# mkdir /usr/local/src/kernel
# chown username /usr/local/src/kernel

Kao običan korisnik:

$ cp linux-2.6.11.tar.bz2 /usr/local/src/kernel
$ cp patch-2.6.12.bz2 /usr/local/src/kernel
$ cd /usr/local/src/kernel
$ tar -xjf linux-2.6.11.tar.bz2
$ mv linux-2.6.11 linux-2.6.12-extra
$ cd linux-2.6.12-extra
$ bzip2 -dc ../patch-2.6.12.bz2 | patch -p1

Zašto smo direktorij sa izvornim kodom nazvali 'linux-2.6.12-extra'? Ukoliko u omiljenom tekst editoru otvorite datoteku Makefile

$ vi Makefile

primjetićete liniju

EXTRAVERSION = -XXXX

Tj. imate mogućnost da pored verzije kernela, dodatno specificirate vaše "extra" ime, tako da čak možete instalirati/eksperimentisati sa više instaliranih verzija 2.6.12 kernela.

Mi ćemo staviti:

EXTRAVERSION = -extra


[izmijeni] Konfiguracija kernela

[izmijeni] Izbor radnog okruženja

Slika 1. XConfig alat za podešavanje kernela
Slika 1. XConfig alat za podešavanje kernela

Iako je kernel program koji se može kompajlirati uz pomoć poznatog kompajlera gcc, nisu potrebna nikakva programerska iskustva za njegovu gradnju. Sve što nam je potrebno možemo odraditi koristeći jedan grafički meni u kojem se odreduju potrebni i nepotrebni moduli. Postoje tri vrste tog menija:

  • Meni u tekstualnom modu koji obično nije naročito ugodan za upotrebu (osim kada koristite make oldconfig).
  • Meni sa tzv. curses interfejsom sa navigacijom uz pomoć tastature (strelice)
  • Pravo grafičko okruženje, komforno za korištenje i funkcioniše samo iz XWindows sistema.

Sve tri opcije omogućavaju korisniku da odgovori na pitanja vezana za konfiguraciju kernela i snimi rezultat u datoteku '/usr/local/src/kernel/linux-2.6.12-extra/.config'. Odgovoriti na pitanja za vrijeme konfiguracije kernela može biti prilično mukotrpan posao. Kod verzije 2.4.18 recimo, postoji 656 pitanja. Na svu sreću postoje već gotove '.config' datoteke koje mnoge distribucije prilože uz svoj kernel (obično u /boot direktoriju). Možemo slobodno kopirati ovu datoteku u novi direktorij i komandom make oldconfig preuzeti staru konfiguraciju tako da sada moramo još samo odgovoriti na nova pitanja koja dolaze uz novi kernel.

Početi ćemo od naredbe make menuconfig. U direktoriju /usr/local/src/kernel/linux-2.6.12-extra/ kucajte make menuconfig što će startati aplikaciju koja će vam olakšati izbor. Pored ove opcije tu je i make config koji je manje pregledan i ukoliko pogriješite u odabiru neke opcije moraćete ponoviti postupak ispočetka i ispraviti grešku.

Ako imate instaliran X Window sistem, preporučujemo korištenje naredbe make xconfig koja predstavlja standardan grafički interfejs. Dostupan je i alternativni konfiguracijski alat, koji možete koristiti sa naredbom make gconfig.

Šta sada uraditi? Jednostavno izaberite one opcije za koje mislite znate da su potrebne. Recimo, ukoliko nemate podršku za zvuk i ako je ona u kernelu isključena, a imate zvučnu karticu i želite imati zvuk, logično je da je uključite (enable).

Možete se kretati kroz opcije tipkama sa strelicama gore ili dolje, te tipkom ENTER ući u neko od područja (za "make menuconfig") ili jednostavno izabrati mišem (za "make xconfig"). Opcijom Exit se uvijek možete vratiti do glavnog menija. Ako želite da isključite neki modul onda izaberite "n", a da biste ga aktivirali izaberite "y". Osim toga, neke drivere možete označiti sa "m" što znači da će pomenuti driver biti napravljen kao "modul".

Tabela 1.
Stranice sa opcijama Kernela
PROCESSOR TYPE AND FEATURES
LOADABLE MODULE SUPPORT
GENERAL SETUP
NETWORKING OPTIONS
CHARACTER DEVICES
FILESYSTEMS
CONSOLE DRIVERS
SOUND
(Najbolje da drivere za vašu karticu označite kao module <M>)
Sve stranice

Naprimjer, ako koristite SCSI diskove onda obavezno ugradite podršku za SCSI direktno u kernel, jer u suprotnom ne možete pokrenuti sistem sa tog SCSI diska (pored SCSI podrške mora se uključiti i podrška za specifični SCSI kontroler; a sve komplikacije mogu se izbjeći korištenjem initrd). S druge strane, drivere za TV karticu možete označiti kao modul koji će biti učitan onog trenutka kada probate gledati TV.

[izmijeni] Neke važnije konfiguracijske opcije

Moduli se stalno mijenjaju. Svakodnevno dolaze izvještaji o novim modulima te se zanemaruju stari moduli. Zbog toga je teško nabrojati sve module i ostale mogućnosti koje se mogu izabrati u kernelu.

Pokušaćemo navesti neke od njih. Ukoliko naiđete na modul za koji niste sigurni da li vam je potreban, najbolje je da ga označite kao modul (m) ako je moguće, a ako nije da ga izaberete (y).

Dakle, sve što trebate uraditi je pogledati koje su vam opcije zaista potrebne a koje ne. Ukoliko niste sigurni šta je šta, koristite upitnik (?) pored opcije koja vas interesuje.

U Tabeli 1. imate pristup stranicama sa opcijama za kernel.


[izmijeni] Kompajliranje

[izmijeni] Kernel image

$ make bzImage

Pazite na (veliko) slovo I. Na novijim 2.6.## kernelima možete koristiti nešto jednostavnije:

$ make

ali to još uvijek ne preporučujemo (za razloge pogledajte poglavlje o [Instalaciji]).

Ovaj korak će potrajati određeno vrijeme. Na 2GHz mašini sa 512MB RAM-a traje oko 5 minuta, a na sporijim može trajati mnogo duže. Preporučljivo je pratiti sve poruke koje se pojavljuju jer možete uočiti neka upozorenja ili eventualne greške.

Na kraju ovog koraka dobili smo svježe iskompajliran kernel u 'arch/i386/boot/' poddirektoriju (datoteka bzImage).

[izmijeni] Kernel moduli

$ make modules


[izmijeni] Instalacija

[izmijeni] Instalacija modula

Sada ćemo instalirati module naredbom

# make modules_install

I ovo će da potraje malo. Ovim nastaje novi direktorij /lib/modules/2.6.12-extra u koji se kopiraju svi kernel moduli.

[izmijeni] Instalacija kernel image-a

Standardna lokacija za Linux kernel jeste direktoriju /boot pa ćemo i mi novi kernel premjestiti u taj direktorij. vmlinuz je tredicionalno ime za kernel image

# pwd
/usr/local/src/kernel/linux-2.6.12-extra
# cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.12-extra
# cp System.map /boot/System.map-2.6.12-extra

Još jedan način je da prepustite sve automatizovanoj skripti:

# make install

Koja će također izmjeniti vaš /boot/grub/menu.lst ili /etc/lilo.conf i sačuvati prethodnu verziju kernela kao izbor. Zvanična kernel dokumentacija ipak ne preporučuje ovakav način instalacije novog kernela. Linux distribucije se obično suptilno razlikuju u konvencijama i nazivima kernela i postavkama boot manager-a, a svaka greška ima za posljedicu sistem koji se ne može startati, tako da je najbolje da ovaj i zadnji konfiguracijski korak, instalaciju boot manager-a, odradite ručno.

[izmijeni] Boot Manager (LILO)

Editovanje /etc/lilo.conf

lilo.conf je datoteka u kojoj se nalaze opcije za LILO. LILO je skraćenica od LInux LOader, to je program koji vam omogućuje izbor operativnog sistema nakon paljenja/reseta računara.

Prije nego što počnemo praviti bilo kakve promjene u lilo.conf napravite prvo backup (cp /etc/lilo.conf /etc/lilo.conf.backup), što ste već i uradili ako ste pažljivo čitali ovaj tekst ;) Otvorite lilo.conf u vašem omiljenom editoru i počnimo. Evo kako izgleda jedna vrlo jednostavna lilo.conf datoteka:

image=/boot/vmlinuz-2.6.11
label=linux
root=/dev/hda2
read-only

Vaš lilo.conf je vjerovatno nešto složeniji, ali fokusirajte se na linije slične ovima, vjerovatno pri kraju. Instalacijski program vaše distribucije već je napravio najmanje jednu LILO konfiguraciju koja radi. Iskoristite je, prepišite i prilagodite vašem konkretnom slučaju.

Sada nakon ovog bloka napravite jednu kopiju istog i prepravite red sa label=linux u label=novikernel. Osim toga, prepravite red sa "image=/boot/vmlinuz-2.4.18" i stavite ime vašeg kernela koje ste odabrali maloprije, dakle /boot/vmlinuz-2.6.xx (xx zamijeniti za odgovarajuću verziju), tako da dobijete situaciju:

image=/boot/vmlinuz-2.6.11
label=Linux
root=/dev/hda2
read-only 
image=/boot/vmlinuz-2.6.12-extra
label=LinuxExtra
root=/dev/hda2
read-only 

Sačuvajmo ovaj novi lilo.conf. Kako bismo isprobali da li smo sve dobro sredili kucajte u konzoli:

# lilo

Naredba bi trebala dati izlaz npr. ovakav:

Added Linux *
Added LinuxExtra
Added dos

što bi zapravo trebalo da znači da je "LinuxExtra", naš novi kernel, dodan u LILO izbornik, pri čemu je stari kernel "Linux" i dalje podrazumijevana opcija (označen zvijezdom - *). Jedna uobičajena greška je da "image" nije na mjestu koje smo naznačili.

[izmijeni] Boot Manager (GRUB)

Grub ili bolje rečeno GNU Boot Loader se konfigurira preko filea /boot/grub/menu.lst. Evo primjer jednog unosa u menu.lst:

title Novell SuSE Linux (latest kernel)
  root (hd0,4)
  kernel /boot/vmlinuz-2.6.11 root=/dev/sda5 vga=0x31a selinux=0  splash=silent resume=/dev/sda7  showopts
  initrd /boot/initrd-2.6.11

Ovdje je instaliran kernel 2.6.11, ako ste pratili proceduru dosad, dodajte još jednu ovakvu stavku pri dnu filea menu.lst i promijenite sljedeće:

  • title, ovdje stavite nesto kreativno, poput MojOS ... :) (ovu liniju ćete vidjeti kada se starta GRUB kao mogući izbor)
  • kernel /boot/vmlinuz-#.#.## sa vašim kernelom, tj. sa nazivom vašeg kernel imagea (bez ekstenzije .img)
  • initrd /boot/initrd-#.#.##, ista procedura kao i sa kernel imageom, samo se pobrinite da su brojke iste

Ako vaš kernel radi i želite da se on starta svaki put zamijenite liniju:

default 0

sa default i brojem unosa vašeg kernela (GRUB broji od 0 pa nadalje, znači prvi unos je 0, drugi 1, etc). Pretpostavimo da vam je prvi unos kernel 2.6.11 a drugi novoinstalirani 2.6.12, onda bi bilo:

default 1

Backup važnih datoteka uvijek je dobra ideja:

# cp /boot/grub/menu.lst /boot/grub/menu.lst.backup

[izmijeni] Testiranje

Na kraju je potrebno još samo uraditi restart sistema. Kada se pojavi LILO ili GRUB kucajte ili izaberite "LinuxExtra" ili šta ste već stavili. Ukoliko želimo da se novi kernel automatski podiže moramo promijeniti redoslijed ova dva, gore navedena, bloka u lilo.conf ili obratiti pažnju na opciju "default=Linux" koju naravno treba promijeniti u "default=LinuxExtra".


[izmijeni] Zaključak

Novi kernel trebate kompajlirati u slučaju da vaš hardver nije prepoznat, ako imate problema sa drajverima ili trebate određenu dodatnu funkcionalnost. Vrlo vjerovatno ćete morati kompajlirati posebno "zakrpljene" verzije kernela (tj. originalni kernel sa kernel.org + određeni skupovi zakrpa). Upamtite da, kada je u pitanju kernel vašeg sistema, nije presudno da imate zadnju verziju nego da vam sistem radi brzo i stabilno.