Mikrojádro

Mikrojádro

Mikrojádro je v informatice typ jádra operačního systému, které je velmi malé a obsahuje jen nejzákladnější funkce (typicky správu paměti a podporu pro plánování procesů a meziprocesové komunikace), čímž se minimalizuje objem běžícího kódu v privilegovaném režimu. Ostatní potřebné části jádra jsou řešeny v uživatelském prostoru jako běžné procesy (resp. démoni, u mikrojader se označují servery), například správa souborového systému, ovladače zařízení, podpora protokolů pro počítačové sítě a další. Mezi zástupce systémů s mikrojádrem patří operační systém MINIX 3, GNU Hurd (s mikrojádrem GNU Mach), L4Linux (s mikrojádrem L4-Fiasco.OC)[1], PikeOS, QNX a Symbian OS. Opakem mikrojádra je monolitické jádro, kompromisem pak hybridní jádro.

Charakteristika

Mikrojádro je novější odlišný návrh, který se staví do protikladu k monolitickému jádru, u kterých byl kvůli velikosti obtížný vývoj a údržba.[2] Návrh mikrojádra proto odpovídá teorii strukturovaného programování.[3] Rozdělení na více samostatných logických celků umožňuje získat vysoké hodnocení bezpečnosti[4] a zajistit vysokou spolehlivost.[5]

V některých případech je za výhodu mikrojádra označována schopnost se udržet v chodu i poté, co dojde v některém z podsystémů k závažné chybě, protože příslušný server může být restartován.[5] Velkým problémem je však v takovém případě ztráta původního stavu (například navázaná síťová spojení, obsahy bufferů, cache), kterou lze řešit jen na úkor komplexity obsluhy serverů a jejich interních mechanismů. Tato vlastnost také může vést ke kontraproduktivnímu postoji, že pro mikrojádra není nutné vytvářet 100% spolehlivé ovladače.

Nespornou výhodou mikrojádra je schopnost jednoduše pozastavit jednotlivé servery a případně odpojit od napájení i jimi ovládané zařízení, což může vést k úsporám elektrické energie (např. Symbian OS) a což nelze v monolitickém jádře tak snadno zařídit.

Vliv na výkon

Nevýhodou mikrojádra je, že při požadavku na službu jádra je nutné projít několika změnami kontextu mezi žádajícím procesem, mikrojádrem a obsluhujícími servery (na rozdíl od monolitického jádra, kde dojde při systémovém volání jádra jen ke dvěma změnám mezi kernel a user space). Dalším problémem je mechanismus meziprocesové komunikace, který vede k velkým ztrátám na výkonu (a lavinovitým změnám kontextu). V tomto ohledu lze však pečlivým návrhem dosáhnout značných vylepšení.[6] Další nevýhodou je vlastní návrh mikrojádra, který vyžaduje existenci více či méně oddělených datových struktur, zatímco v monolitickém jádře jsou všechna data přístupná přímo, což umožňuje dosahovat vyššího výkonu, což vedlo u některých systémů k příklonu k hybridnímu jádru (např. Windows NT, Windows CE).

Mnoha ohledům výhod a nevýhod se věnovaly debaty mezi Linusem Torvaldsem (tvůrce monolitického jádra Linuxu) a Andrewem S. Tanenbaumem (tvůrce mikrojádra MINIXu).[2][5]

Mikrojádro a Unix

Unixová filozofie původně představovala malé jádro, které je považováno za dokonale bezchybné. První jádra operačních systémů, stejně jako Unixu byla původně malá. S postupným vývojem hardware, stejně jako s rostoucím počtem podporovaných služeb tato jádro nabývala na velikosti. Postupně tak docházelo ke vzniku jader, která mají i milióny řádek zdrojového kódu. I když jsou unixové systémy tradičně spojeny s monolitickými jádry, může být i unixové jádro implementováno jako mikrojádro. Příkladem je operační systém MINIX 3[7] a jádro GNU Mach.

Nevýhodou rozsáhlých monolitických jader je, že u nich nelze dosáhnout původního předpokladu unixové filozofie – totiž toho, že takové jádro bude (z praktického hlediska) prosté chyb a tudíž bezchybně fungující. To je jeden z důvodů, že jen málokterý operační systém dnes neobsahuje mikrojádrové prvky včetně např. Microsoft Windows či macOS.

