Segment stavu úlohy - Task state segment
The segment stavu úkolu (TSS) je struktura na x86 - počítače na bázi, které obsahují informace o a úkol. To je používáno operační systém jádro pro správu úkolů. Konkrétně jsou v TSS uloženy následující informace:
- Registr procesoru Stát
- Oprávnění I / O portu
- Ukazatele zásobníku na vnitřní úrovni
- Předchozí odkaz na TSS
Všechny tyto informace by měly být uloženy na konkrétních místech v TSS, jak je uvedeno v IA-32 manuály.
Umístění TSS
TSS může být kdekoli Paměť. Registr segmentu zvaný registr úkolů (TR) obsahuje a selektor segmentů který ukazuje na platný deskriptor segmentu TSS, který se nachází v souboru GDT (deskriptor TSS nemusí být umístěn v LDT ). Proto pro použití TSS musí jádro operačního systému provést následující:
- Vytvořte položku deskriptoru TSS v GDT
- Načtěte TR selektorem segmentu pro daný segment
- Podle potřeby přidejte informace do TSS v paměti
Z bezpečnostních důvodů by měl být TSS umístěn v paměti, která je přístupná pouze pro jádro.
Registr úkolů
Registr TR je 16bitový registr, který obsahuje selektor segmentu pro TSS. Může být načten přes LTR návod. LTR je privilegovaná instrukce a funguje podobným způsobem jako ostatní načtení registru segmentů. Registr úloh má dvě části: část viditelnou a přístupnou programátorem a část neviditelnou, která se automaticky načte z deskriptoru TSS.
Zaregistrujte státy
TSS může obsahovat uložené hodnoty všech x86 registry. To se používá pro přepínání úkolů. The operační systém může načíst TSS s hodnotami registrů, které nový úkol potřebuje, a po provedení přepnutí hardwarového úkolu (například s IRET instrukce) CPU x86 načte uložené hodnoty z TSS do příslušných registrů. Všimněte si, že některé moderní operační systémy jako např Okna a Linux[1] nepoužívejte tato pole v TSS, protože implementují přepínání softwarových úkolů.
Všimněte si, že během přepínání úloh hardwaru jsou některá pole starý TSS jsou aktualizovány o aktuální obsah registru CPU před hodnotami z Nový TSS jsou čteny. Některá pole TSS jsou tedy pro čtení / zápis, zatímco jiná jsou jen pro čtení:
- Pole pro čtení / zápis: čtení a zápis během přepínání úloh hardwaru.
- Všechny univerzální registry (
EAX
,EBX
,ECX
,EDX
,ESI
,EDI
,EBP
,ESP
); - Všechny segmentové registry (
CS
,DS
,ES
,FS
,GS
,SS
); - Aktuální stav provádění (
EIP
,EFlag
); - The
Odkaz
pole v Nový TSS, pokud k přepnutí úlohy došlo kvůliVOLÁNÍ
neboINT
spíše než aJMP
.
- Všechny univerzální registry (
- Pole jen pro čtení: číst pouze v případě potřeby, jak je uvedeno.
- Řídicí registr 3 (
CR3
), také známý jako základní adresář stránek (PDBR
).- Číst během přepínání úloh hardwaru.
- Registr tabulky místních deskriptorů (
LDTR
);- Číst během přepínání úloh hardwaru.
- Tři páry na úrovni privilegovaných (
SS0: ESP0
,SS1: ESP1
,SS2: ESP2
);- Přečtěte si na mezilehlé úrovni
VOLÁNÍ
neboINT
založit nový zásobník.
- Přečtěte si na mezilehlé úrovni
- Ukazatel bitmapového portu IO (
IOPB
) a samotný bitmapový port I / O;- Číst během
V
,VEN
,INS
neboOUTS
instrukce, pokudCPL> IOPL
k potvrzení, že instrukce je legální (viz Oprávnění I / O portu níže).
- Číst během
- Řídicí registr 3 (
The PDBR
pole je ve skutečnosti úplně první načtené z nového TSS: protože přepínač hardwarových úloh může také přepnout na úplně jiné mapování tabulky stránek, všechna ostatní pole (zejména LDTR
) jsou relativní k novému mapování.
Oprávnění I / O portu
TSS obsahuje 16bitový ukazatel na bitmapu oprávnění I / O portu pro aktuální úkol. Tato bitmapa, obvykle nastavená operačním systémem při spuštění úlohy, určuje jednotlivé porty, ke kterým by měl mít program přístup. I / O bitmapa je bitové pole oprávnění přístupu k portu; pokud má program oprávnění pro přístup k portu, je u příslušného bitového indexu uložena „0“ a pokud program nemá oprávnění, je tam uložena „1“. Pokud je limit segmentu TSS menší než plná bitmapa, předpokládá se, že všechny chybějící bity jsou „1“.
Funkce funguje následovně: když program vydá instrukci x86 I / O portu, jako je IN nebo OUT (viz Výpisy instrukcí x86 - a všimněte si, že existují verze s délkou bajtu, slova a dwordu), hardware provede kontrolu úrovně I / O oprávnění (IOPL), aby zjistil, zda má program přístup ke všem I / O portům. Pokud Aktuální úroveň oprávnění (CPL) programu je numericky větší než úroveň I / O Privilege (IOPL) (program je méně privilegovaný než specifikuje IOPL), program nemá přístup I / O port ke všem portům. Hardware poté zkontroluje bitmapu oprávnění I / O v TSS, aby zjistil, zda má tento program přístup k určitým portům v instrukci IN nebo OUT. Pokud jsou (všechny) relevantní bit (y) v bitmapě oprávnění I / O portu jasné, program má povolený přístup k portům a instrukci je možné provést. Pokud je (je) nastaven (jsou) příslušný bit (y) - nebo pokud (kterýkoli z) bitů je / jsou za limitem segmentu TSS - program nemá přístup a procesor generuje porucha obecné ochrany. Tato funkce umožňuje operačním systémům udělit přístup k vybraným portům uživatelským programům.
Ukazatele zásobníku na vnitřní úrovni
TSS obsahuje 6 polí pro zadání nového ukazatel zásobníku když dojde ke změně úrovně oprávnění. Pole SS0 obsahuje selektor segmentu zásobníku pro CPL = 0 a pole ESP0 / RSP0 obsahuje novou hodnotu ESP / RSP pro CPL = 0. Dojde-li k přerušení v chráněném (32bitovém) režimu, ikona x86 CPU vyhledá v TSS pro SS0 a ESP0 a načte jejich hodnoty do SS a ESP. To umožňuje jádru použít jiný zásobník než uživatelský program a také mít tento zásobník jedinečný pro každý uživatelský program.
Nová funkce představená v AMD64 rozšíření se nazývá Interrupt Stack Table (IST), která se také nachází v TSS a obsahuje logické (segment + offset) ukazatele zásobníku. Pokud tabulka deskriptorů přerušení určuje položku IST, která se má použít (je jich 8), procesor místo toho načte nový zásobník z IST. To umožňuje použití známých dobrých zásobníků v případě vážných chyb (NMI nebo Dvojitá chyba například). Dříve položka pro výjimku nebo přerušení v IDT ukazovala na bránu úlohy, což způsobilo, že procesor přepnul na úlohu, na kterou ukazuje brána úlohy. Původní hodnoty registru byly uloženy do proudu TSS v době, kdy došlo k přerušení nebo výjimce. Procesor poté nastavil registry, včetně SS: ESP, na známou hodnotu uvedenou v TSS a selektor uložil do předchozího TSS. Problém je v tom, že přepínání úloh hardwaru není na AMD64 podporováno.
Předchozí odkaz na TSS
Jedná se o 16bitový selektor, který umožňuje propojení tohoto TSS s předchozím. Používá se pouze pro přepínání hardwarových úloh. Viz IA-32 manuály pro podrobnosti.
Použití TSS v Linuxu
Přestože lze TSS vytvořit pro každou úlohu spuštěnou v počítači, Linuxové jádro vytvoří pouze jeden TSS pro každý CPU a použije je pro všechny úkoly. Tento přístup byl zvolen, protože poskytuje snadnější přenositelnost do jiných architektur (například AMD64 architektura nepodporuje hardwarové přepínače úloh) a lepší výkon a flexibilitu. Linux používá pouze bitmapu oprávnění I / O portu a funkce vnitřního zásobníku TSS; ostatní funkce jsou potřebné pouze pro hardwarové přepínače úloh, které jádro Linux nepoužívá.[2]
X86 výjimka vektor 10 se nazývá neplatná výjimka TSS (#TS). Vydává jej procesor, kdykoli se něco pokazí s přístupem TSS. Například pokud dojde k přerušení v CPL = 3 a přenáší řízení na CPL = 0, použije se TSS k extrahování SS0 a ESP0 / RSP0 pro přepínač zásobníku. Pokud registr úloh obsahuje špatný selektor TSS, bude vygenerována chyba #TS. Výjimka Invalid TSS by se nikdy neměla stát během normálního provozu operačního systému a vždy souvisí s chybami jádra nebo selháním hardwaru.
Více podrobností o výjimkách TSS najdete ve svazku 3a, kapitole 6 dokumentu IA-32 manuál.[3]
TSS v režimu x86-64
The x86-64 architektura nepodporuje hardwarové přepínače úloh. TSS však lze stále použít ve stroji běžícím v 64bitových rozšířených režimech. V těchto režimech je TSS stále užitečný, protože ukládá:
- Adresy ukazatele zásobníku pro každou úroveň oprávnění.
- Adresy ukazatele pro tabulku přerušení zásobníku (výše uvedená část ukazatele zásobníku na vnitřní úrovni popisuje potřebu tohoto).
- Offsetová adresa bitmapy oprávnění IO.
Registr úloh je v těchto režimech také rozšířen, aby bylo možné uchovávat 64bitovou základní adresu.
Reference
- ^ Bovet, Daniel Pierre; Cesatí, Marco (2006). Porozumění jádru Linuxu, třetí vydání. O'Reilly Media. p. 104. ISBN 978-0-596-00565-8. Citováno 2009-11-23.
- ^ Daniel P. Bovet; Marco Cesati (2006). Porozumění jádru Linuxu. books.google.com. O'Reilly. p. 104. ISBN 9780596554910. Citováno 2014-02-25.
- ^ „Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3a“. Citováno 21. května 2012.