Jak je to s kompilací

Jak je to s kompilací
« kdy: 23. 04. 2019, 23:57:53 »
Ahoj, chtěl bych požádat, jestli by mi někdo mohl vysvětlit, jak je to s kompilací pro různé systémy. Pokud je kompilace binarizací pro CPU, potom nerozumím tomu, co s tím má společného mezivrstva, tedy operační systém? Tohle mi nikdy nedávalo smysl.

Díky.


Re:Jak je to s kompilací
« Odpověď #1 kdy: 24. 04. 2019, 00:41:16 »
Mame tu sycally, ktery resej veci, jako je I/O, site, atd. Wine funguje prave na tom principu, ze prevadi systemovy volani windows na systemovy volani cilovy platformy. Pokazdy, kdyz program chce neco precist nebo zapsat, tak prave vstupuje do hry operacni system (program vi, ze chce zapsat do souboru X, ale nevi, kde ve skutecnosti je ani jak je vlastne reprezentovan, muze se jednat o obyc soubor na disku, nebo nekde na siti, pripadne muze dojit k poslani dat treba po seriove lince)

Mlocik97

  • *****
  • 898
  • Ubunťák, JS dev.
    • Zobrazit profil
    • E-mail
Re:Jak je to s kompilací
« Odpověď #2 kdy: 24. 04. 2019, 00:43:16 »
OS nie je len pracovná ploha a prieskumník. Samotný OS sa stará o to akú pamäť nechá program alokovať. To že je binární? I word dokument je fyzicky binární. Ale vždy je nutné jej v něčem otvoriť. Programi sa spúšťajú v systéme. Ta medzivrstva je tam preto aby napr. jeden program nemohol manipulovať s pamäťou alokovanou iným programom. Program teda využíva služby jadra OS aby mu bol pridelen prístup či už k nejakej pamäti, k zariadeniu ci iným veciam.

_Jenda

  • *****
  • 1 605
    • Zobrazit profil
    • https://jenda.hrach.eu/
    • E-mail
Re:Jak je to s kompilací
« Odpověď #3 kdy: 24. 04. 2019, 00:47:43 »
Wine funguje prave na tom principu, ze prevadi systemovy volani windows na systemovy volani cilovy platformy.
A současně implementuje knihovny Windows.

Mimochodem tazatel by také mohl najít část odpovědi na svou otázku na https://en.wikipedia.org/wiki/Glibc, povedená jsou ta schémata vpravo a odkazy z nich vedoucí.

Re:Jak je to s kompilací
« Odpověď #4 kdy: 24. 04. 2019, 01:52:50 »
Hardware není jen procesor, operační systém umožňuje programu práci se všemi perifériemi.

Program neví jak jsou uspořádána data na disku, ale potřebuje číst a zapisovat soubory - proto volá služby operačního systému, který mu to obstará. Přitom může chránit data, ke kterým uživatel, který program spustil, nemá mít přístup.

Program neví jaká jsou vstupní zařízení a kam jsou připojená, ale volá služby operačního systému, které mu poskytnou data. Jestli je místo klávesnice připojená čtečka čárových kódů nebo místo myši dva potenciometry je mu úplně jedno, dostane prostě konkrétní data v konkrétním formátu. O to se postará ovladač v operačním systému.

Program neví jak je rozdělená operační paměť, jen požádá operační systém o přidělení určitého rozsahu, a ten se postará o jeho umístění ve virtuální paměti a překlad na skutečné fyzické adresy. Také chrání oblasti paměti přidělené v tu chvíli jiným programům.

Program neví jaký grafický čip plní obrazovku, jen zavolá operační systém a předá mu data k zobrazení. A tak dál, i primitivní operační systémy typu DOS měly až stovky různých služeb, které mohly programy používat: http://spike.scu.edu.au/~barry/interrupts.html

Doporučená literatura:
Hansen - Principy operačních systémů
Madnick/Donovan - Operační systémy


Re:Jak je to s kompilací
« Odpověď #5 kdy: 24. 04. 2019, 11:03:56 »
Jde o to, co kompilujete. Pojďme se podívat 30 let zpátky a programujme hru pro počítač Commodore Amiga. Máme na výběr několik jazyků, ale to není zajímavé. Zajímavé je, že máme na výběr, co bude výsledkem.

V téhle době je nejčastější volbou "binární image". Výsledkem je tedy posloupnost bytů, které se zapíší na disketu. Po startu počítače se načte základ OS z ROM. Z něj je zajímavá jediná věc - a sice že "olizuje" disketovou mechaniku a čeká, zda do ní někdo nějakou disketu vsune. Pokud ano, pak z ní načte první sektor do RAM a zkusí ho spustit jako binární kód.