Meziprocesová komunikace

Související informace naleznete také v článku Meziprocesová komunikace.

Meziprocesová komunikace umožňuje odděleným procesům komunikovat navzájem, obvykle zasíláním zpráv. Pro implementaci se často používá sdílená paměť. Meziprocesová komunikace je pro mikrojádra kritickým místem, který má zásadní vliv na jejich výkon (viz výše).

IPC může být synchronní nebo asynchronní. Asynchronní IPC je analogická se síťovou komunikací: odesilatel odešle zprávu a pokračuje v provádění činnosti. Příjemce dotazováním zkontroluje dostupnost zprávy při pokusu ji obdržet nebo je na přijetí zprávy upozorněn přes jiný mechanismus oznamování. Asynchronní IPC vyžaduje, aby jádro udržovalo vyrovnávací paměti a fronty zpráv, a zabývá se přetečením vyrovnávací paměti; ale také vyžaduje dvojité kopírování zpráv (odesílatel jádru a jádro příjemci). V synchronní IPC první strana (odesilatel nebo příjemce) blokuje, než druhá strana je připravena k realizaci IPC. Nevyžaduje vyrovnávací nebo vícenásobné kopie, ale implicitní setkání může být pro programování ošidné. Většina programátorů proto raději používá asynchronní a synchronní příjem zároveň.

První generace mikrojader obvykle podporovala synchronní i asynchronní IPC, ale neměla tak vysoký výkon. Jochen Liedtke navrhl design a implementaci IPC mechanizmů jako důvod k vyřešení špatného výkonu. Jeho mikrojádra rodiny L4, díky nimž se stal průkopníkem v technice, vedla k řádovému snížení režie IPC. Mezi ně patří systém IPC volání, který podporuje odesílací a přijímací operace, takže všechny IPC jsou synchronní a předávají mnoho dat skrze registry procesoru. Dále Liedtke představil koncept přímého procesového přepínače, kde se v průběhu vykonávání IPC provádí neúplná změna kontextu přímo od odesílatele k příjemci. Stejně jako v L4 je část nebo celá zpráva předávána jen uvnitř registrů, převod části zprávy v registrech se děje bez jakéhokoliv kopírování. Kromě toho se vyhneme režii vyvolávací paměti, což je zvláště výhodné v případě, kdy se IPC používá ve vzdáleném volání procedur (RPC), tedy klientem iniciované volání serveru. Další optimalizace, tzv. líné plánování, zabraňuje křížení plánovací fronty v IPC tím, že uvolní vlákna, která blokují IPC v připravené frontě. Jakmile je plánovač použit, přenese taková vlákna do čekající fronty. V mnoha případech se vlákno odblokuje před dalším vyvoláním plánovačem, tato metoda nám ušetří práci. Podobné metody byly adoptovány v systémech QNX a MINIX.

V systémech klient-server je většina komunikace v podstatě synchronní, a to i v případě použití asynchronních základů. Typický provoz je takový, že klient vyvolá server a pak čeká na odpověď. Asynchronní IPC může být prováděna použitím pomocníka vláken (anglicky helper threads). Avšak díky verzi L4 implementované v komerčních produktech se zjistilo, že je nezbytné pro lepší komunikaci přidání asynchronního oznamování. Tento signál nepřenáší data, a proto nevyžaduje vyrovnávací paměti jádra.

Jak synchronní IPC blokuje jednu stranu, než je druhá strana připravena, tak by jeho neomezené použití mohlo vést k zablokování (deadlock). Mimoto může klient snadno způsobit odmítnutí služby na serveru tak, že odesílá požadavky a nikdy se nepokusí o získání odpovědi. Proto se u synchronního IPC často využívá timeoutů, které omezují dobu blokování IPC. V praxi je výběr rozumné hodnoty časového limitu obtížný a systémy téměř nevyhnutelně používají nekonečné časové limity pro klienty a nulové časové limity pro servery. V důsledku toho je, že trend nesměřuje k poskytování libovolného časového limitu, ale pouze příznaku, který ukazuje, že IPC selhalo. Tento přístup účinně nabízí výběr ze dvou timeoutových hodnot nuly a nekonečna. Poslední verze L4 a Minixu šly touto cestou (starší verze L4 používá časové limity, stejně jako QNX).

