GNU/Linux >> Znalost Linux >  >> Linux

Jak se v Linuxu řeší přerušení?

Zde je pohled na nízkou úroveň zpracování na vysoké úrovni. Popisuji jednoduchou typickou architekturu, skutečné architektury mohou být složitější nebo se mohou lišit způsoby, které na této úrovni detailů nejsou důležité.

Když dojde k přerušení, procesor hledá, zda nejsou přerušení maskována. Pokud jsou, nic se neděje, dokud nebudou demaskovány. Když se přerušení odmaskují, pokud existují nějaká čekající přerušení, procesor je vybere.

Poté procesor provede přerušení větvením na konkrétní adresu v paměti. Kód na této adrese se nazývá obsluha přerušení. Když se tam procesor větví, maskuje přerušení (takže obsluha přerušení má výhradní kontrolu) a ukládá obsah některých registrů na nějaké místo (typicky jiné registry).

Obsluha přerušení dělá to, co dělat musí, obvykle komunikuje s periferním zařízením, které spustilo přerušení, aby odeslalo nebo přijalo data. Pokud bylo přerušení vyvoláno časovačem, obsluha by mohla spustit plánovač OS, aby se přepnul na jiné vlákno. Když handler dokončí provádění, provede speciální instrukci return-from-interrupt, která obnoví uložené registry a odmaskuje přerušení.

Obsluha přerušení musí běžet rychle, protože brání spuštění jakéhokoli jiného přerušení. V linuxovém jádře je zpracování přerušení rozděleno na dvě části:

  • Horní polovina je obsluha přerušení. Dělá nezbytné minimum, obvykle komunikuje s hardwarem a nastavuje příznak někde v paměti jádra.
  • „Spodní polovina“ provádí jakékoli další nezbytné zpracování, například kopíruje data do paměti procesu, aktualizuje datové struktury jádra atd. Může to trvat dlouho a dokonce blokovat čekání na jinou část systému, protože běží s přerušeními povoleno.

Jako obvykle na toto téma, pro více informací si přečtěte Linux Device Drivers; kapitola 10 je o přerušeních.


Gilles již popsal obecný případ přerušení, následující platí konkrétně pro Linux 2.6 na architektuře Intel (část je také založena na specifikacích Intelu).

Přerušení je událost, která mění sekvenci instrukcí prováděných procesorem.
Existují dva různé druhy přerušení:

  • Synchronní přerušení (výjimka) produkované CPU při zpracování instrukcí
  • Asynchronní přerušení (přerušení) vydávané jinými hardwarovými zařízeními

Výjimky jsou způsobeny chybami programování (např. Chyba rozdělení , Chyba stránky , Přetečení ), které musí zpracovat jádro. Vyšle signál do programu a pokusí se zotavit z chyby.

Jsou klasifikovány následující dvě výjimky:

  • Výjimka zjištěná procesorem generované CPU při detekci anomálního stavu; rozděleny do tří skupin:Chyby lze obecně opravit, Pasti nahlásit provedení, Přeruší jsou závažné chyby.
  • Naprogramovaná výjimka vyžádaný programátorem, zacházeno jako s pastí.

Přerušení mohou vydávat I/O zařízení (klávesnice, síťový adaptér, ..), intervalové časovače a (na víceprocesorových systémech) další CPU. Když dojde k přerušení, CPU musí zastavit svou aktuální instrukci a provést nově příchozí přerušení. Potřebuje uložit starý stav přerušeného procesu, aby jej (pravděpodobně) obnovil po zpracování přerušení.

Zpracování přerušení je citlivý úkol:

  • K přerušení může dojít kdykoli, jádro se ho snaží co nejdříve dostat z cesty
  • Přerušení může být přerušeno jiným přerušením
  • V jádře jsou oblasti, které nesmí být vůbec přerušeny

Jsou definovány dvě různé úrovně přerušení:

  • Maskovatelná přerušení vydávané I/O zařízeními; může být ve dvou stavech, maskovaný nebo odmaskovaný. Zpracovávají se pouze odmaskovaná přerušení.
  • Nemaskovatelná přerušení; kritické poruchy (např. selhání hardwaru); vždy zpracovává CPU.

Každé hardwarové zařízení má svůj vlastní řádek požadavku na přerušení (IRQ). IRQ jsou číslována od 0. Všechny linky IRQ jsou připojeny k programovatelnému řadiči přerušení (PIC). PIC naslouchá IRQ a přiřazuje je CPU. Je také možné zakázat konkrétní linku IRQ.
Moderní multiprocessingové linuxové systémy obecně zahrnují novější Advanced PIC (APIC), který rozděluje požadavky IRQ rovnoměrně mezi CPU.

Středním krokem mezi přerušením nebo výjimkou a jeho zpracováním je tabulka deskriptorů přerušení (IDT). Tato tabulka spojuje každé přerušení nebo vektor výjimky (číslo) se zadaným obslužným programem (např. chyba rozdělení je zpracována funkcí divide_error() ).

Prostřednictvím IDT jádro přesně ví, jak zacházet s nastalým přerušením nebo výjimkou.