Při výrobě diskety je tedy potřeba napsat si zavaděč, který se umístí na disketu. Ten si naprogramujeme třebas tak, že načte prvních 150KB z diskety, uloží je od adresy RAM 250000 a skočí na začátek. Ten zavaděč i těch 150KB je potřeba na disketu nějak zapsat, ale na to je celá řada programů. První chyták - nejsou to soubory. Nemáme žádný OS, který by tušil, co na disketě je. Pomocí obslužných rutin v ROM skutečně čteme konkrétní stopy a bloky, nikoliv soubory.

Vyrobit těch 150KB pak obnáší napsat si ten program, překladači říci, že bude uložen na adrese 250000 a nechat ho přeložit. Při psaní jste na tom jako s tím zavaděčem - máte jen základní ovládací rutiny v ROM. A v nich není skoro nic. Takže pokud chcete zobrazit černou obrazovku a uprostřed ní bílý kruh, pak si musíte nastudovat jak se ovládá grafický koprocesor. A hezky ručně mu nastavit hodnotu registrů, vygenerovat si bitmapu, nastrkat na správné místo v paměti a máte hotovo. Potřebujete přehrát zvuk? Tak opět příručku ke zvukovému koprocesoru a to dáte. Potřebujete něco složitějšího, například nakreslit na obrazovku okénko a kurzor, který jde ovládat myší? No tak jak se ovládá grafický koprocesor už víte, jak vytvářet bitmapovou grafiku si už nastudujete snadno. No a myš je snadná, je mapovaná na nějaké HW porty, tak si opět jen nastudujete na jaké a jak s ní komunikovat.

No a když už vám to funguje na vašem počítači, tak je čas začít řešit počítače jiné. Ty mohou mít více disketových mechanik a tak musíte zjistit, ve které vlastně vaše disketa je. A pak číst z té správné, nebo se prostě jen kousnout s chybou "sorry jako ale tohle jde spustit jen z FD0". A co více myší? Nebo jinak rozložená paměť? Chip RAM vs FAST RAM, aneb konflikt Amiga 500+ vs Amiga 500 + RAM modul.

Taková perlička, co některým na první pohled nedochází - na počítači běží váš program. Jen a pouze váš program. Jak doběhne, tak se počítač rebootuje a pak je možné spustit nějaký jiný program.


No, tak to máme "kompilujeme jako binární kód pro počítač". Nyní si proberem "kompilujeme jako spustitelný program pro operační systém". Vaše situace je v mnohém lepší - OS vám nabízí rovnou celou škálu ovladačů. Už nemusíte studovat jak ovládat konkrétní HW. A nemusíte ani studovat, jaký HW vlastně máte. Ani o natažení do paměti se starat nemusíte, to OS udělá za vás, včetně relokace programu na volnou adresu. I s tou disketou je práce rázem snadnější, protože váš program je soubor! A co víc, vy si můžete na disketu dát souborů víc a váš program si je pak za běhu může volně číst! Stačí mu k tomu znát název souboru, vůbec nemusí řešit na kterém bloku začíná a na kterém končí.

Co dál vám OS nabídnul? Třebas GUI! Nemusíte si programovat vlastní ovladač, vlastní rasterizaci, generování bitmap apod. Prostě jen zavoláte funkci OS a rázem máte na obrazovce okénko. Luxus! A co víc, tím okénkem jde hýbat, jde zvětšit, zmenšit, minimalizovat. A to vše bez nutnosti si to naprogramovat. A víte co? Těch oken je na obrazovce více a dokonce i z jiných programů! Vážně, už tam nejste sám.

Ale má to i stinné stránky. Najednou si nemůžete dělat co chcete a musíte respektovat pravidla. Když potřebujete kus RAM, tak si řeknete OS a on vám řekne kde a kolik jí máte k dispozici. Úleva je v tom, že si nemusíte z HW zjišťovat kolik a kde je RAM a pak si sledovat její využití. Přítěž v tom, že si nemůžete jen tak říci kde ji chcete mít a navíc ani tu RAM nemusíte dostat - buď už není dost volné pro vás, nebo (častěji) není volný takový kus v celku.

----

