Spouštění programů a ELF


[Další]

Spouštění programů

V Linuxu se, stejně jako v UNIXu, programy a příkazy spuštějí pomocí interpretu příkazů. Příkazový interpret je uživatelský proces jako každý jiný a označuje se termínem shell.

V UNIXech je mnoho příkazových interpterů, mezi nejpoužívanější patří sh(1), bash(1) a tcsh(1). S výjimkou několika vestavěných příkazů jako např. cd nebo pwd jsou ostatní příkazy spustitelné binární soubory. Při zadání příkazu prohledává příkazový interpret adresáře ve vyledávací cestě (pronměnná prostředí PATH) a hledá spustitelný obraz zadaného jména. Pkud soubor najde, nahraje jej a spustí.

Příkazový interpret provede svůj klon pomocí volání jádra fork a nový proces nahradí binární obraz příkazového interptetu obsahem právě nehraného spustitelného obrazu1. Za normálních okolností příkazový interpret čeká na dokončení synovského procesy, příkazový interpret lze zpět vyvolat tím, že synovský proces přesuneme na pozadí stiskem C-z, čímž se synovskému procesu pošle signál SIGSOTP a proces se zastaví. Zastavený proces lze přesunout na pozadí přípazem bg (zašle signál SIGCONT)2.

Spustitelný soubor m+yže mít mnoho formátů nebo se může jednat o skript. Skriptové soubory je nutné rozeznat a nechat je provést příslušným interpretem. Spustitelné objektové soubory obsahují spustitelný kód a data doplněná o další informace, které umožňují OS nahrát soubor do paměti a spustit jej. Nejběžnějším formátem spustitelného souboru v Linuxu je formát ELF3 (Executable and Linkable Format). Linux je však neuvěřitelně pružný OS, může obsoužit téměř jakýkoliv objektový formát (viz. jádro --- MISC BINARIES, JAVA, DOS i386 a Digital UNIX ELF atd).

Tuto pružnost zajišťuje samo jádro, které si udržuje seznam podporovaných binárních formátů a pokud dojde ke spuštění souboru, postupně se jednotlivé formáty vyzkoušejí, dokud nějaký nebude fungovat. Linux běžně podporuje formáty ELF, a.out (brontosauři žijí :))). Spustitelné soubory nemusejí být nahrávány celé do paměti, využívá se metody vynuceného nahrávání. Jednotlivé části spustitelného obrazu se zavádějí do pamětí podle toho, jak je proces potřebuje. Nepoužívané části je možné z pamětí uvolnit.

Formát ELF

Objektový souborový formát ELF nevržený v Unix System Laboratories je dnes zaveden jako nejčastěji používaný formát v Linuxu. Protože v porovnání s jinými objektovými formáty jako ESCOFF a a.out má tento formát poněkud vyšší výkonostní režii, je daleko pružnější. Spustitelné soubory je formátu ELF obsahují spustitelný kód označovaný text a data. Tabulky ve spustitelném obraze říkají, jak má být proces umístěn do virtuální paměti procesu. Staticky linkované obrazy jsou sestaveny linkerem ld(1) do jediného obrazu, který zahrnuje vše potřebné k jeho spuštění. Obraz dále specifikuje své rozvržení v paměti a adresu, od níž se má kód začít vykonávat. Pro zájemce o detailní strukturu hlavičky ELF souborů doporučuji nahlédnout do zdrojáků jádra.

Když Linux nahrává spustitelný obraz ve formátu ELF do virtuálního paměťového prostoru procesu, neprovádí skutečné nahrávání obrazu. Nastaví datové struktury virtuální paměti, strom struktur vm_area_struct a tabulky stránek. Když se program začne provádět, dojde k výpadku stránky, což způsobí, že se kód a data programu načtou do fyzické paměti. Nepoužité části programu se do paměti nikdy nenahrají. Jakmile zavaděč binárního formátu ELF zjistí, že nahrávaný obraz je platným obrazem ve formátu ELF, odstraní z virtuální paměti procesu obraz stávajícího prováděného programu. Portože proces je klone obrazu, respektive všechny procesy jsou klonem, starý obraz je obraz programu prováděného rodičovským procesem, například tedy obrazem interpretu příkazů.

Odstranění starého spustitelného obrazu zruší staré sruktury virtuální paměti a tabulky stránek. Dojde rovněž k vymazání všech handlerů signálů a k zavření všech otevřených souborů. Na konci rušení je proces připraven přijmout nový spustitelný obraz. Bez ohledu na formát spustitelného obrazu se struktura mm_struct4 procesu nastavuje vždy stejnými informacemi. Musí totiž obsahovat ukazatele na začítek a konec kódu a dat obrazu. Tyto hodnoty se načtou z fyzických hlaviček formátu ELF a jimi určené oblasti programu se mapují do virtuálního adresového prostoru procesu. Zde se rovněž nastaví datové struktury vm_area_struct a provede se inicializace tabulky stránek procesu. Datová struktura mm_struct dále obsahuje ukazatele na parametry předávané programu a na proměnné prostředí procesu.


Poznámky:

1. Jelikož systémy typu UNIX nerozeznávají spustitelné soubory podle přípon (tento terminus technicus se v UNIXu ani nepoužívá), musí mít spustitelný program nastaven příznak `x' (pro daného užívatele, skupinu, či ostatní). Typicky tak činíme sekvencí

     chmod 755 soubor

2. Paradoxně bychom tedy mohli proces rozběhnout příkazem

     kill -SIGCONT pid_procesu

3. To skutečně nemá s Tolkienem pranic společného.

4. Datovou strukturou mm_struct je popsán obsah virtuální paměti každého procesu, na tuto strukturu se ukazuje ze struktury task_struct procesu. mm_struct obsahuje také informace o nahraném spustitelném obrazu a ukazatel na tabulku stránek procesu. Dále obsahuje ukazatele na seznam datových struktur vm_area_struct, z nichž každá reprezentuje jednu oblast virtuální paměti procesu.


Send me a mail to <vychodiv@alpha.inf.upol.cz>.