Servery

Základní sada serverů pro univerzální mikrojádro zahrnuje servery souborového systému, servery ovladačů zařízení, síťové servery, servery displeje a uživatelské rozhraní serveru zařízení. Tato sada serverů (převzato od QNX) poskytuje zhruba soubor služeb, jako monolitické jádro u unixových systémů. Potřebné servery jsou spuštěny systémem a poskytují služby, jako je souborový systém, síť a přístup k zařízením pro běžné aplikační programy. Servery běží v prostředí běžných uživatelských aplikací. Vývoj serverů je spíše podobný vývoji běžných aplikací, než programování na úrovni jádra systému. Chybové stavy lze korigovat zastavením a restartováním serveru, avšak tím se ztrácí informace o původním stavu komunikace či výpočtu, a proto tento přístup vyžaduje, aby se aplikace uměla vyrovnat s neúspěchem při volání služby poskytované serverem. Příkladem může být server zodpovědný za TCP/IP stack (síťový subsystém): pokud je tento server restartován, aplikace zaznamená výpadek spojení, což je však v prostředí sítí běžný jev. U jiných služeb se však běžně neočekává, že jejich volání selže, a proto tento přístup může vyžadovat změny v kódu aplikace.

Proto, aby všechny servery byly restartovatelné, se některá mikrojádra soustředila na přidávání různých databázových technik, jako jsou databázové transakce, replikace a checkpointing. V případě, že má být zachován základní stav, se restartuje jen jeden server. Příkladem je ChorusOS, který byl zaměřen na zajištění vysoké dostupnosti aplikací telekomunikačního světa. Chorus zahrnoval vlastnosti, které dovolují „nesprávně napsané“ servery kdykoliv restartovat. Klienti používající tyto servery jsou pozastaveni, zatímco se server vrací zpět do původního stavu.

Ovladače zařízení

Ovladač zařízení využívá často přímý přístup do paměti nebo programování DMA přenosů, a proto potřebuje mít možnost zapisovat na libovolné místo operační paměti včetně datových struktur jádra. Takové ovladače proto musí být z hlediska zbytku jádra (či systému) důvěryhodné. Proto však nutně nemusí být ovladač součástí jádra.

Uživatelský režim ovladačů ve skutečnosti přebírá mikrojádro. Michigan Terminal System (MTS) byl již v roce 1967 prvním systémem, který podporoval ovladače realizované v uživatelském prostoru (včetně podpory souborového systému). Historicky byly ovladače menším problémem, protože počet zařízení byl malý a věřilo se, že se to nezmění. Ovladač v jádře znamenal jednodušší návrh a eliminaci problémům s výkonem. To vedlo k tradiční implementaci ovladačů v jádře systému ve stylu původních unixových systémů jako je Linux, ale i pro systémy Microsoft Windows. S postupem času se počet různých typů periferií zvětšoval a tím i množství kódu nutného pro ovladače, takže v současných systémech tvoří ovladače většinu zdrojového kódu.

Nutné komponenty a minimalita

Mikrojádro musí minimálně, mimo libovolných služeb operačního systému, poskytnout tyto mechanismy:

Průkopníky ve využití minimálního designu byly operační systémy Nucleus (zakladatel Brinch Hansen) a VM (od IBM).

Jochen Liedtke stanovil tzv. minimální princip, který vypadá takto:

Koncept je tolerován uvnitř mikrojádra, pouze když přesun vně jádro, tj. povolení implementací, by zabránil implementaci požadované systémové funkcionality.[8]

