Segmentace paměti
Segmentace je v informatice metoda správy paměti, kdy je procesu vytvořen virtuální adresní prostor začínající od nuly, čímž odpadá potřeba relokace použitého strojového kódu. Strojové instrukce používají pro adresaci logické adresy (offset). Fyzická adresa operační paměti je získána součtem segment registru a offsetu. Ve většině případů používá každý proces více segmentů, přičemž obsah jednotlivých segmentů odpovídá struktuře paměťového prostoru procesu.
Popis
Ve víceúlohovém systému, který využívá multitasking, je nutné umístit do paměti více procesů najednou. Pokud jsou k dispozici nástroje na virtualizaci paměti, lze vytvořit každému z procesů jeho vlastní adresní prostor, který bude začínat od nuly. Každý proces (resp. jeho strojové instrukce) pak bude pracovat s logickými (virtuálními) adresami, které budou vyjadřovat vzdálenost od začátku tohoto vlastního vyhrazeného adresního prostoru (tj. logická adresa bude pro každý proces začínat od nuly). Logické adresy používané strojovými instrukcemi jsou pak v případě přístupů do paměti automaticky překládány pomocí MMU procesoru na fyzické adresy a zpět.
Segmentace používá pro vytvoření logické (virtuální) adresy dva speciální registry – segment a offset, přičemž jejich součet vyjadřuje fyzickou adresu. Segment se nastaví předem (tzv. bázová adresa). Strojové instrukce pak pracují pouze s offsetem (logickou adresou), která vyjadřuje vzdálenost od bázové adresy (segmentu). Segmentový registr je typicky procesu nepřístupný, nastavuje ho operační systém v privilegovaném režimu. Operační systém tak může bez vědomí procesu segment přemístit (např. při tzv. setřásání segmentů), protože logické adresy (offsety) se při přemístění nezmění (viz níže).
Každý proces má k dispozici typicky více segmentů, které odpovídají logickému členění adresního prostoru procesu (např. kód programu, knihovny, data, zásobník, halda). Pro přístup do každého z těchto segmentů musí být k dispozici segmentový registr, který uchovává informaci o začátku segmentu. Nepoužívané segmenty mohou být odloženy z paměti na pevný disk (tzv. swapování) – viz virtuální paměť.
Ochrana paměti
Ochrana paměti je zajištěna mezním registrem na offset (procesor nedovolí použít offset větší, než je hodnota v mezním registru). Změna mezního registru a segment registru je privilegovaná instrukce, takže ji může provést pouze jádro operačního systému. Běžící proces tedy může v neprivilegovaném stavu volně pracovat pouze s offsetem. Pokusí-li se proces běžící v neprivilegovaném režimu provést privilegovanou instrukci (tj. změnu segmentu nebo mezního registru), vyvolá procesor vnitřní přerušení (přičemž obsluha přerušení se nachází uvnitř jádra operačního systému), které tak může dotyčný proces okamžitě ukončit.
Fragmentace volného místa
Při používání segmentace dochází postupně k fragmentaci volného místa v paměti, kdy je volná paměť rozdělena na více částí, které vznikly uvolněním některých segmentů. Kvůli fragmentaci volného místa nelze vyplnit požadavky procesů na alokaci další paměti nebo pro spuštění dalšího procesu, který má nároky menší, než je součet volného místa, avšak požadované volné místo není k dispozici v souvislém úseku. Pokud segmentový registr spravuje operační systém a procesy (resp. strojové instrukce) používají volně výhradně offset, může být volná paměť defragmentována tzv. setřásáním segmentů, kdy jsou vybrané segmenty nakopírovány na jiná místa v paměti tak, aby došlo ke spojení fragmentovaných volných částí paměti do souvislého úseku. Při kopírování celého segmentu nedojde ke změnám v offsetech, změní se pouze segment registr, který spravuje (a nastavuje) jádro operačního systému. Po překopírování je opravena tabulka dotčených segmentů vedená jádrem.
Kopírování segmentů v paměti je velmi náročné na systémové zdroje počítače, a proto je fragmentace jednou z důležitých nevýhod segmentace.
Existující implementace
Segmentace procesorů 80286+
Segmentace v chráněném režimu na procesorech x86 od Intel 80286 výše vykazuje znaky připomínající reálný mód. Segmentace je povinná a pokud je zapnuto stránkování paměti, provádí se před ním, tedy virtuální adresa se segmentací překládá na lineární adresu, která se stránkováním překládá na fyzickou adresu.
Virtuální adresa se skládá ze dvou částí: selektor segmentu a offset. Selektor obsahuje tři příznakové bity a index do tabulky GDT (global descriptor table) nebo LDT (local descriptor table). Selektor je uložen v segmentovém registru, kromě něj obsahuje segmentový registr i „cache“ příslušného řádku z GDT nebo LDT (zvaného descriptor) pro rychlejší vyhodnocování (k této cache nelze programově přistupovat, proto se říká že se nachází v neviditelné části registru).
Selektor
- Horních 13 bitů selektoru je indexem do tabulky deskriptorů.
- Další bit určuje zda se bude hledat v GDT nebo LDT.
- Dva poslední nejnižší bity určují úroveň oprávnění segmetu.
Když se segmentový registr naplní selektorem nahraje se do jeho neviditelné části deskriptor na který daný selektor v tabulce ukazoval.
Deskriptor
- 32bitová báze (Počáteční adresa daného segmentu), rozdělená na dolních 24 bitů a horních 8 bitů (Intel 80286 neměl horní část).
- 20bitový limit segmentu
- Příznaky:
- bit „Granularity“ (značí se G)
- Pokud je G=0 20bitový limit se počítá po bajtech, tzn.:Limit = 20 bitů = 1048575*bajt = ±1 MB segment bude mít tedy limit 1MB.
- Pokud bude G=1 tak se limit počítá po 4 KB, tzn.:Limit = 20 bitů = 1048575*Kb = ±4096 MB segment bude tedy mít limit 4GB.
- typ segmentu (kódový, datový, systémový)
- přístupová práva segmentu (READ/WRITE/EXECUTE – kombinace WRITE a EXECUTE je ovšem nenastavitelná).
- bit „Granularity“ (značí se G)
Tabulky deskriptorů
Tabulek deskriptorů může být více. Kromě IDT, která se používá pro interrupty a se segmentací nesouvisí, existuje však pouze jedna kořenová nazvána GDT. Její přímá adresa a limit (limit velikosti tabulky) je v registru GDTR. Je to jediná přímo viditelná přímá adresa v celém systému. Jinak se adresuje jedině přes selektory a deskriptory. V GDT se nachází globální segmety kódové (.code) i datové (.data) a rovněž deskriptor popisující tabulky LDT. Například každý proces může mít svou vlastní tabulku LDT. Dalším deskriptorem v tabulce GDT je TSS (Task State Segment). Do TSS se ukládájí obsahy registrů procesu při přepínání kontextu u multitaskingu. Je to jakási pomyslná záloha běžícího procesu. Existuje ještě deskriptor brány. Ten se používá pokud chce nějaký méně privilegovaný proces přistoupit k paměti s vyššími privilegii. Číslo 0 znamená nejvyšší privilegia a 3 nejnižší privilegia. Např.: Jádro OS běží jako ring 0 a uživatelské programy pod ring 3.
V tabulce LDT příslušného procesu jsou uložené deskriptory daného procesu, který tabulku vlastní. Je to jednoduché, pokud chcete přeložit logickou adresu na lineární, je třeba nahrát do segmentového registru příslušný selektor, kterým se budeme odkazovat v tabulce (LDT/GDT) najdeme si příslušnou 32bitovou bázovou adresu segmentu, který se snažíme zaadresovat. Naše bázová adresa se sečte s adresou efektivní (představte si jako offset v poli) a tím vzniká adresa lineární. Pokud je daný offset větší než je limit segmentu, procesor vyvolá výjimku (druh přerušení), na kterou operační systém obvykle reaguje hlášením chyby aplikaci (v systémech UNIXového typu signálem SIGSEGV) a v případě neošetření ukončením aplikace.