Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
statnice:bakalar:b4b35osy [2025/06/02 15:45] – [Jak se deadlocku vyhnout] mistrjirka | statnice:bakalar:b4b35osy [2025/06/09 20:32] (current) – [5. Souborové systémy] zapleka3 | ||
---|---|---|---|
Line 11: | Line 11: | ||
* **Virtualizace** – softwarová virtualizace, | * **Virtualizace** – softwarová virtualizace, | ||
- | ===== Systémová volání ===== | + | ===== 1. Systémová volání ===== |
** jak je implementována ochrana paměti jádra, jak se předávají parametry a data ze systémových volání, rozdíl mezi mikro jádrem a monolitickým jádrem. ** | ** jak je implementována ochrana paměti jádra, jak se předávají parametry a data ze systémových volání, rozdíl mezi mikro jádrem a monolitickým jádrem. ** | ||
Systémová volání jsou rozhraní mezi uživatelským a jádrovým režimem. Umožňují uživatelským aplikacím komunikovat s jádrem operačního systému a využívat jeho služby. Systémová volání se obvykle implementují pomocí přerušení nebo speciálních instrukcí (SYSCALL či SYSENTER), které přepínají procesor do jádrového režimu. | Systémová volání jsou rozhraní mezi uživatelským a jádrovým režimem. Umožňují uživatelským aplikacím komunikovat s jádrem operačního systému a využívat jeho služby. Systémová volání se obvykle implementují pomocí přerušení nebo speciálních instrukcí (SYSCALL či SYSENTER), které přepínají procesor do jádrového režimu. | ||
+ | |||
==== Jak se volají systémová volání ==== | ==== Jak se volají systémová volání ==== | ||
- | Jádro implementuje tzv ABI (Application Binary Interface), což je rozhraní, které definuje, jakým způsobem se volají systémová volání a jak se předávají parametry. | + | Jádro implementuje tzv. **ABI (Application Binary Interface)**, což je rozhraní, které definuje, jakým způsobem se volají systémová volání a jak se předávají parametry. |
- | Systémová volání mají čísla, která se uloží do registru (např. EAX v x86 architektuře) a parametry se předávají pomocí dalších registrů nebo na zásobník. Po provedení systémového volání jádro vrátí výsledek do registru a přepne procesor zpět do uživatelského | + | Systémová volání mají čísla, která se uloží do registru (např. |
- | režimu. | + | Pokud potřebujeme předat |
- | Pokud potřebujeme předat | + | |
+ | ==== Předávání parametrů a návratových hodnot ==== | ||
+ | Parametry systémového volání se předávají různými způsoby podle architektury a konkrétního API: | ||
+ | |||
+ | * **Jednoduché hodnoty** (čísla, příznaky, velikosti atd.) se ukládají do registrů – např. v Linuxu na x86-64 se používají registry **rdi, rsi, rdx, r10, r8, r9**. | ||
+ | * **Složitější struktury nebo pole** se předávají pomocí **ukazatelů**, | ||
+ | * **Výsledky systémových volání** se obvykle vrací do jednoho registru (např. **rax**) – typicky návratový kód nebo počet zpracovaných bajtů. V případě chyby se vrací záporný návratový kód (např. `-EINVAL`, `-EPERM`, ...). | ||
+ | |||
+ | **Předávání přes paměť** je bezpečnější, | ||
==== Ochrana paměti jádra ==== | ==== Ochrana paměti jádra ==== | ||
- | Hlavním způsobem ochrany paměti jádra je použití virtuální paměti. Každý proces má svůj vlastní virtuální adresní prostor, což znamená, že každý proces vidí svou vlastní paměť a nemůže přistupovat k paměti jiných procesů nebo jádra. To se provádí pomocí stránkování, | + | Hlavním způsobem ochrany paměti jádra je použití |
+ | |||
+ | V moderních architekturách procesory implementují tzv. **privilegované režimy** (*rings of privilege*). Jádro OS běží | ||
+ | Přechod z uživatelského do jádrového režimu je řízen např. přes systémová volání. | ||
- | V moderních architekturách procesory implementují tzv. **privilegované režimy** (rings of privilege). Jádro OS běží v nejvyšším privilegovaném režimu (např. ring 0 v x86), s plným | + | |
+ | **Pozn.:** Intel v r. 2024 oznámil útlum podpory pro ring 1 a 2 v x86, jelikož je moderní OS nevyužívají. | ||
==== Mikro jádro vs. monolitické jádro ==== | ==== Mikro jádro vs. monolitické jádro ==== | ||
Line 56: | Line 69: | ||
* Některé části jádra jsou implementovány jako samostatné procesy (jako v mikro jádře), zatímco jiné části běží přímo v jádrovém režimu (jako v monolitickém jádře). | * Některé části jádra jsou implementovány jako samostatné procesy (jako v mikro jádře), zatímco jiné části běží přímo v jádrovém režimu (jako v monolitickém jádře). | ||
- | ===== Vlákna a procesy ===== | + | ===== 2. Vlákna a procesy ===== |
**jak se vytvoří proces, jak lze předat data mezi procesy. Jaký je rozdíl mezi vlákny a procesy, která data sdílejí různá vlákna jednoho procesu (registry, zásobník, lokální proměnné, globální proměnné, dynamicky alokované proměnné)** | **jak se vytvoří proces, jak lze předat data mezi procesy. Jaký je rozdíl mezi vlákny a procesy, která data sdílejí různá vlákna jednoho procesu (registry, zásobník, lokální proměnné, globální proměnné, dynamicky alokované proměnné)** | ||
Line 69: | Line 82: | ||
* Tradiční „monolitický“ proces = proces s jediným vláknem. | * Tradiční „monolitický“ proces = proces s jediným vláknem. | ||
* **Stavy vlákna:** Running (běží), Ready (připravené), | * **Stavy vlákna:** Running (běží), Ready (připravené), | ||
- | * Přepnutí (context switch) uloží | + | * Přepnutí (context switch) uloží |
* OS plánuje vlákna podobně jako procesy; implementace může být kernel-level, | * OS plánuje vlákna podobně jako procesy; implementace může být kernel-level, | ||
Line 84: | Line 97: | ||
| Kategorie | | Kategorie | ||
- | | Kód (text) & globální data | ✔ | ✖ | | + | |----------------------------------|-----------------------|-----------------------| |
- | | Heap (dynamicky alokovaná paměť) | + | | Kód (text) & globální data |
- | | Otevřené popisovače souborů | + | | Heap (dynamicky alokovaná paměť) | ✔ |
- | | Programový čítač & registry | + | | Otevřené popisovače souborů |
- | | Zásobník (stack) | + | | Programový čítač & registry |
- | | Thread-local storage (TLS) | ✖ | ✔ | | + | | Zásobník (stack) |
+ | | Thread-local storage (TLS) | ||
+ | **Přednosti: | ||
+ | * Vlákno se vytvoří i ukončí rychleji než proces. | ||
+ | * Přepínání mezi vlákny je rychlejší než mezi procesy. | ||
+ | * Dosáhne se lepší strukturalizace programu. | ||
- | < | + | **Realizace: |
- | **Přednosti**: | + | * knihovna |
- | - Vlákno se vytvoří i ukončí rychleji než proces | + | * v jazyce Java pomocí třídy **Thread** |
- | - Přepínání mezi vlákny je rychlejší než mezi procesy | + | |
- | - Dosáhne se lepší strukturalizace programu | + | |
- | Realizace: - knihovna PThread, Java - třída Thread | ||
- | |||
- | </ | ||
==== Procesy ==== | ==== Procesy ==== | ||
- | < | + | * **Program** |
- | **Program**: | + | |
- | - je soubor (např. na disku) | + | * má vlastní virtuální adresní |
- | + | * může obsahovat | |
- | **Proces**: | + | |
- | - je spuštěný program | + | * paměť |
- | - je charakterizovaný svým paměťovým prostorem a kontextem (prostor | + | |
- | - může vlastnit (kontext obsahuje položky pro) otevřené soubory, | + | |
- | - obsahuje jedno či více vláken | + | |
- | + | ||
- | Proces | + | |
- | + | ||
- | **Co tvoří proces:** | + | |
- | - Obsahy registrů procesoru (čítač instrukcí, ukazatel zásobníku, | + | |
- | - Otevřené soubory | + | |
- | - Použitá | + | |
- | Rodič vytváří nový proces (potomka) voláním služby **fork** - vznikne identická kopie rodičovského procesu až na: | + | * Proces je objekt s vlastním kontextem: |
- | - návratovou hodnotu systémového volání | + | * registry procesoru (čítač instrukcí, ukazatel zásobníku, |
- | - hodnotu PID, PPID – číslo rodičovského procesu | + | |
+ | | ||
+ | | ||
+ | * použitá paměť: Zásobník – .stack, Data – .data, Program – .text | ||
- | návratová hodnota určuje, kdo je potomek | + | ==== Vytváření procesů |
- | potomek | + | * Proces vytváří nový proces voláním systémového volání **fork()**. |
- | </ | + | * vznikne téměř identická kopie rodičovského procesu. |
- | **Stavy** | + | * rozdíly: návratová hodnota |
+ | * Dítě | ||
+ | * Předání dat mezi procesy: | ||
+ | * pomocí | ||
+ | * **potrubí (pipes)** – unidirekcionální datový tok | ||
+ | * **sockets** – obousměrná komunikace, i mezi různými stroji | ||
+ | * **signály** – pro jednoduchou asynchronní notifikaci | ||
+ | * **souborový systém** – zápis do souboru čitelný jiným procesem | ||
+ | ==== Stavy procesů ==== | ||
{{: | {{: | ||
- | Přepnutí | + | * Přepnutí |
- | + | * Proces může | |
- | **Meziprocesní komunikace** | + | |
+ | ==== Meziprocesní komunikace ==== | ||
{{: | {{: | ||
+ | * IPC je klíčová pro spolupráci procesů. | ||
+ | * Výběr prostředku závisí na požadavcích (rychlost, bezpečnost, | ||
- | ===== Synchronizace vláken ===== | + | |
+ | ===== 3. Synchronizace vláken ===== | ||
**jaké jsou problémy při paralelním přístupu ke sdíleným datům, jaké existují synchronizační prostředky, | **jaké jsou problémy při paralelním přístupu ke sdíleným datům, jaké existují synchronizační prostředky, | ||
Line 146: | Line 163: | ||
* Data race – situace, kdy výsledek operace závisí na pořadí provedení vláken, což může vést k nečekaným výsledkům. | * Data race – situace, kdy výsledek operace závisí na pořadí provedení vláken, což může vést k nečekaným výsledkům. | ||
* False sharing – situace, kdy více vláken přistupuje k různým částem stejného cache řádku, což může vést k neefektivnímu využití cache a snížení výkonu. (není kritické, ale může hodně zpomalit) | * False sharing – situace, kdy více vláken přistupuje k různým částem stejného cache řádku, což může vést k neefektivnímu využití cache a snížení výkonu. (není kritické, ale může hodně zpomalit) | ||
+ | |||
+ | ==== Problémy při paralelním přístupu ==== | ||
+ | * **Deadlock** – situace, kdy dva nebo více procesů čeká na uvolnění zdrojů, které jsou drženy jinými, a žádný nemůže pokračovat. | ||
+ | * **Data race** – výsledek výpočtu závisí na pořadí přístupu k proměnným → nekonzistentní chování. | ||
+ | * **False sharing** – více vláken přistupuje k různým částem stejného cache-řádku → výkonnostní problém (neporušuje správnost, ale zpomaluje). | ||
==== Deadlock ==== | ==== Deadlock ==== | ||
- | < | + | Deadlock (uváznutí) nastává, když skupina vláken čeká na zdroje způsobem, |
- | **Deadlock** (uváznutí) nastává, když skupina | + | |
- | Formálně se musí současně vyskytnout **čtyři Coffmanovy podmínky**: | + | |
- | 1. **Vzájemné vyloučení | + | **Coffmanovy podmínky pro vznik deadlocku: |
- | 2. **Hold-and-Wait** – proces | + | - **Vzájemné vyloučení** – zdroj může držet jen jedno vlákno. |
- | 3. **Neodnímatelnost | + | - **Hold and wait** – vlákno |
- | 4. **Cyklické čekání | + | - **Neodnímatelnost** – zdroje nelze násilně odebrat. |
+ | | ||
Pokud všechny čtyři podmínky platí zároveň, vznikne deadlock. | Pokud všechny čtyři podmínky platí zároveň, vznikne deadlock. | ||
- | + | **Jak se deadlocku vyhnout:** | |
- | + | * **Prevence** – např. | |
- | ### Jak se deadlocku vyhnout | + | * **Vyhýbání (Avoidance)** |
- | * **Prevence:** zrušit některou z Coffmanových podmínek | + | * **Detekce + obnova** – detekce cyklů v grafu čekání; obnova |
- | * **Vyhýbání (Avoidance):** algoritmus | + | |
- | * **Detekce + Obnova:** periodicky procházet graf přidělení/ | + | |
- | + | ||
- | </ | + | |
< | < | ||
Line 198: | Line 215: | ||
\end{document} | \end{document} | ||
</ | </ | ||
+ | |||
==== Synchronizační prostředky ==== | ==== Synchronizační prostředky ==== | ||
- | < | ||
- | * **Mutex (mutual exclusion)** – zámek, který umožňuje pouze jednomu vláknu přístup do kritické sekce. Pokud jedno vlákno zámek získá, ostatní musí čekat, dokud ho neuvolní. | ||
- | * **Semafor** – základní vlastností je celočíselná proměnná. Dvě základní operace: | + | |
- | * **wait** – čeká, pokud je hodnota ≤ 0, poté snižuje hodnotu semaforu (pro vstup do kritické sekce). | + | |
- | * **signal** – zvyšuje hodnotu semaforu a probouzí čekající | + | |
- | * Na rozdíl od mutexu může semafor zařídit, že se vlákno *vždy* | + | |
- | * **Podmínkové proměnné (condition variables)** – synchronizační objekt určený k „čekání na stav“. | + | |
- | * **Princip:** vlákno | + | * **wait** – pokud je hodnota ≤ 0, vlákno |
- | | + | * **signal** – zvýší hodnotu a probudí čekající vlákno, pokud existuje. |
- | | + | |
- | * **Hlavní operace** (`pthread` API): | + | |
- | | Operace | Efekt | | + | * **Podmínkové proměnné (condition variables)** – slouží k čekání na konkrétní stav: |
- | | + | |
- | | + | |
- | | + | * Po splnění predikátu může jiné vlákno zavolat `signal` (probudí jedno) nebo `broadcast` (všechna). |
- | | + | |
+ | * **Hlavní operace (`pthread` API):** | ||
+ | * `pthread_cond_wait(& | ||
+ | | ||
+ | | ||
* **Spurious wake-ups:** vlákno se může probudit i bez `signal` → **vždy testuj predikát v `while` smyčce**, ne v `if`. | * **Spurious wake-ups:** vlákno se může probudit i bez `signal` → **vždy testuj predikát v `while` smyčce**, ne v `if`. | ||
- | ```c | + | < |
- | pthread_mutex_lock(& | + | pthread_mutex_lock(& |
- | while (queue_empty) | + | while (queue_empty) |
- | pthread_cond_wait(& | + | pthread_cond_wait(& |
- | dequeue_item(); | + | dequeue_item(); |
- | pthread_mutex_unlock(& | + | pthread_mutex_unlock(& |
- | ``` | + | </ |
* **Rozdíl vůči semaforu: | * **Rozdíl vůči semaforu: | ||
Line 241: | Line 257: | ||
* **Nevýhody: | * **Nevýhody: | ||
- | * **Spin-lock** – zámek, který místo uspání **aktivně točí procesor** (busy-wait), | + | |
+ | * **Princip (krok za krokem)** | ||
+ | * **Sdílená proměnná `lock`** je inicializována na `0` = neobsazeno. | ||
+ | * Vlákno provede ***atomickou*** instrukci `test-and-set` (TAS) nebo `compare-and-swap` (CAS) | ||
+ | * **Výsledek atomické operace** | ||
+ | * návratová 0 → zámek byl volný, vlákno ho právě získalo ⇒ vstup do kritické sekce; | ||
+ | * návratová 1 → zámek je držen někým jiným ⇒ vlákno **spinuje**: | ||
+ | * **Uvolnění**: | ||
+ | * U vícejádrových CPU se přidá *release memory fence* (`mfence`, `std:: | ||
+ | |||
+ | **TAS**: „ulož do `lock` hodnotu 1 **a vrať mi předchozí obsah**“. | ||
+ | <code c> | ||
+ | tas: | ||
+ | xchg %eax, lock ; ATOMICKY vyměním registr ↔ paměť | ||
+ | ; pokud %eax == 0 → zámek byl volný a mám ho | ||
+ | </ | ||
- | | + | **CAS**: „pokud je `lock == 0`, zapiš 1; jinak nedělej nic a dej mi současnou hodnotu“. |
- | 1. **Sdílená proměnná `lock`** je inicializována na `0` = neobsazeno. | + | < |
- | 2. Vlákno provede ***atomickou*** instrukci `test-and-set` (TAS) nebo `compare-and-swap` (CAS): | + | bool acquired = __sync_bool_compare_and_swap(& |
- | | + | </ |
- | | + | Tyto instrukce jsou **atomické**, |
- | | + | |
- | xchg %eax, lock ; ATOMICKY vyměním registr ↔ paměť | + | |
- | ; pokud %eax == 0 → zámek byl volný a mám ho | + | |
- | | + | |
- | - *CAS*: „pokud je `lock == 0`, zapiš 1; jinak nedělej nic a dej mi současnou hodnotu“. | + | |
- | ```c | + | |
- | | + | |
- | ``` | + | |
- | | + | |
- | 3. **Výsledek atomické operace** | + | |
- | - návratová 0 → zámek byl volný, vlákno ho právě získalo ⇒ vstup do kritické sekce; | + | |
- | - návratová 1 → zámek je držen někým jiným ⇒ vlákno **spinuje**: | + | |
- | 4. **Uvolnění**: | + | |
- | - U vícejádrových CPU se přidá *release memory fence* (`mfence`, `std:: | + | |
* **Proč „atomické nastavení“? | * **Proč „atomické nastavení“? | ||
- | | + | |
- | | + | |
* **Kdy se vyplatí** | * **Kdy se vyplatí** | ||
- | | + | |
- | | + | |
- | | + | |
* **Nevýhody / na co si dát pozor** | * **Nevýhody / na co si dát pozor** | ||
- | | + | |
- | | + | |
- | | + | |
- | * **Monitor** – „třída + vestavěný zámek + čekací fronta“, která **zapouzdřuje sdílená data a pravidla používání**: | + | |
- | * Voláš-li *veřejnou metodu* monitoru, **vstupuješ do monitoru** – systém ti **automaticky zamkne vnitřní mutex**. | + | |
- | Žádné jiné vlákno se dovnitř nedostane, dokud z metody nevrátíš – tím se zámek zase uvolní. | + | |
- | → Všechny změny dat uvnitř monitoru jsou atomické vůči ostatním vláknům. | + | |
- | * Potřebuje-li metoda čekat na nějaký **stav** (např. „fronta není prázdná“), | + | |
- | - vlákno se přesune do **čekací fronty** dané podmínky a **současně opustí monitor** (uvolní vnitřní zámek), | + | |
- | - jiná vlákna mohou stav změnit. | + | |
- | Když někdo zavolá `signal(cond)`, | + | |
- | * Důsledek: **uživatel monitoru nikdy ručně nemanipuluje se zámkem ani s podmínkovými proměnnými** – ty jsou schované „pod kapotou“. | + | |
- | Programátor píše jen logiku metod a test predikátů. | + | |
- | * **Rozdíl proti „mutex + podmínková proměnná“ samostatně: | + | |
- | - s monitorem nemůžeš omylem zapomenout zámek odemknout nebo přistoupit k datům bez ochrany; | + | |
- | - data jsou *soukromá*, | + | |
- | V podstatě jde o **bezpečnější a samo-dokumentující obal** nad dvojicí „mutex + cond-var“. | + | |
- | </ | + | |
- | ===== Správa virtuální a fyzické paměti ===== | + | * **Monitor** – „třída + vestavěný zámek + čekací fronta“, která **zapouzdřuje sdílená data a pravidla používání**: |
+ | * Voláš-li *veřejnou metodu* monitoru, **vstupuješ do monitoru** – systém ti **automaticky zamkne vnitřní mutex**. | ||
+ | * Žádné jiné vlákno se dovnitř nedostane, dokud z metody nevrátíš – tím se zámek zase uvolní. | ||
+ | * Všechny změny dat uvnitř monitoru jsou atomické vůči ostatním vláknům. | ||
+ | * Potřebuje-li metoda čekat na nějaký **stav** (např. „fronta není prázdná“), | ||
+ | * vlákno se přesune do **čekací fronty** dané podmínky a **současně opustí monitor** (uvolní vnitřní zámek), | ||
+ | * jiná vlákna mohou stav změnit. | ||
+ | * Když někdo zavolá `signal(cond)`, | ||
+ | * Důsledek: **uživatel monitoru nikdy ručně nemanipuluje se zámkem ani s podmínkovými proměnnými** – ty jsou schované „pod kapotou“. | ||
+ | * Programátor píše jen logiku metod a test predikátů. | ||
+ | * **Rozdíl proti „mutex + podmínková proměnná“ samostatně: | ||
+ | * s monitorem nemůžeš omylem zapomenout zámek odemknout nebo přistoupit k datům bez ochrany; | ||
+ | * data jsou *soukromá*, | ||
+ | * V podstatě jde o **bezpečnější a samo-dokumentující obal** nad dvojicí „mutex + cond-var“. | ||
+ | |||
+ | ===== 4. Správa virtuální a fyzické paměti ===== | ||
* co je a jak vypadá stránkovací tabulka, jaké jsou zásadní nevýhody stránkování, | * co je a jak vypadá stránkovací tabulka, jaké jsou zásadní nevýhody stránkování, | ||
==== Názvosloví ==== | ==== Názvosloví ==== | ||
- | ** FAP ** – Fyzický adresní prostor, skutečná paměť počítače, velikost | + | * **FAP** – Fyzický adresní prostor, skutečná paměť počítače; její velikost |
- | ** LAP ** - Logický adresní prostor, | + | |
- | * 32-bit: 4 GiB (2^32) | + | * Adresy v LAP jsou překládány OS na odpovídající místa ve FAP pomocí tabulek stránek a dalších struktur. |
- | * 64-bit: 16 EiB (2^64) – v praxi omezeno na 256 TiB (2^48) kvůli TLB a stránkovacím tabulkám | + | * Velikost LAP závisí na architektuře |
+ | * 32-bit: 4 GiB (2³²) – většinou celý prostor nelze využít kvůli dělení jádra a uživatelského prostoru. | ||
+ | * 64-bit: | ||
+ | |||
+ | ==== Segmentace ==== | ||
+ | * Segmentace je jedna z metod správy paměti, kde se paměť dělí na logické bloky – **segmenty** (např. pro kód, data, zásobník). | ||
+ | * Adresy v programu jsou tzv. **selektory**, | ||
+ | * Segmentový záznam obsahuje: základní adresu, délku segmentu, přístupová práva. | ||
+ | * Procesor pak fyzickou adresu vypočítá jako: `fyzická adresa = základna segmentu + offset`. | ||
- | ==== Segmentace ==== | ||
- | V programu používáme adresy zvané " | ||
{{statnice: | {{statnice: | ||
- | < | + | **Výhody segmentace** |
+ | * Délka segmentu odpovídá skutečné potřebě – **úspora paměti** (menší vnitřní fragmentace). | ||
+ | * Při přístupu mimo segment dojde k **výjimce** – typicky **segmentation fault**. | ||
+ | * Přesuny v paměti jsou **transparentní** – změna základny segmentu neovlivní kód procesu. | ||
+ | * Každý segment může mít samostatná **přístupová práva** – lepší ochrana paměti (např. nelze spustit data). | ||
- | Výhody segmentace | + | **Nevýhody segmentace** |
- | - Segment má délku uzpůsobenou skutečné potřebě | + | |
- | - minimum vnitřní fragmentace | + | |
- | - Lze detekovat přístup mimo segment, který způsobí chybu segmentace – výjimku typu „segmentation fault“ | + | * Větší **režie při přístupu do paměti** – nutnost kontroly segmentového záznamu a výpočtu fyzické adresy. |
- | - Lze nastavovat práva k přístupu do segmentu | + | |
- | - Lze pohybovat s daty i programem v fyzické paměti – posun počátku segmentu je pro aplikační proces neviditelný a nedetekovatelný | + | |
- | + | ||
- | Nevýhody segmentace | + | |
- | - Alokace | + | |
- | - Segmenty | + | |
- | | + | |
- | - Režie při přístupu do paměti | + | |
- | + | ||
- | **Fragmentace** | + | |
- | *Externí (vnější) fragmentace* – Celkové množství volné paměti je sice dostatečné, aby uspokojilo požadavek procesu, avšak prostor není souvislý, takže ho nelze přidělit. | + | |
- | *Interní (vnitřní) fragmentace* – Přidělená díra v paměti je o málo větší než potřebná, avšak zbytek je tak malý, že ho nelze využít. | + | |
- | </ | + | |
+ | **Fragmentace** | ||
+ | * *Externí (vnější)* – V paměti je dost místa, ale rozděleného na malé části – **nelze přidělit větší blok**. | ||
+ | * *Interní (vnitřní)* – Segment je větší, než proces reálně potřebuje → vzniká **nevyužitý zbytek** uvnitř segmentu. | ||
==== Stránkování ==== | ==== Stránkování ==== | ||
- | < | ||
- | **Stránkování** (paging) rozděluje logický adresní prostor procesu na pevně velké bloky – **stránky** | + | **Stránkování** (paging) rozděluje logický adresní prostor procesu na pevně velké bloky – **stránky**, a fyzickou paměť na stejně velké **rámce** (frames). |
- | </ | + | * Překlad stránka → rámec zajišťují **stránkovací tabulky**, které spravuje jádro; hardwarová jednotka MMU je využívá k překladu adres. |
=== Základní pojmy === | === Základní pojmy === | ||
- | < | ||
- | - **Velikost stránky** – 4 KiB na x86 / ARM (často | + | * **Velikost stránky** – obvykle |
- | - **Page Frame Number (PFN)** – index rámce ve fyzické paměti. | + | * **Page Frame Number (PFN)** – index rámce ve fyzické paměti. |
- | - **Virtuální adresa** = ⟨index stránky, offset ve stránce⟩. | + | |
- | - **Page fault** – přerušení při přístupu na stránku, která není (zatím) namapována do RAM. | + | |
- | </markdown> | + | |
+ | === Stránkovací tabulka === | ||
+ | |||
+ | * Každý proces má svou **stránkovací tabulku** – strukturu mapující virtuální adresy na fyzické rámce. | ||
+ | * Záznam o stránce obsahuje např.: | ||
+ | * PFN cílového rámce (pokud je stránka přítomná), | ||
+ | * přístupová práva (RWX), | ||
+ | * příznaky (valid/dirty/ | ||
+ | * info pro cache / TLB. | ||
+ | * V moderních architekturách (např. x86_64) je tabulka **víceúrovňová** (typicky 4 nebo 5 úrovní) – pro každou část adresy existuje jedna tabulka. | ||
=== Eliminace externí fragmentace === | === Eliminace externí fragmentace === | ||
- | < | ||
- | - Fyzická paměť je rozdělena na **stejně velké rámce** – OS udržuje | + | * Fyzická paměť je rozdělena na **stejně velké rámce** – OS udržuje bitmapu nebo volný seznam. |
- | - Jakákoli | + | * Každá |
- | - Zbytková nevyužitá paměť se omezuje jen na *vnitřní* | + | * Vzniká pouze **vnitřní |
- | - Oproti | + | |
- | - Díky jednotné velikosti rámců i stránek je výběr volného | + | |
- | </ | + | |
=== Překlad adresy – krok za krokem === | === Překlad adresy – krok za krokem === | ||
- | < | ||
- | 1. **TLB lookup** – MMU hledá | + | - **TLB lookup** – MMU nejprve |
- | 2. **Miss v TLB** ⇒ hardware čte položku | + | |
- | 3. Pokud tabulky | + | |
- | </ | + | * jádro zvolí volný |
+ | * načte požadovanou stránku | ||
+ | * aktualizuje tabulku | ||
- | === Víceúrovňové tabulky | + | === Nevýhody stránkování |
- | < | + | |
- | | Architektura | Úrovně | Dekompozice virtuální adresy (příklady) | | + | * **Vícenásobný |
- | |--------------|-------|-----------------------------------------| | + | * **Vnitřní fragmentace** – poslední stránka segmentu často není plně využita. |
- | | **x86 32-bit** | 2 (PDE, PTE) | 10 bit index PDE • 10 bit index PTE • 12 bit offset | | + | * **TLB thrashing** – pokud pracovní set přesahuje kapacitu TLB, dochází ke zpomalujícím TLB missům. |
- | | **x86-64 (48 bit LAP)** | 4 (PML4, PDPTE, PDE, PTE) | 9 + 9 + 9 + 9 + 12 | | + | * **Správa swappu** přináší I/O režii a může vést ke *thrashingu* celé RAM. |
- | | **x86-64 (57 bit LAP, „5-level“)** | 5 (PML5…) | 9 × 5 + 12 | | + | |
- | > Více úrovní | + | === TLB (Translation Lookaside Buffer) === |
- | </ | + | |
- | === Nevýhody stránkování === | + | * Malá, **plně asociativní cache** překladů Virt → Fyz (desítky až stovky záznamů na CPU jádro). |
- | < | + | * Výrazně zrychluje přístup – při TLB hit není třeba sahat na stránkovací tabulky. |
+ | * **TLB shootdown**: | ||
+ | * **ASID (Address Space ID)** nebo **PCID (Process Context ID)**: | ||
+ | * značka v TLB, která umožňuje udržovat překlady i po přepnutí procesu, | ||
+ | * zabraňuje nutnosti flush TLB při každém context switchi. | ||
- | - **Vícenásobný přístup** na jednu virtuální adresu: TLB miss → až 4–5 čtení z paměti, pak teprve data. | + | === Víceúrovňové tabulky === |
- | - **Vnitřní fragmentace**: | + | |
- | - **TLB thrashing** u pracovních setů větších než TLB. | + | |
- | - **Režie správy swapu** (I/O latence) ⇒ thrashing celé RAM. | + | |
- | </ | + | |
- | === TLB (Translation Lookaside Buffer) === | + | | Architektura |
- | < | + | |----------------------------|----------------------------------|------------------------------------------------| |
+ | | **x86 (32-bit)** | ||
+ | | **x86-64 (48bit LAP)** | ||
+ | | **x86-64 (57bit LAP)** | ||
- | - Malá, plně asociativní cache překladů (desítky až stovky | + | * Každá úroveň odpovídá stránkovací tabulce (page table), která se používá pro překlad |
- | - **Shoot-down**: když kernel změní mapování, musí invalidovat TLB všech CPU (IPI). | + | * Jednotlivé části virtuální adresy slouží jako indexy do těchto tabulek – z každé se vybere |
- | - **ASID/PCID**: značka procesu v TLB zmenšuje nutnost flush při přepnutí procesu. | + | |
- | </ | + | * Díky stránkování stránkovacích tabulek (samy jsou rozděleny na stránky) systém |
+ | * Nejčastější hloubka tabulek dnes je 4 (x86-64), pátá úroveň se používá | ||
=== Odkládání stránek na disk (swapping) === | === Odkládání stránek na disk (swapping) === | ||
- | < | ||
- | - **Swap area** | + | * **Swap area** |
- | - **Lazy** a **demand | + | * **Demand |
- | - **Thrashing**: když se pracovní set nevejde do RAM a proces | + | |
- | </ | + | |
=== Algoritmy výběru oběti (page replacement) === | === Algoritmy výběru oběti (page replacement) === | ||
- | < | ||
- | *„Oběť“ (victim) = stránka/ | ||
- | | Algoritmus | Idea | Poznámky | | + | * „Oběť“ = stránka ve fyzické paměti, kterou kernel vyhodí (nebo uloží do swapu), aby mohl přinést novou stránku (např. po page faultu). |
- | |------------|------|----------| | + | * Cílem je vybrat stránku, která **nebude brzy znovu potřebná**, |
- | | **FIFO** | vyhoď nejstarší stránku | jednoduchý, trpí Beladyho anomálií | | + | |
- | | **Second-Chance (Clock)** | FIFO + 1 bit „referenced“ | linuxový základ | + | | Algoritmus |
- | | **LRU / Aproximované | + | |----------------------------|--------------------------------------|-----------------------------------------------| |
- | | **Working-Set** | drž stránky aktivní v posledním | + | | **FIFO** |
- | | **Adaptive (e.g., ARC)** | kombinuje | + | | **Second-Chance (Clock)** | FIFO s dodatečným bitem „referenced“ | základní Linuxová varianta |
- | </ | + | | **LRU / Approx. |
+ | | **Working-Set** | ||
+ | | **Adaptive (např. ARC)** | ||
=== Copy-On-Write (COW) === | === Copy-On-Write (COW) === | ||
- | < | ||
- | 1. Při `fork()` | + | * Mechanismus pro **efektivní sdílení paměti** mezi procesy. |
- | 2. První | + | * Při volání |
- | - alokuje nový rámec, | + | * Proces **rodič |
- | - zkopíruje obsah původní stránky, | + | * Jakmile jeden z nich provede **zápis**, vyvolá |
- | - přemapuje | + | * Kernel: |
- | 3. Šetří kopírování při `fork+exec`, sdílí read-only data (např. `.text`, | + | * alokuje nový rámec, |
- | </ | + | * zkopíruje obsah původní stránky, |
+ | * přemapuje | ||
+ | * Výhody: | ||
+ | * výrazné **zrychlení | ||
+ | * efektivní **sdílení statických dat** – např. | ||
=== Shrnutí výhod stránkování === | === Shrnutí výhod stránkování === | ||
- | < | ||
- | - **Eliminace externí fragmentace** – všechny rámce mají stejnou velikost, takže OS vždy najde volný rámec bez „děr“; na rozdíl od segmentace není nutná kompakce. | + | * **Eliminace externí fragmentace** – všechny rámce mají stejnou velikost, takže OS vždy najde volný rámec bez „děr“; na rozdíl od segmentace není nutná kompakce. |
- | - Snadný růst haldy/ | + | * **Snadný růst haldy/ |
- | - Izolace procesů – ochranné bity (R/W/X, User/ | + | * **Izolace procesů** – ochranné bity (R/W/X, User/ |
- | - Sdílení kódu a knihoven | + | * **Sdílení kódu a knihoven** – více procesů může mapovat |
- | - Podpora virtuální | + | * **Virtuální |
- | - Mechanismus pro COW, mmap souborů, lazy allocation. | + | * **Podpora moderních technik** – Copy-On-Write, `mmap()` pro soubory, lazy allocation. |
- | Nevýhody (víceúrovňové přístupy, TLB miss, swap latence) se řeší | + | *Nevýhody* (víceúrovňový překlad, TLB missy, latence |
- | </ | + | * větších TLB (ASID/PCID), |
+ | * použití **huge-pages**, | ||
+ | * lepších algoritmů výběru oběti, | ||
+ | * dostatku fyzické paměti (RAM). | ||
- | ===== Souborové systémy ===== | + | ===== 5. Souborové systémy ===== |
- | * jaké typy souborových systémů znáte, který je vhodný pro sekvenční čtení a který pro náhodné čtení souborů. Vysvětlete základní souborové systémy: FAT, systémy založené na inodech a systémy založené na extendech. Žurnálování – základní princip, kdy mohou vzniknout v souborovém systému chyby, jaké jsou úrovně žurnálování a jeho nevýhody. | + | ** jaké typy souborových systémů znáte, který je vhodný pro sekvenční čtení a který pro náhodné čtení souborů. Vysvětlete základní souborové systémy: FAT, systémy založené na inodech a systémy založené na extendech. Žurnálování – základní princip, kdy mohou vzniknout v souborovém systému chyby, jaké jsou úrovně žurnálování a jeho nevýhody.** |
- | FAT, FAT32, exFAT, NTFS, ext2/3/4, btrfs, ZFS | + | Způsob organizace dat na disku – data jsou uložena v souborech, soubory jsou strukturované v adresářích (hierarchická struktura). |
+ | * Souborový systém určuje, jak jsou data fyzicky a logicky organizována, jak se přistupuje ke souborům, jaká metadata jsou vedena apod. | ||
- | možnosti uložení obsahu: | + | ==== Příklady souborových systémů ==== |
- | * uložení souboru jako souvislý úsek bloků | + | |
- | * posobné alokace paměti, rychlý přístup k datům | + | |
- | * způsobuje fragmentaci a nutnost přesunů souborů | + | |
- | * spojové seznamy | + | |
- | * každý blok obsahuje i ukazatel na další blok (adresář obsahuje odkaz na 1. blok) | + | |
- | * výhodné pro sekvenční přístup k souborům, ne pro vše ostatní | + | |
- | * není možné data mapovat přímo z disku | + | |
- | * jeden špatný sektor na disku může způsobit ztrátu celého souboru | + | |
- | * indexové struktury | + | |
- | * indexový blok obsahuje ukazatele na mnoho jiných bloků | + | |
- | * vhodnější pro náhodný přístup, stále poměrně dobré pro sekvenční | + | |
- | * může být potřeba použít více indexových bloků | + | |
+ | * **FAT, FAT32** – jednoduché, | ||
+ | * **exFAT** – nástupce FAT32, podporuje větší soubory a disky, stále bez žurnálu. | ||
+ | * **NTFS** – moderní FS pro Windows, podporuje práva, šifrování, | ||
+ | * **ext2/ | ||
+ | * **Btrfs** – pokročilý FS s podporou snapshotů, kontrolních součtů, RAIDu, dynamické alokace. | ||
+ | * **ZFS** – kombinace FS a správy disků, silné kontroly integrity dat, snapshoty, samoopravné mechanismy. | ||
+ | |||
+ | ==== Možnosti uložení obsahu souboru ==== | ||
+ | |||
+ | * **Souvislý úsek bloků** | ||
+ | * Podobné jako alokace paměti – rychlý sekvenční přístup. | ||
+ | * Nevýhoda: fragmentace a nutnost přesunů při zvětšení souboru. | ||
+ | * Typicky vhodné pro **sekvenční čtení** (např. média, logy). | ||
+ | |||
+ | * **Spojové seznamy** | ||
+ | * Každý blok obsahuje i ukazatel na další blok; adresář obsahuje odkaz na první blok. | ||
+ | * Jednoduchá implementace, | ||
+ | * Nevhodné pro náhodný přístup – nutné projít celý seznam. | ||
+ | * Nemožnost přímého mapování souboru do paměti. | ||
+ | * Jediný poškozený sektor může znepřístupnit celý soubor. | ||
+ | |||
+ | * **Indexové struktury** | ||
+ | * Používá se samostatný **indexový blok**, který obsahuje ukazatele na datové bloky. | ||
+ | * Umožňuje rychlý **náhodný přístup** (random access), stále dobrý i pro sekvenční čtení. | ||
+ | * Při velkých souborech může být potřeba víceúrovňový index. | ||
+ | * Používají např. ext a NTFS. | ||
+ | |||
+ | ==== Základní souborové systémy ==== | ||
=== FAT (File Allocation Table) === | === FAT (File Allocation Table) === | ||
- | * starý | + | * Starý, jednoduchý |
- | * něco mezi spojovými seznamy a indexovou strukturou | + | * Konstrukčně |
- | * základní | + | * Základní |
- | * disk je rozložen na MBR (master boot record, | + | * Maximální |
- | * v tabulce FAT jsou uloženy položky, kdy každá odpovídá jednomu clusteru na disku (hodnota | + | * FAT16: |
- | * nevýhodou je fragmentace, omezená velikost | + | * FAT32: |
+ | * exFAT: | ||
+ | * Disková struktura: | ||
+ | * **MBR** (Master Boot Record) – informace o FS (velikost, jméno, počet FAT tabulek, | ||
+ | * **FAT1, FAT2** – dvě redundantní | ||
+ | * **Root directory** | ||
+ | * **Data** | ||
+ | * V každé položce FAT je číslo následujícího | ||
+ | * Nevýhody: | ||
+ | * silná **fragmentace** | ||
+ | * **sekvenční přístup** k FAT tabulce při čtení souboru | ||
+ | * **omezená velikost | ||
+ | * chybí | ||
=== Inodový souborový systém === | === Inodový souborový systém === | ||
- | * metadata | + | * Metadata |
- | * inode obsahuje | + | * Adresářová |
- | * když je soubor větší než počet odkazů na datové bloky v inode, odkat na další bloky je nepřímo přes blok odkazů | + | * Každý |
+ | * několik přímých | ||
+ | * nepřímé odkazy – jednoduchý, | ||
+ | * Výpočet pozice bloku je snadný – dle offsetu | ||
{{statnice: | {{statnice: | ||
- | rozložení na disku: | + | Rozložení na disku: |
- | * pevný | + | * **Pevný |
- | * v superbloku je uložena | + | * **Superblok** – obsahuje |
- | * kořenový adresář | + | * **Kořenový adresář** – výchozí místo připojení FS. |
- | hledání | + | Hledání |
- | * sekvenčním procházením (neefektivní) | + | * Sekvenční procházení – neefektivní. |
- | * poznání volného místa je obtížné (blok nul může být validní obsah souboru) | + | * Blok s nulou může být validní obsah souboru |
- | * řešení | + | * Řešení: |
- | * místo prohledávání inodů se prohledává tato bitová mapa | + | * **bitové mapy** (bitmapy) pro inode i datové bloky. |
+ | * Vyhledávání je pak rychlé a efektivní. | ||
{{statnice: | {{statnice: | ||
- | ext2-4 | + | ext2/3/4: |
- | * při práci se souborem je potřeba | + | |
- | * disky (hlavně | + | * Při práci se souborem je potřeba |
- | * proto jsou data organizována do skupin, kde se FS snaží alokovt datové bloky ve stejné skupině jako inody | + | * U rotačních disků je výhodné, když jsou bloky blízko sebe. |
+ | * FS dělí disk na **skupiny bloků**, které obsahují | ||
{{statnice: | {{statnice: | ||
=== Extents === | === Extents === | ||
- | * tabulky bloků nejsou efektivní pro obrovské soubory, je potřeba velká režie | ||
- | * moderní FS mohou odkazovat místo na jednotlivé bloky na celé souvislé skupiny bloků | ||
- | * odkazovaná skupina s více než jedním blokem se nazývá extent | ||
- | * implementováno v ext4, NTFS, btrfs | ||
- | | ||
- | {{statnice: | ||
+ | * U velkých souborů je indexace po jednotlivých blocích neefektivní. | ||
+ | * Moderní FS používají **extenty** – odkazy na **souvislé skupiny bloků** (namísto jednotlivých). | ||
+ | * Každý extent: ⟨začátek, | ||
+ | * Výhody: | ||
+ | * Méně režie než při uložení všech odkazů zvlášť. | ||
+ | * Lepší výkon u sekvenčního i náhodného přístupu. | ||
+ | * Používá se např. v **ext4**, **NTFS**, **btrfs**. | ||
+ | |||
+ | {{statnice: | ||
=== Žurnálování === | === Žurnálování === | ||
- | | + | |
- | * pokud dojde k pádu systému, | + | |
- | * implementováno | + | * Pokud dojde k pádu systému, |
+ | * Běžné | ||
{{statnice: | {{statnice: | ||
- | bezpečný způsob | + | Bezpečný postup |
- | - Commit | + | |
- | - Checkpoint | + | |
- | - aktualizace bloků v souborovém systému | + | |
- | - odstranění transakce z žurnálu | + | |
- | Možné scénáře při pádu: | + | |
- | - do žurnálu se zapíše pouze část transakce | + | * **Checkpoint** – změny v inodech, datech, bitových mapách se zapíšou na správná místa na disku. |
- | | + | * Po úspěšném dokončení se transakce **odstraní** ze žurnálu. |
- | | + | |
- | - do žurnálu se zaíše celá transakce, ale neaktualizují se bloky | + | |
- | | + | |
- | - zapíše se celá transakce, aktualizují se bloky ale transakce ze žurnálu není odstraněna | + | |
- | | + | |
- | - do žurnálu se zapíše pouze část transakce (např. $TxB$, $I_\text{v2}$ a $TxE$, bez $B_\text{v2}$ a $D_\text{v2}$) | + | |
- | * problém - HW disků se snaží provádět optimalizace, může změnit pořadí vykonávání příkazů zalaných OS | + | |
- | * OS musí poslat speciální příkaz (bariéry), aby se data skutečně zapsala ve skutečném pořadí (garance vykonání všech příkazů před bariérou před pokračováním) | + | |
- | | + | |
- | nevýhodou je overhead, komplexnost, | + | ==== Scénáře při pádu systému ==== |
- | Flash paměti | + | * **Pouze část transakce** zapsaná do žurnálu: |
- | * zapisovat lze pouze do vymazaného bloku | + | * FS zůstává konzistentní, |
- | * zapsat lze pouze jednou, pak se musí vymazat | + | * OS při startu zjistí neúplnou transakci a ignoruje ji. |
- | * mazací blok bývá větší (např 4 MiB) | + | * **Celá transakce** je v žurnálu, ale **blogy na disku se nezmění**: |
- | * každý blok garantuje pouze určitý početpřepsání (např. | + | * OS je použije k dokončení změn (tzv. *roll-forward*). |
- | * často se měnící data (např. bitmapy, či FAT tabulka) drasticky snižují životnost paměti | + | * **Transakce i bloky jsou zapsány**, ale transakce není odstraněna: |
- | * změna jednoho bytu v souboru znamená smazání a znovu zapsání 4 MiB | + | * OS je znovu aplikuje (*idempotentní* operace – nezmění výsledek, když se provedou víckrát). |
+ | * **Pouze | ||
+ | * Riziko způsobeno optimalizacemi disku – **změna pořadí zápisů**. | ||
+ | * OS musí použít tzv. **write barriers** | ||
+ | * Správná sekvence: `TxB`, `I_v2`, `B_v2`, `D_v2`, *bariéra*, `TxE`. | ||
+ | |||
+ | * **Nevýhody žurnálování**: | ||
+ | * Režie navíc (dvojnásobné zápisy: nejprve do žurnálu, pak do FS). | ||
+ | * Složitost implementace. | ||
+ | * Zpomalení zápisových operací. | ||
- | řešením je nepoužívat | + | === Flash paměti === |
- | * použití speciálních souborových systémů (UBIFS, JFFS2, NILFS) | + | * **Flash bloky** lze pouze přepsat, pokud jsou nejprve **vymazány**. |
+ | * **Zápis je jednorázový** – změna jednoho bajtu znamená smazání celého bloku (např. 4 MiB). | ||
+ | * **Omezený počet přepisů** – typicky 100 000 až 1 000 000 cyklů na blok. | ||
+ | * Často měněná data (bitmapy, FAT tabulky) mohou výrazně zkrátit životnost paměti. | ||
+ | * Důsledkem je **write amplification** – malá změna vyžaduje velkou operaci. | ||
+ | ==== Řešení pro flash paměti ==== | ||
+ | * Nepoužívají se přímo, ale s řadičem, který implementuje **Flash Translation Layer (FTL)**: | ||
+ | * Skryje omezení zápisu, přemapovává fyzické bloky, spravuje wear-leveling. | ||
+ | * Typické u SSD, eMMC, SD karet. | ||
+ | * **Speciální souborové systémy pro flash**: | ||
+ | * **UBIFS** – pro NAND flash, umí journal, garbage collection. | ||
+ | * **JFFS2** – log-strukturovaný, | ||
+ | * **NILFS** – log-based, kontinuální snapshoty, optimalizovaný pro SSD. | ||
- | + | ===== 6. Bezpečnost ===== | |
- | ===== Bezpečnost ===== | + | |
* co je Trusted Computing Base, základní metody řízení přístupu, jak se provádí útok na přetečení zásobníku, | * co je Trusted Computing Base, základní metody řízení přístupu, jak se provádí útok na přetečení zásobníku, | ||
- | === Trusted Computing Base === | + | === Trusted Computing Base (TCB) === |
- | je množina všech | + | * Množina všech |
- | Příklady: hardware, | + | * Pokud selže některá část TCB, **celý |
+ | | ||
=== Základní metody řízení přístupu === | === Základní metody řízení přístupu === | ||
- | Základní princip | + | * Základním teoretickým modelem |
{{statnice: | {{statnice: | ||
- | * Objekty jsou např. | + | * **Subjekty** – např. |
- | * Subjekt je např. | + | * **Objekty** – např. |
- | * Subjekty mohou být zároveň objekty | + | * Subjekty mohou být zároveň |
**Ukládání stavu ochrany** není typicky jako matice (moc „řídké“, | **Ukládání stavu ochrany** není typicky jako matice (moc „řídké“, | ||
Line 565: | Line 637: | ||
- Každý takový řádek je nazýván „seznam schopností“ (**capability list**) | - Každý takový řádek je nazýván „seznam schopností“ (**capability list**) | ||
- | == Seznamy pro řízení přístupu (ACL) == | + | === Seznamy pro řízení přístupu (ACL) === |
- | Implementováno skoro ve všech běžných OS | + | |
- | Subjekty | + | * Nejrozšířenější model, implementován v UNIX, Linux, Windows... |
- | * např. | + | |
+ | | ||
<code bash> | <code bash> | ||
$ ls -ld / | $ ls -ld / | ||
drwx--x--- 1 root lp 6754 Nov 22 00:00 / | drwx--x--- 1 root lp 6754 Nov 22 00:00 / | ||
</ | </ | ||
- | | + | |
- | (příkazy get/ | + | |
- | * mohou obsahovat „negativní“ | + | * Podpora **negativních |
- | vyloučení | + | * **Metaoprávnění** – např. oprávnění měnit ACL nebo členství ve skupinách. |
- | Meta-oprávnění: | + | |
- | | + | |
- | * dovolují modifikaci ACL | + | |
{{statnice: | {{statnice: | ||
- | == seznamy Schopností | + | |
- | **Schopnost** je prvek seznamu schopností | + | === Seznamy schopností |
+ | |||
+ | | ||
+ | * Držitel schopnosti může s objektem manipulovat podle udělených práv. | ||
+ | * Nevyžaduje centrální seznam přístupů – **decentralizovaný model přístupu**. | ||
{{statnice: | {{statnice: | ||
- | **Pojemnovává objekt**, aby s ním program mohl zacházet | + | |
+ | | ||
- | Všichni kdo vlastní „schopnost“ mají právo s objektem pracovat | + | === ACL vs Capability List === |
- | Méně | + | | Seznamy řízení přístupu (ACL) | Schopnosti (Capabilities) | |
+ | |-------------------------------|-----------------------------| | ||
+ | | Tradiční model; proces musí vědět, **jaký objekt chce**, a systém mu řekne, jestli má přístup. | Objekty jsou přístupné **pouze skrze předané schopnosti** – uživatel je *nemůže najít sám*. | | ||
+ | | Oprávnění určena podle identity subjektu | ||
+ | | Problém **ambientní autority** – proces má automaticky všechna práva uživatele. | **Neexistuje ambientní autorita** – práva | ||
+ | | Nelze snadno omezit práva potomků (děděná práva). | Nikdo nemůže předat právo, které **sám nemá**. | | ||
+ | | Linux částečně řeší pomocí **namespaces**, | ||
- | == ACL vs capability list == | + | === Stack Overflow – how to attack |
+ | * **Přetečení zásobníku** nastane, když program zapíše více dat do bufferu (pole, proměnné) na zásobníku, | ||
+ | * ⇒ přepíší se další položky na zásobníku – např. sousední proměnné, uložený rámec (frame pointer) nebo **návratová adresa funkce**. | ||
+ | * Útočník může do bufferu vložit tzv. **shellcode** – malý strojový kód, který může např. spustit shell a umožnit vzdálenou kontrolu systému. | ||
+ | * Pokud útočník přepíše **návratovou adresu**, může přesměrovat běh programu na vlastní kód (shellcode) nebo jinou část programu. | ||
+ | * Útoky se zaměřují na programy v C/C++, kde chybí **automatická kontrola hranic polí**. | ||
+ | * **Omezení shellcodu** – nesmí obsahovat binární nuly (`\0`), protože řetězce jsou jimi ukončovány. ⇒ používají se techniky kódování. | ||
+ | * Moderní techniky: **Return-Oriented Programming (ROP)** – nevpichují nový kód, ale skládají útočný řetězec z již existujících instrukcí v programu (**gadgety**). | ||
- | | Seznamy řízení přístupu (ACL) | Schopnosti | | + | === Stack Overflow – how to defend === |
- | |-----------------------------------|----------------| | + | * **Nespustitelný zásobník (NX, XD bit, ARM UXN)** – zakáže spuštění kódu z datové |
- | | - Tradiční, všeobecně známé, ale... | Lepší vlastnosti | + | * **ASLR (Address Space Layout Randomization)** – náhodné rozmístění paměťových oblastí |
- | | - Proces musí být schopen | + | |
- | | - Typicky to řeší tzv. **ambientní autorita** – tj. každý proces má všechna práva uživatele, který ho spustil (např. „vidí“ celý souborový systém | + | * **Retguard** – návratová adresa je zakódována při vstupu do funkce |
- | | - Pokud program spouští jiný program, potomkovi nelze jednoduše práva omezit. | - Nikdo nemůže delegovat schopnosti, které | + | * **Bezpečné programování** – validace velikosti vstupních dat, používání bezpečných funkcí |
- | | - V Linuxu se dnes tento problém | + | * **Používání moderních jazyků a knihoven**, které |
+ | | ||
- | === Stack Overflow - how to attack === | ||
- | Přetečení zásobníku nastane, když program zapíše více dat do bufferu (pole, proměnné) na zásobníku, | ||
- | => Tím se přepíší další položky na zásobníku, | ||
- | Útočník může do bufferu vložit tzv. shellcode – malý strojový kód, který po vykonání může např. spustit shell a umožnit vzdálenou kontrolu systému. | + | ===== 7. Virtualizace ===== |
+ | * softwarová virtualizace, metoda trap-and-emulate, | ||
- | Pokud útočník přepíše návratovou adresu funkce, může přesměrovat | + | Virtualizace je **abstrakce hardwaru** a jeho částečná emulace v softwaru. Hostujícímu systému je vytvořena iluze, že běží na vlastním fyzickém stroji. |
- | Útoky jsou často cílené | + | Základní pojmy: |
+ | * **Hostitel (host)** – fyzický hardware nebo virtualizované prostředí, | ||
+ | * **Hypervizor** – software, který emuluje virtuální hardware a řídí běh VM. | ||
+ | * **Host (guest)** – OS běžící na virtuálním hardware poskytovaným hypervizorem. | ||
- | Omezení shellcode: nesmí obsahovat binární nulové bajty (řetězce jsou ukončeny nulou). Proto se využívají speciální techniky kódování. | + | Typy virtualizace: |
+ | * **Plná virtualizace** – host neví, že běží na virtualizovaném systému | ||
+ | * **Paravirtualizace** – host si je vědom virtualizace a aktivně spolupracuje s hypervizorem. | ||
+ | * **Emulace** – celé prostředí je softwarově emulované, včetně instrukcí CPU (např. QEMU bez KVM). | ||
+ | * **Cloud virtualizace** – vzdálené řízení a spouštění VM v rámci cloud infrastruktury. | ||
- | Moderní útočníci používají i Return-Oriented Programming (ROP) – místo vkládání nového kódu využívají již existující kód (gadgety) a poskládají z něj škodlivý program. | + | === Výhody VM === |
- | === Stack Overflow - how to defend | + | |
- | Nespustitelný zásobník (Non-executable stack) – moderní procesory (Intel XD bit, ARM UXN) umožňují označit zásobník jako neexekuovatelný, | + | |
- | Address Space Layout Randomization (ASLR) | + | * **Izolace** |
+ | * **Současný běh více OS** – např. Linux + Windows současně na jednom stroji. | ||
+ | * **Přenositelnost a snapshoty** – běžící VM lze přesunout nebo pozastavit. | ||
+ | * **Vývoj a testování** – chyby v kernelu nezhodí celý systém. | ||
- | Stack Canary / Stack Protector – do zásobníku se před návratovou adresu vloží speciální kontrolní hodnota (canary). Při návratu se zkontroluje, | + | === Problémy virtualizace === |
- | Retguard | + | Moderní CPU má dva režimy: |
+ | * **Uživatelský režim (user mode)** | ||
+ | * **Privilegovaný režim (kernel mode)** – OS, přístup ke všemu v systému. | ||
- | Bezpečné programování – vždy kontrolovat velikost vstupních dat před jejich uložením do bufferů, používat | + | VM nesmí běžet přímo v privilegovaném režimu – vnímáno by to jako bezpečnostní riziko. |
+ | VM tedy běží v uživatelském režimu hostitele ⇒ je nutné emulovat vlastní **uživatelský** a **privilegovaný režim** uvnitř VM. | ||
- | Použití moderních jazyků a knihoven, které mají zabudovanou ochranu proti přetečení bufferu. | + | === Trap and Emulate === |
- | Oddělení práv a omezení přístupu – minimalizovat oprávnění běžících procesů, aby případné zneužití mělo co nejmenší dopad. | + | * Instrukce v **uživatelském režimu** hosta se vykonávají nativně. |
+ | * Pokus o vykonání **privilegované instrukce** (např. přístup k HW) vyvolá **výjimku** (trap). | ||
+ | * Výjimku zachytí hypervizor, provede požadovanou akci a vrátí řízení zpět do VM. | ||
+ | * Hostující OS si myslí, že vše proběhlo nativně – **transparentní virtualizace**. | ||
+ | * Nutné rozlišovat: | ||
+ | * **Privilegované instrukce** – způsobí trap, když jsou volány z uživatelského režimu. | ||
+ | * **Citlivé instrukce** – mění globální stav nebo závisí na systému ⇒ musí být zachytitelné (v ideálním případě vždy privilegované). | ||
+ | === Virtualizace systémových volání === | ||
+ | * Systémová volání (např. `open`, `read`, `write`) přecházejí z uživatelského do privilegovaného režimu. | ||
+ | * Ve VM se volání spustí pomocí **trap**, který hypervizor zachytí a provede požadovanou činnost. | ||
+ | * ⇒ **lehce pomalejší** než nativní syscalls, ale zachována kompatibilita a izolace. | ||
+ | === Virtualizace stránkovacích tabulek === | ||
+ | * Každý OS spravuje své **virtuální paměťové mapování** pomocí vlastních stránkovacích tabulek. | ||
+ | * Hypervizor ale musí zajistit, že host nemůže měnit skutečné fyzické mapování: | ||
+ | * Host dostane **virtuální stránkovací tabulky pouze pro čtení**. | ||
+ | * Pokus o změnu vyvolá **trap** – hypervizor provede potřebnou aktualizaci. | ||
+ | * Efektivnější varianta: **shadow page tables** – hypervizor vede vlastní mapu překladů, kterou host nevidí. | ||
+ | * Modernější způsob: **EPT (Intel)** / **NPT (AMD)** – viz níže. | ||
- | ===== Virtualizace | + | === Hardwarově asistovaná virtualizace |
- | * softwarová virtualizace, | + | |
- | Virtualizace je abstrakce hardwaru a jeho částečná | + | Moderní procesory (Intel VT-x, AMD-V) přidávají nový režim: |
+ | * **Non-root execution mode** – speciální režim pro běh VM. | ||
+ | * Privilegované instrukce v tomto režimu mohou běžet přímo bez nutnosti trap-emulace. | ||
+ | * Významně zvyšuje výkon, protože: | ||
+ | * většina běžných činností běží nativně, | ||
+ | * trapy nastávají jen při I/O nebo specifických výjimkách. | ||
- | Jmenujeme tři základní pojmy: | + | Navíc podporují: |
- | * **Hostitel** - systém, na kterém běží hypervizor, na nejnižší úrovni fyzický hardware, v případě zapouzdřené virtualizace to neni fyzický hardware | + | * **EPT (Extended Page Tables)** – hardwarová správa |
- | * **Hypervizor** - software běžízí na hostiteli implementující | + | * **Nested virtualization** – virtualizace uvnitř virtualizace |
- | * **Host** - systém | + | |
- | ====Výhody VM==== | + | === Shrnutí |
- | * **Izolace** - izolace zlepšuje zabezpečení systému | + | |
- | * **Mnooho OS najednou** | + | | Oblast |
- | * **Praktické** | + | |--------------------------|-------------------------------------------------------------------------| |
- | * **Dobré pro vývoj** - při vývojí věcí jako kernel (nepadá celý počítač) | + | | Trap and Emulate |
+ | | Virtualizace syscalls | ||
+ | | Virtualizace page tables | Host spravuje své PT, ale nesmí | ||
+ | | HW asistence | ||
- | ====Problémy virtualizace==== | ||
- | Běžné **CPU** vykonává instrukce ve dvou režimech: | ||
- | * **uživatelský** - běžné uživatelské aplikace, není možné vykonávat určité akce jako např. zápis na disk | ||
- | * **privilegovaný** - režim jádra, má neomezený přístup k celému systému | ||
- | | ||
- | Virtualizovaný stroj tedy nemůže běžet v privilegovaném režimu, běží v uživatelském - pro hostitele se tváří jako běžný program. | ||
- | Je nutné tedy implementovat virtuální uživatelský a virtuální privilegovaný režim. | ||
- | ====Trap and emulate==== | ||
- | * VM vykonává instrukce, jako by se jednalo o normální nativní OS. | ||
- | * Uživatelské instrukce běží normálně, nenastává problém. | ||
- | * Při privilegované instrukci nastane vyjímka (exception) - VM neví že běží celý ve uživatelském režimu. | ||
- | * Hypervizor tuto vyjímku odchytí a vyřeší - běh VM pokračuje a VM ani neví že nějaká vyjímka nastala | ||
- | ====Virtualizace Syscalls==== | ||
- | Využívá systému **trap and emulate** - privilegované instrukce vykonává jako by byl normální OS, hypervizor se postará o vyjímky | ||
- | ====Virtualizace Page Tables==== | ||
- | ====Hard | ||