Všechno ostatní může být zhotoveno v uživatelských programech, ačkoliv některé ovladače zařízení, implementované jako uživatelské programy, mohou na některých procesorových architekturách vyžadovat privilegia na přístup k I/O hardwaru. Vzhledem k efektivnosti obsahuje většina mikrojader plánovací a spravovací časovače (porušují tím ale minimální princip). Start operačního systému, založeného na mikrojádru, vyžaduje ovladače zařízení (které nejsou součástí jádra). Většinou to znamená, že jsou ovladače zabaleny s jádrem v boot obrazu a jádro podporuje bootstrap (samozaváděcí) protokol, který definuje, kde jsou dané ovladače a jak je spouštět – toto je tradiční boostrap procedura mikrojader L4. Některé mikrojádra tuto proceduru zjednodušují uložením některých klíčových ovladačů přímo do jádra (porušení minimálního principu), například LynxOS či Minix. Některé dokonce přidání souborového systému do jádra ke zjednodušení bootovací procedury. V některých případech, například GNU GRUB, systém, založený na mikrojádru, může bootovat pomocí boot loaderu. Takovéto systémy obvykle načtou statické servery pro vytvoření prvotní bootstrap procedury (nebo čekají na obraz OS pro pokračování bootstrap procedury). Klíčovou komponentou operačního systému, založeného na mikrojádru, je dobrá IPC a manažer virtuální paměti. Protože všechny úlohy jsou provedeny v uživatelských programech, efektivní komunikace mezi programy je klíčová, daleko důležitější, než je tomu v monolitických jádrech.

Výkon

Na většině mainstreamových procesorů je přepnutí mezi úlohami podstatně pomalejší v systému založeném na mikrojádře, než v monolitickém jádře.[9] V monolitickém systému je úkol získán jedním systémovým voláním, které potřebuje dva přepínače módů (změna procesorového režimu, módu). V systémech, založených na mikrojádru, jsou úlohy získány odesláním IPC zprávy na server a získávání výsledku probíhá v další IPC zprávě ze serveru. Toto vyžaduje tzv. změnu kontextu, pokud jsou tedy ovladače implementovány jako procesy, pokud jsou ovladače implementovány jako procedury, vyžaduje to pak volání funkcí. Posílání dat na server a zpět může způsobit extra kopírování, zatímco v monolitickém systému může kernel přistoupit přímo k datům klienta.

Výkon je proto potenciálním problémem v systémech, založených na mikrojádru. Ačkoliv zkušenosti z prvních generací mikrojader, jako třeba Mach a Chorus, ukázaly, že systémy, založené na těchto jádrech, byly velmi výkonově slabé,[10] Jochen Liedtke ukázal, že výkonové problémy Machu byly výsledkem špatného designu, implementace a hlavně pak Machovy velké cache.[8] Liedtke demonstroval se svým vlastním mikrojádrem L4, že skrz pozorný design, implementaci a hlavně dodržováním principu minimalizace, užívání IPC může být sníženo o více než jeden řád ve srovnání s Machem. Výkon L4 IPC není stále dodnes poražen v rozmezí dostupných architektur.[11][12][13]

Zatímco tyto výsledky demonstrují, že slabý výkon systémů, založených na mikrojádrech první generace, není reprezentativní pro druhou generaci jader (jako například L4), stejně to nedokazuje, že systémy, založené na mikrojádru, mohou být postaveny se solidním výkonem. Bylo totiž zjištěno, že monolitický Linux server, konvertovaný na L4, vykazuje výsledek pouze o pár procent lepší, než nativní Linux.[14] Takovéto jednotné servery se ale prakticky vůbec neobjevují. Výhody operačních systémů, založených na mikrojádře, spočívají v poskytování strukturované funkcionality operačního systému na více serverech najednou.

Mezi komerční multiprocesorové systémy můžeme zařadit například real-time systémy QNX a Integrity. U těchto systémů ale nebyly vypracovány podrobné porovnání výkonu s monolitickými systémy a zdá se, že výkon pro tyto výrobce není zas tak primární, spoléhají primárně na rychlé zachycení přerušení (QNX) a jednoduchost z důvodu robustnosti celého systému. Pokus o vytvoření výkonného multiprocesorového operačního systému byl projekt IBM Sawmill Linux.[15] Tento projekt ale nebyl nikdy dokončen.

Bylo ukázáno, že ovladače zařízení na uživatelské úrovni se mohou blížit výkonem jádrových ovladačů dokonce i pro zařízení náročné na datový tok a s vysokými nároky na přerušení (Gigabit Ethernet).[16] Z toho se dá mimo jiné usoudit, že výkonné multiserverové systémy jsou možné.