Co tedy jádro udělá, když dojde k přerušení?

  • CPU po každé instrukci zkontroluje, zda existuje IRQ z (A)PIC
  • Pokud ano, poradí se s IDT, aby namapoval přijatý vektor na funkci
  • Zkontroluje, zda přerušení nevydal autorizovaný zdroj
  • Uloží registry přerušeného procesu
  • Zavolejte příslušnou funkci, která přerušení zpracuje
  • Načtěte nedávno uložené registry přerušeného procesu a zkuste jej obnovit

První ze všech účastníků zapojených do zpracování přerušení jsou periferní hardwarová zařízení, řadič přerušení, CPU, jádro operačního systému a ovladače. Za generování přerušení jsou zodpovědná periferní hardwarová zařízení. Uplatňují řádky požadavků na přerušení, když chtějí pozornost od jádra operačního systému. Tyto signály jsou multiplexovány řadičem přerušení, který je zodpovědný za sběr signálů přerušení. Je také zodpovědný za určení pořadí, ve kterém budou signály přerušení předány CPU. Řadič přerušení je schopen dočasně zakázat konkrétní řádek požadavku přerušení (IRQL) a znovu jej povolit (maskování IRQL). Řadič přerušení předává shromážděné požadavky na přerušení do CPU postupně. CPU po dokončení provádění každé instrukce CPU zkontroluje, zda existují nějaké čekající požadavky na přerušení od řadiče přerušení. Pokud CPU zjistí, že existuje čekající požadavek A v interním řídicím registru CPU je nastaven příznak Povolení přerušení, CPU zahájí zpracování přerušení. Jak můžete vidět, manipulací s příznakem přerušení v CPU a komunikací s řadičem přerušení je linuxové jádro schopno řídit přijímání přerušení. Například Linux může zakázat přijímání přerušení z konkrétního zařízení nebo zakázat přijímání přerušení vůbec.

Co se stane, když procesor obdrží požadavek na přerušení? Za prvé, CPU automaticky zakáže přerušení resetováním příznaku přerušení. Po dokončení zpracování přerušení budou znovu povoleny. Současně CPU vynakládá minimální množství práce potřebné pro přepnutí CPU z uživatelského režimu do režimu jádra takovým způsobem, aby bylo možné obnovit provádění přerušeného kódu. CPU konzultuje se speciálními řídicími strukturami CPU vyplněnými linuxovým jádrem, aby našel adresu kódu, kterému bude řízení předáno. Tato adresa je adresou první instrukce obsluhy přerušení, která je součástí linuxového jádra.

Jako první krok zpracování přerušení jádro identifikuje vektor přijatého přerušení, aby identifikovalo, jaký druh události se v systému stal. Vektor přerušení definuje, jaké akce Linux provede, aby to zvládl. Jako druhý krok Linux uloží zbytek CPU registrů (které nebyly uloženy CPU automaticky) a které mohou být potenciálně použity přerušeným programem. Toto je velmi důležitá akce, protože umožňuje Linuxu zacházet s přerušeními transparentně s ohledem na přerušený program. Jako třetí krok Linux provede přepnutí do režimu jádra nastavením prostředí jádra a nastavením stavu CPU, který je pro to nezbytný. A nakonec vektor je volána obsluha závislého přerušení. (Můžete se podívat na makro BUILD_INTERRUPT3 v arch\x86\kernel\entry_32.S a získat další podrobnosti pro příklad související s architekturou x86) V případě periferních zařízení se jedná o rutinu do_IRQ(). (Podívejte se do souboru arch\x86\kernel\irq.c)

Obsluha přerušení závislá na vektoru je obvykle zabalena do volání irq_enter() a irq_exit(). Oblast kódu uzavřená ve dvojici těchto funkcí je atomická s ohledem na jakékoli jiné takové oblasti a je atomická s ohledem na dvojice cli/sti. Irq_enter() a irq_exit() také zachycují některé statistiky související se zpracováním přerušení. Nakonec se jádro podívá do tabulky vector_irq, aby našlo číslo irq přiřazené vektoru přijatého přerušení a zavolalo handle_irq() (z arch\x86\kernel \irq_32.c).

V tomto bodě běžná část zpracování přerušení v Linuxu končí, protože jádro vyhledává rutinu obsluhy přerušení závislou na zařízení nainstalovanou ovladačem zařízení jako součást deskriptoru irq a vyvolává ji. Pokud takový ovladač nebyl nainstalován ovladačem, jádro pouze potvrdí přerušení na řadiči přerušení a přejde k ukončení obecné obsluhy přerušení.

Po skončení zpracování přerušení jádro obnoví stav programu, který byl dříve přerušen, a obnoví provádění tohoto programu.


Linux
  1. Jak používat BusyBox na Linuxu

  2. Úvod do Linuxových přerušení a CPU SMP Affinity

  3. Jak se liší \n a \r na Linuxu a Windows?

  1. Jak nainstalovat Python na Linux

  2. Jak používám cron v Linuxu

  3. Jak nainstalovat Javu na Linux

  1. Jak rozdělit disk v Linuxu

  2. Jak používat Su Command v Linuxu

  3. Jak nainstalovat NodeJS na Linux