Linux Kernel

From EIK wiki

Autor: Jan Eerik DK31

Sissejuhatus

Linux kernel on Unix-tüüpi monoliitne operatsioonisüsteemi tuum, mis on välja arendatud Linus Torvalds'i poolt 1991. aastal. Nimi "Linux" tuleneb tema autori eesnimest ja tolleaegsest populaarsest operatsioonisüsteemist UNIX, millel Linux'i tuum põhineb. Linux'i tuum on vabavara ning põhineb GPL (GNU Public Licence) litsensil.

Tuum on operatsioonisüsteemi põhiline osa, mis organiseerib tööd kasutaja ning arvutisüsteemi riistvara vahel.

Linux'i tuum sisaldab kõiki põhilisi omadusi, mis on iseloomulikud kaasaegsele operatsioonisüsteemile, muuhulgas multitegumtöötlust, virtuaalmälu, jagatud teeke, mäluhaldust, mitmekihilist võrgusüsteemi (IPv4, IPv6).

Kuigi Linux'i tuum oli algselt välja arendatud 32-bitilise x86 tüüpi arhitektuuri jaoks, töötab Linux tänapäeval kõigi moodsate 32 ja 64-bitiliste masinate peal. Eriti levinud on Linux'i kasutamine serverites ning samuti domineerib mobiilsete seadmete turgu Android'i operatsioonisüsteem, mis põhineb omakorda Linux'il.

Erinevat tüüpi tuumad

Enne kui asume Linux'i tuuma arhitektuuri lähemalt vaatlema, heidame pilgu, millised tuumade tüübid on muudes süsteemides kasutusel.

Monoliitne tuum (monolithic kernel) - on olnud traditsiooniliselt kasutusel Unix-tüüpi operatsioonisüsteemides ja sisaldavad kõiki süsteemi põhifunktsionaalsuseid ja riistvara draivereid. Moodsad monoliitsed tuumad, mida võib leida Linuxi ja FreeBSD süsteemides pakuvad võimalust mooduleid dünaamiliselt laadida, mis annab võimaluse tuuma funktsionaalsust väga lihtsalt laiendada (ei pea funktsionaalsust tuuma koodis kirjeldama, vaid saab arendada mooduli ja selle tuuma külge laadida).

Mikrotuum (microkernel) - pakub üldjuhul vaid minimaalseid teenuseid, nagu mäluaadressid ja protsessijuhtimine. Ülejäänud funktsionaalsus, näiteks riistvara haldus, on rakendatud tuumast eraldisesivates protsessides. Sellist tuuma kasutavad näiteks AIX, Mac OS X ja MINIX süsteemid.

Hübriidtuum (hybrid kernel) - on sarnased mikrotuumale, kuid sisaldab lisakoodi kiiremaks tööks (selle asemel, et see kood kasutaja keskkonda kirjutada). Sellist tuuma tüüpi kasutab näiteks Microsoft Windows NT, 2000 ja XP ning DragonFly BSD.

Eksotuum (exokernel) - on siiani eksperimentaalne arendus, mis on oma olemusel väga minimaalse suurusega ning lahutab riistvara halduse riistvara kaitsest. Kuna erinevate teekidega tulevad kaasa erinevad API-d, saab seda tüüpi tuuma kasutada erinevate programmide käitamiseks korraga nii Linux'i kui Windows'i süsteemi peal.


Arhitektuur

Algselt oli Linux'i tuum täielikult monoliitne, mis tähendab, et kõik tuuma komponendid olid staatiliselt üksteise külge "seotud" ning laaditi alglaadimise käigus. Tänapäevased modernsemad Linux'i tuuma versioonid on aga pigem modulaarsed ning võimaldavad erinevaid komponente dünaamiliselt süsteemi töö käigus lisada ja eemaldada. Terve operatsioonisüsteem töötab eraldatult "tuuma keskkonnas" ehk kogu tegevus tuumas on rangelt reserveeritud tema operatsioonide jaoks ning kasutaja keskkond sellele ligi pääse. Selle tulemusena on süsteem turvalisem, kuna pakub kaitset nii mäluruumile kui riistvarale potentsiaalse sissetungi eest. Samuti töötavad tuuma keskkonnas riistvara draiverid. Lisaks tuumale endale asub tuuma keskkonnas ka GNU C teek, mis võimaldab süsteemi kutseid ja üleminekut kasutaja keskkonnast tuuma keskkonda. Kasutaja keskkonnas töötavad seevastu erinevad kasutaja rakendused, näiteks graafiline kasutajaliides ja muud kasutaja rakendused.

Fig1.jpg

Skeem 1: GNU/Linux operatsioonisüsteemi arhitektuur

Peamised Linux'i alamsüsteemid