A teď do současnosti. Programy prvního typu se dnes prakticky nepíší. Když budete chtít pár příkladů, tak LILO, GRUB nebo VMware ESXi. Vy ale takový program psát nebudete, protože je to nad vaše síly. A navíc by to uživatele dost iritovalo - málokdo by dneska chtěl rebootovat jen proto, aby spustil váš program.

Prakticky vše je dnes ten druhý případ, spustitelný soubor pro nějaký OS. Ten soubor začíná instrukcemi pro OS. Tedy jaké části toho souboru vzít a kam je nakopírovat. Pak adresu, na kterou se má převést řízení. OS podle instrukcí vytvoří proces, zarezervuje RAM, vykopíruje kusy souboru na správné místo a nakonec zavolá ten binární kód. Samotný program pak, podle konvencí OS, volá služby OS. Dříve se to řešilo třebas tabulkou přerušení - do registrů jste napsal co potřebujete a vyvolal přerušení, na což zareagoval procesor přechodem do módu supervizoru a vyvolal obsluhu přerušení, což byla součást OS. Dnes se to prakticky vždy řeší tím, že ve vašem programu použijete nějakou hotovou knihovnu, například libc. Takže pro váš program je to defakto jen volání funkce. Co se děje na pozadí a jak vlastně k volání OS dojde už vás nezajímá. To za vás udělá ta knihovna. Jenže právě ta je v každém OS jiná. Win32, msvcrt.dll, libc, glibc atd.

Koukněte se sem:
https://wiki.osdev.org/VGA_Hardware
https://files.osdev.org/mirrors/geezer/osd/graphics/modes.c

A pak si upřímně odpovězte na otázku, zda by se vám tohle chtělo programovat, nebo to raději necháte na OS a jeho ovladačích?

alex6bbc

  • *****
  • 1 663
    • Zobrazit profil
    • E-mail
Re:Jak je to s kompilací
« Odpověď #6 kdy: 24. 04. 2019, 11:34:20 »
Karele, moc mile az nostalgicke cteni :-)
Dik

SB

  • ****
  • 347
    • Zobrazit profil
    • E-mail
Re:Jak je to s kompilací
« Odpověď #7 kdy: 24. 04. 2019, 11:51:14 »
...Pokud je kompilace binarizací pro CPU, potom nerozumím tomu, co s tím má společného mezivrstva, tedy operační systém? ...

Operační systém je další vrstvou abstrakce.

Příklad:  MSDOS byl polosystém, protože mnoho věcí neřešil, např. každá hra si musela sama(!) řešit práci se zvukovou kartou, a to s každým typem extra!!! Dnešní systémy poskytují abstraktní rozhraní, kdy aplikace již neřeší na hardwareové úrovni komunikaci s kartou.

Re:Jak je to s kompilací
« Odpověď #8 kdy: 25. 04. 2019, 09:13:05 »
Pro Váš binární program je OS vlastně externí "knihovna funkcí", v obecném slova smyslu. Pro Váš binární program je to pomůcka, abyste si nemusel všechno řešit sám - jak už psali ostatní výše. Nic Vám nebrání se toho pohodlí vzdát, tzn. zkompilovat si program do podoby, kterou lze flashnout místo BIOSu do SPI Flash ROM, nebo do podoby přímo startovatelné jako diskový bootloader - ale z hlediska užitečnosti si moc nepomůžete :-)

Různé dnešní rodiny OS pokrývají částečně tytéž funkce, ale mají je různě pojmenované a liší se zcela určitě únavné podrobnosti = "prototypy funkcí" (počet/pořadí/typy argumentů), formáty předávaných datových struktur, očekávané chování (interní logika) = "programátorské rozhraní" včetně "kontraktu". Dokonce různé verze téhož OS se budou v detailech lišit a zpětná kompatibilita má své meze, takže v zásadě kompilujete dokonce proti konkrétní verzi OS.

A dál to má spoustu nuancí a návazností... stabilita user-space API/ABI a kernel API/ABI napříč verzemi, jazyky kompilované do generického bajtkódu pro "svůj vlastní" softwarový VM (a tedy na OS do jisté míry nezávislé), omezující pravidla pro malé aktualizace low-level C-čkových knihoven tak, aby rozhraní zůstalo kompatibilní s programy zkompilovanými proti starší verzi, pak vedle kernelu a jeho syscallů tu máme standardní user-space knihovnu a individuálně instalované další knihovny pro specifické účely (a jejich verzování) apod. Dependency hell a jeho krocení. Release engineering a jeho best practices...

Jako další čtení bych doporučil třeba něco o volacích konvencích funkcí v C/C++: 1, 2