Odkazy

Reference

  1. TU Dresden [cit. 2015-06-17]. Dostupné online. (anglicky) 
  2. a b – Open Sources: Voices from the Open Source Revolution (Tanenbaum-Torvalds Debate)
  3. Edsger Dijkstra označil GOTO za škodlivý příkaz v roce 1969 a v roce 1972 vydal pojednání o strukturovaném programování
  4. Klein, Gerwin; Elphinstone, Kevin; Heiser, Gernot; Andronick, June; Cock, David; Derrin, Philip; Elkaduwe, Dhammika; Engelhardt, Kai; Kolanski, Rafal; Norrish, Michael; Sewell, Thomas; Tuch, Harvey; Winwood, Simon (October 2009). "seL4: Formal verification of an OS kernel". 22nd ACM Symposium on Operating System Principles. 
  5. a b c – Tanenbaum-Torvalds Debate: Part II
  6. Liedtke, Jochen (December 1993). "Improving IPC by kernel design". 14th ACM Symposium on Operating System Principles: 175–88. 
  7. Towards a True Microkernel Operating System, viz http://www.minix3.org/theses/herder-true-microkernel.pdf
  8. a b Liedtke, Jochen (December 1995). "On µ-Kernel Construction". 15th ACM symposium on Operating Systems Principles: 237–250. doi:10.1145/224056.224075. 
  9. LIEDTKE, Jochen. Towards Real Microkernels. Communications of the ACM. 1996, s. 70–77. DOI 10.1145/234215.234473. 
  10. Chen, Bradley; Bershad, Brian (December 1993). "The Impact of Operating System Structure on Memory System Performance". 14th ACM Symposium on Operating System Principles: 120–33. doi:10.1145/168619.168629. 
  11. Liedtke, Jochen; Elphinstone, Kevin; Schönberg, Sebastian; Härtig, Hermann; Heiser, Gernot; Islam, Nayeem; Jaeger, Trent (May 1997). "Achieved IPC performance (still the foundation for extensibility)". 6th Workshop on Hot Topics in Operating Systems: 28–31, Cape Cod, MA, USA: IEEE.  – neplatný odkaz !
  12. Gray, Charles; Chapman, Matthew; Chubb, Peter; Mosberger-Tang, David; Heiser, Gernot (April 2005). "Itanium—a system implementor's tale". USENIX Annual Technical Conference: 264–278. 
  13. van Schaik, Carl; Heiser, Gernot (January 2007). "High-performance microkernels and virtualisation on ARM and segmented architectures". 1st International Workshop on Microkernels for Embedded Systems: 11–21, Sydney, Australia: NICTA. Retrieved on 2007-04-01.  Archivováno 26. 4. 2007 na Wayback Machine. Archivovaná kopie. ertos.nicta.com.au [online]. [cit. 2011-10-21]. Dostupné v archivu pořízeném z originálu dne 2007-04-26. 
  14. HÄRTIG, Hermann, Hohmuth, Michael; Liedtke, Jochen; Schönberg, Sebastian. The performance of µ-kernel-based systems. Proceedings of the sixteenth ACM symposium on Operating systems principles. 1997, s. 66–77. Dostupné online. ISBN 0-89791-916-5. DOI 10.1145/268998.266660. 
  15. Gefflaut, Alain; Jaeger, Trent; Park, Yoonho; Liedtke, Jochen; Elphinstone, Kevin J.; Uhlig, Volkmar; Tidswell, Jonathon E.; Deller, Luke; Reuther, Lars (2000). "The Sawmill multiserver approach". 9th ACM SIGOPS European Worshop: 109–114. 
  16. LESLIE, Ben, Chubb, Peter; FitzRoy-Dale, Nicholas; Götz, Stefan; Gray, Charles; Macpherson, Luke; Potts, Daniel; Shen, Yueting; Elphinstone, Kevin; Heiser, Gernot. User-level device drivers: achieved performance. Journal of Computer Science and Technology. 2005, s. 654–664. DOI 10.1007/s11390-005-0654-4. 

Související články

Média použitá na této stránce

Kernel-microkernel.svg
Overview of a microkernel, SVG version