Linuxi tuum on väga kompleksne ja mitmekihiline süsteem, mis omakorda koosneb mitmetest alamsüsteemidest.

Fig2.jpg

Skeem 2: Arhitektuuriline vaade Linux'i alamsüsteemidele

Süsteemi kutsungiliides (System Call Interface):

Süsteemi kutsungiliides on õhuke kiht tuumas, mis vahendab funktsiooni väljakutseid kasutaja keskkonnast tuuma keskkonda. Kuna Linux'i tuum on eraldatud erinevateks õiguskihtideks (Privilege Levels), liiguvad kõik kasutaja antud käsud tuuma üle API, mis edastab vastavad käsud edasi tuumale.

Protsessihaldus (Process Management):

Protsessihalduse ülesandeks on protsesside täideviimine. Protsesse tuumas nimetatakse lõimedeks (threads) ning esindavad iseseisvat protsessori virtuaalset osa (lõimekood, andmed, registrid jne). Kuigi kasutaja keskkonnas kasutatakse pigem terminit protsess (või toiming), siis Linuxi puhul neid kontseptsioone spetsiaalselt ei eristata. Protsessihaldus peab lisaks tegelema ka protsessori ressursside eraldamisega aktiivsete lõimede vahel. Tuum kasutab selleks spetsiaalset planeerimisalgoritmi, mis töötab konstantses ajas ja ei ole sõltuv aktiivsete lõimede arvust, mis protsessori ressursse parajasti nõuavad. Tänapäeval toetavad need algoritmid ka mitut protsessorit (Symmetric Multiprocessing).

Mäluhaldus (Memory Management):

Lisaks protsessihaldusele peab tuum tegelema ka mäluhaldusega. Enamikes arhitektuuritüüpides hallatakse mälu 4KB suuruste puhvritena (pages). Linux'i tuum võimaldab lisaks tekitada abstraktsioone jagades mälu ka puhvrisiseselt, jälgides millised puhvrid on täis, pooltäis või tühjad. See võimaldab mäluhaldusskeemil dünaamiliselt vastavalt vajadusele mälu ümber jagada. Kuna mälu on jagatud mitmete erinevate protsesside vahel, võib juhtuda, et vaba mälu saab otsa, mistõttu tuleb puhvrid kirjutada kõvakettale. Seda protsessi nimetatakse saalimiseks (swapping).

Virtuaalne failisüsteem (Virtual File System):

Virtuaalne failisüsteem pakub vahekihti süsteemi kutsungiliidese ja tuuma poolt toetatud failisüsteemide vahel.

Fig3.jpg

Skeem 3: Virtuaalne failisüsteem vahendab infot kasutajate ning failisüsteemide vahel

Virtuaalse failisüsteemi ülemises otsas on realiseeritud tavapärane API abstraktsioon, mis sisaldab põhilisemaid funktsioone (nt open, close, read, write). Allpool asub failisüsteemi abstraktsioon, mis defineerib kuidas kõrgema kihi funktsioone rakendatakse. Failisüsteemi kihi all asub omakorda puhver, mis sisaldab universaalseid funktsioone, mis ei sõltu konkreetsest failisüsteemi tüübist. See kiht optimeerib ligipääsu füüsilistele seadmetele ja muudele riistvarakomponentidele hoides lühiajaliselt mälus järgmisena vajaminevat infot. Puhvri all asuvad omakorda draiverid, mis juhivad juba konkreetsete füüsilise seadme tööd.

Võrgukihid (Networking Stack):

Võrgu ülesehitus Linux'is järgib kihilist arhitektuurimudelit ning koosneb seega mitmetest eriotstarbelistest kihtidest.

Seadme juhtprogrammid (Device Drivers):

Suur enamus Linux'i tuuma lähtekoodist eksisteerib seadme juhtprogrammidena. Linux'is on juhtprogrammid järjestatud puuna vastavalt toetatavatele seadmetüüpidele (nt Bluetooth, I2C, Serial jne).

Lisaks eelnevale põgusale ülevaatele Linux'i tuuma ülesehitusest pakub ta lisaks palju huvitavaid võimalusi. Kuna tegemist on vabavaralise süsteemiga, mille lähtekood on kõigile avatud ning kättesaadav, on Linuxi tuumaga võimalik katsetada uusi protokolle ning nende edasiarendusi.

Veel üks kasulik omadus on dünaamiliselt laetavad moodulid, mis võimaldavad käigu pealt lisada ja eemaldada tarkvarakomponente.

Tuuma paigaldamine

Süsteemil saab olla korraga paigaldatud mitu tuuma, mille vahel saab valida alglaadimise käigus (GRUB menu). Tuuma paigaldades saab valida mitmete erinevate versioonide vahel, kusjuures LTS (Long Term Support) versioonid on rohkem testitud, pikemalt toetatavad ning sobivad seega missioonikriitilistesse süsteemidesse. LTS versioonidest on tavaliselt olemas ka uuemad versioonid, mis sisaldavad uusimat riistvaratuge ning nendes versioonides on eemaldatud rohkem turvavigu. Negatiivse aspektina on need vähem testitud ning ei pruugi olla nii stabiilsed kui LTS versioonid. Selleks, et näha milline tuuma versioon on hetkel paigaldatud, saab kasutada järgmist käsku:

$ uname -r

4.40-57-generic

Käsk "uname" prindib välja süsteemi info, lipp -r aga väljastab tuuma täpse versiooni.

Linux'i tuuma saab paigaldada erinevalt. Üks võimalus on laadida alla lähtekood ja see kompileerida (see ei ole soovitatav tegevus). Lihtsam on aga kasutada pakihalduse vahendeid (Ubuntu puhul näiteks apt-get). Nagu ikka, on soovitav enne uute pakkide paigaldamist uuendada varamud ning seejärel paigaldada nii Linux'i tuum kui päise metapaketid. Näiteks Ubuntu 16.04 LTS Xenial Xerus korral:

$ sudo apt-get update
$ sudo apt-get install linux-image-generic-lts-xenial linux-headers-generic-lts-xenial linux-image-generic linux-headers-generic && sudo apt clean && sudo update-grub

Samuti tuleb peale paigaldust teha arvutile taaskäivitus käsuga:

$ sudo reboot

Kui on soov paigaldada juba olemasoleva tuuma uuem versioon, on veelgi lihtsam teha süsteemile kõikide pakkide uuendus käsuga

$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get clean

Üldjuhul tehakse kogu süsteemi uuenduse korral (sudo apt-get dist-upgrade) ka automaatselt alglaaduri GRUB uuendamine, kuid kindluse mõttes tasub peale uuema tuuma paigaldamist teha ka see käsitsi käsuga

$ sudo update-grub

Siis teab alglaadur käivituse ajal uusima tuuma kasutusele võtta. Alglaaduri korduv uuendamine ei mõju kuidagi süsteemile halvasti ja seega võib seda käsku julgelt kasutada.

$ sudo apt-get autoremove

Vanade tuumade eemaldamine

Kui uusim LTS-versiooni tuum paigaldatud, alglaadur uuendatud, süsteem taaskäivitatud ja veendutud uname -r abil, et töötatakse uusima tuuma pealt siis tuleks vanad ja kasutuses mitteolevad tuumad turvalisuse kaalutlustel ka eemaldada.

Vaatame esmalt, millised tuumad on paigaldatud:

$ dpkg --get-selections | grep linux-image
$ dpkg --get-selections | grep linux-headers

Uue tuuma paigaldamisel tekitatakse süsteemi mõned uued failid, mis tavaliselt lisatakse /boot kausta. Iga tuuma versiooni jaoks tehakse eraldi fail.

  • vmlinuz - tuum ise
  • initrd - ajutine failisüsteem, mida kasutatakse enne tuuma laadimist
  • System.map - Lookup tabel
  • config - konfiguratsiooni sätted, kuhu pannakse kirja, millised moodulid laaditakse

Seejärel veendume, millise tuuma versiooni pealt arvuti hetkel töötab

$ uname -r

Kui kasutuses olev tuum on uusim, võib uuematel Ubuntu süsteemidel kohe vanad versioonid eemaldada käsuga:

$ sudo purge-old-kernels

See käsk eemaldab kõik vanad tuumad ja jätab alles kaks uusimat. Kui on soov alles jätta vaid uusim, saab kasutada käsku:

$ sudo purge-old-kernels --keep 1

kus lipuke --keep 1 jätab alles vaid viimase versiooni.

NB! See käsk ei ole paraku vaikimisi saadaval ning selle kasutamiseks tuleb paigaldada pakk nimega byobu:

$ sudo apt-get update
$ sudo apt-get install byobu
$ sudo apt-get clean

Kuna vaikimisi varamutes ei ole byobu uusim versioon saadaval, võib soovi korral lisada ka byobu enda varamu ning paigaldada byobu peale varamu lisamist ja nimekirja uuendamist:

$ sudo add-apt-repository ppa:byobu/ppa
$ sudo apt-get update
$ sudo apt-get install byobu
$ sudo apt-get clean

Tuuma käigu pealt parandamine

Aegajalt võib ette tulla, et tuuma kasutuses oleva versiooniga on midagi juhtunud ning tuuma alglaadimine ebaõnnestub või ei tuvastata selle tuuma versiooni olemasolu üleüldse. Selline olukord võib ette tulla näiteks juhul kui teostatakse süsteemi uuendust ning tööjaam või server peatab selle käigus töö (näiteks läheb elekter ära). Kuna uuenduste paigaldus jäi poolikuks võib juhtuda, et masin ei suuda teostada enam alglaadimist.

Uusima versiooni parandamine

Selliste olukordade vältimiseks on soovitatav hoida alles vähemalt üks tuuma vanem versioon, mida saab vajadusel alglaadimismenüüst valida ning selle abil süsteem tööle saada. Seejärel on võimalik uusim (kuid mittetöötav) tuum eemaldada käsuga:

$ sudo apt-get purge linux-image-x.x.x

kus x.x.x tuleks asendada tuuma versiooniga (nt 3.4.8). Seejärel saab paigaldada tuuma tehes süsteemi uuenduse ning uuendada GRUB

$ sudo apt-get update
$sudo apt-get dist-upgrade
$sudo update-grub
$sudo apt-get clean

Seejärel teha süsteemile restart, misjärel peaks uusim tuum uuesti käivituma:

$ sudo reboot

Taastusrežhiim

Alternatiivselt saab proovida taastusrežiimi (recovery mode). Selleks tuleb masin tööle panna ning all hoida SHIFT klahvi. See toob esile alglaadimismenüü:

Grub-recovery-mode-1.png

Skeem 4: GRUB alglaadimismenüü

Seejärel tuleb järgmisest menüüst valida root - Drop to root shell prompt

Grub-recovery-mode-2.png

Skeem 5: Recovery menu

Lisaks tuleb lubada kirjutuse/lugemise õigus failisüsteemile:

mount -rw -o remount /

Nüüd saab vigase tuuma eemaldada ja seejärel uuesti paigaldada (vt. ka eelmised punktid "Tuuma paigaldamine" ja "Vanade tuumade eemaldamine):

$ sudo apt-get purge linux-image-x.x.x
$ sudo update-grub

Seejärel sisestada exit ning valida resume normal boot

Tuuma moodulid

Linux'i tuumas ei pea uue funktsionaalsuse loomiseks käsitsi tuuma koodi juurde kirjutama, vaid funktsionaalsust lisatakse moodulite abil. Moodulid on tarkvaratükid, mis laetakse tuuma ning suuremal osal juhtudest saab need kasutusele võtta isegi ilma süsteemi taaskäivitamata.

Hetkel tuuma laetud mooduleid saab näha käsuga

$ lsmod

Uue mooduli laadimiseks

$ sudo modprobe bluetooth

modprobe on siinjuures haldusvahend, mis üritab laadida mooduli /lib/modules/(kernel version)/kernel/drivers kaustast. Tuuma moodulitel on tihti ka sõltuvused ehk teised pakid, mis peavad olema paigaldatud, et moodul töötaks. Ka siin tuleb appi pakihalduse tarkvara. Kui paigaldatud moodulil on millegipärast puudu pakid, mida ta soovib kasutada (need on näiteks kustutatud, või millegi pärast pole neid üldse paigaldatud), saab üritada need üles otsida ja paigaldada käsuga:

$ sudo apt-get --fix-broken install

või lihtsalt

$ sudo apt-get -f install

NB! pakihaldur apt-get ise puuduvaid või katkisi sõltuvusi tekkida ei luba, eelpool olev olukord võib juhtuda pigem käsitsi seadistamise tulemusel.

Mooduli eemaldamiseks saab kasutada käsku:

$ sudo modprobe -r bluetooth

/proc failisüsteem

Linux'i tuum pakub palju infot ka läbi /proc failisüsteemi. Näiteks on võimalik lisaks lsmod käsule hetkel laetud mooduleid vaadelda otse /proc/modules kaustast:

cat /proc/modules

Veel üks tähtis kaust on /proc/sys, näiteks saab kontrollida, kas ip marsruutimine on sisse lülitatud vaadeldes /proc/sys/net/ipv4/ip_forward sisu:

cat /proc/sys/net/ipv4/ip_forward

Nendesse failidesse saab loomulikult ka kirjutada, seega võime ip marsruutimise sisse lülitada kirjutades faili üle numbriga 1:

echo 1 > /proc/sys/net/ipv4/ip_forward
0

Täpselt sama tulemuse saab alternatiivselt käsuga sysctl:

sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

Viited

1. Anatomy of the Linux kernel: https://www.ibm.com/developerworks/library/l-linux-kernel/l-linux-kernel-pdf.pdf

2. How the Linux kernel works: http://www.tuxradar.com/content/how-linux-kernel-works

3. Kernel Definition: http://www.linfo.org/kernel.html

4. Linux Journey: https://linuxjourney.com/lesson/kernel-overview

5. Tuuma paigaldamine: https://github.com/edmundlaugasson/linuxjourney/blob/master/lessons/locales/et_estonian/kernel/kernel-installation.md