Archiv rubriky: Jak se stát ajťákem

Míra abstrakce

Z minulých dílů už víš, že programovací jazyk není nic jiného, než určitým domluveným kódem psaný text, který se pak skrz kompilátor převádí do strojového kódu.

Jedno důležité členění programovacích jazyků, které je dle mého důležité pochopit, je míra abstrakce.

Nízká míra abstrakce

Tento programovací jazyk se zpravidla kompiluje do konkrétního zařízení/procesoru/instrukční sady/operačního systému. Program zkompilovaný pro instrukční sadu x86 + OS Windows 10 bude běžet jenom na procesoru s instrukční sadou x86 a s operačním systémem Windows 10 a na ničem jiném. Pro všechny možné kombinace instrukčních sad/OS je nutné vytvořit novou kompilaci.

Nízká míra abstrakce znamená, že:

  • jsme nuceni přemýšlet o práci s informacemi ve fyzickém zařízení
  • pracujeme napřímo s nízko-úrovňovými funkcemi operačního systému (Win32, syscalls)
  • děláme něco, u čeho potřebujeme vymáčknout z konkrétního typu zařízení maximální výkon
  • pravděpodobně děláme operační systém, na výkon náročnou počítačovou hru, robotiku, matematiku, statistiku, vědeckou práci, programování čipů, programování na konkrétní zařízení…

Těmto jazykům se také říká nízko-úrovňové programovací jazyky

Vysoká míra abstrakce

Programovací jazyk vytváří úplně nové koncepty, které zjednoduššují práci s kódem a snaží se nás co nejvíc oddělit od fyzického zařízení ale i od operačního systému. V takovém programovacím jazyce nikdy neřešíme instrukční sadu a často ani operační systém.

Tyto programovací jazyky se kompilují do jakéhosi „mezijazyka“ který se pak na konkrétním zařízení s konkrétním OS kompiluje za běhu (tzv. Just-In-Time („právě v čas“) kompilace).

Vysoká míra abstrakce znamená, že:

  • nemusíme přemýšlet o zvláštnostech a rozdílech mezi fyzickými zařízeními a operačními systémy
  • potřebuji vytvořit něco, co funguje většině lidem na všech možných procesorech a operačních systémech
  • pravděpodobně dělám nějaký web, uživatelskou (okénkovou) počítačovou aplikaci nebo mobilní aplikaci

Těmto jazykům se říká vysoko-úrovňové programovací jazyky.

Co je na trhu práce lépe placené?

Přestože práce v nízko-úrovňových jazycích vyžaduje mnohem širší znalosti, vysoko-úrovňové programovací jazyky jsou na trhu práce lépe placené jednoduše proto, že jsou mnohem blíže „obyčejnému businessu“ jehož poptávka je spíš na funkčnost a rychlost dodání, než na brutální efektivitu a výkon.

Shrnutí

  • Programovací jazyky se podle míry abstrakce dělí na nízko-úrovňové programovací jazyky a na vysoko-úrovňové programovací jazyky
  • Nízko-úrovňové programovací jazyky se většinou kompilují pro konkrétní kombinaci instrukční sady a operačního systému
  • Nízko-úrovňové programovací jazyky nás nutí přemýšlet o tom, pro jaké zařízení, instrukční sadu a operační systém programujeme.
  • Vysoko-úrovňové programovací jazyky se kompilují do „mezijazyka“ který se posléze kompiluje do strojového kódu za běhu.
  • S vysoko-úrovňovými programovací jazyky většinou neřešíme rozdíly v instrukčních sadách a často ani mezi operačními systémy.
  • Vysoko-úrovňové programovací jazyky jsou zpravidla lépe placené na trhu práce

Programovací jazyk

Z předchozích dílů už víš, že nejdůležitější součást počítače je procesor který neustále přijímá instrukce, co má dělat. Instrukce v moderních procesorech má 64 bitů a ty už víš, že to je ve skutečnosti 64 nějakých obvodů, kterými putuje elektřina.

Takže co když chceš napsat nějaký program? Třeba počítačovou hru, nějakou svojí vlastní websajtu, eshop, nebo cokoliv jiného?

Teoreticky vzato můžeš bejt kokot, vzít si k ruce manuál konkrétní instrukční sady a svojí aplikaci napsat skrz jedničky a nuly do procesoru napřímo.

x86-64 má přes 2500 stránek, kompletní dokumentace k ARM64 dokonce přes 8000. Hodně štěstí!

Můj první 64-bitový program!
0001100000000000000000010000000000000000000000000000000000000000
0001000000000000000000000000000000000000100000000000000000000010
1100000000000000000000000000000000000000100000000000000000000010
….
Z tohohle se dřív nebo později zjebeš. To, že je něco teoreticky možné neznamená, že bys to měl dělat.

Jak se teda programuje? Jakým způsobem ajťáci píšou software?

No to je úplně jednoduchý. Místo toho, abys pracoval s jedničkama a nulama tak si vymyslíš nějaký „kód„, se kterým se pracuje jednoduššeji a který pak můžeš převést do instrukcí pro procesor.

Programovací jazyk není nic jiného, než pro člověka čitelnější instrukce pro procesor. Procesoru je to jedno, ten furt pracuje se 64 bity ale to je pro člověka s dnešní složitostí procesorů prakticky nereálné.

Kompilátor a strojový kód

Jakýkoliv programovací jazyk se píše jako lidsky čitelný text v nějakém kódu, který je mnohem přehlednější a srozumitelnější, než se orientovat v jedničkách a nulách.

Tento text ale sám o sobě nejsou instrukce pro procesor. Je to pouze text v nějaké znakové sadě.

Kompilátor (nebo compiler) je program, který převádí text do strojového kódu. Strojový kód je jen takovej chytřejší název pro instrukce pro procesor.

A to je vše. Tadá. Právě jsi se naučil podstatu programovacích jazyků. Není to nic jiného, než nějaký „kód“ který je pro člověka čitelnější než přímá práce s jedničkama a nulama. Tento kód se zapisuje jako text ale aby jej bylo možné spustit, je nutné tento text převést do strojového kódu skrz kompilátor.

Úžasná moderní grafika, jak se z programovacího jazyka stanou instrukce pro procesor.

Kompilátor je taky jenom program. Takže tě možná napadla vtipná otázka: kdo zkompiloval kompilátor?

K tomu mohlo dojít dvěma způsoby:

  • Kompilátor někdo napsal přímo ve strojovém kódu procesoru — ano, někdo se vyloženě sral s assemblerem (což je jen o chlup přehlednější zápis místo nul a jedniček) aby tento jazyk zkompiloval, aspoň v základní verzi. Jakmile měl kompilátor hotový tak už měl možnost napsat nový, rozšířenější kompilátor v tomto jazyce. Tomuto procesu se říká bootstrapping.
  • Kompilátor se napsal v jiném programovacím jazyce.

Jeden z prvních kompilátorů vznikl v roce 1957 a psal se 18 let!

Shrnutí

  • Programovací jazyk je kód, který umožňuje lidštější psaní softwaru jako textu
  • Kompilátor (compiler) je program, který převede kód napsaný programovacím jazykem do strojového kódu
  • Strojový kód je název pro spustitelný program což je jen sada instrukcí pro procesor
  • Bootstrapping je jeden ze způsobů, jakým vznikají nové programovací jazyky. Nejdřív se napíše kompilátor v instrukcích pro procesor pro velmi základní prvky programovacího jazyka a pak se díky tomuto kompilátoru, už v daném jazyce, napíše rozšířenější kompilátor.

Multithreading

V minulém díle jsem pojmenoval pojmy jako proces, entry point, vlákno, hlavní vlákno a stavy vláken.

Operační systém má na starost evidenci, vytváření a přidělování vláken. Jak se ale operační systém rozhoduje, které vlákno má zrovna běžet?

HALT instrukce

Už víš, že procesor je zařízení, do kterého se prostě neustále sypou instrukce. Jakmile zapneš počítač a nic na něm neděláš tak to operační systém kompenzuje HALT instrukcí, která prostě jen pozastaví procesor na krátký časový úsek, třeba 0,001 vteřiny.

Context switching

Jakmile začnou v počítači vznikat další vlákna, operační systém jednoduše sníží počet HALT instrukcí a uvolní výpočetní kapacitu procesoru novému vláknu.

Vláken může běžet najednou libovolné množství – jsme omezeni pouze pamětí a výkonem procesoru.

Jenže bacha – vzpomeň si, jak funguje procesor: zpracovává instrukce za sebou. Procesor (jednoduchý, jednojádrový procesor) neumí zpracovávat několik instrukcí současně. Jasně, umí zpracovat 5 miliard instrukcí za vteřinu ale neumí zpracovat 2 instrukce najednou, ve stejný čas. Instrukce zpracovává v sérii (za sebou) nikoliv paralelně (vedle sebe).

Jak to tedy operační systémy dělají, že umožňují paralelní běh několika vláken najednou?

Neumožňují. Operační systém prostě jen neustále přepíná mezi tím, které vlákno má zrovna přidělený čas procesoru. Tomuto přepínání se říká context switching a schopnosti takto spouštět jednotlivá vlákna se říká multithreading.

Na tomto jednoduchém schématu je vyznačeno, jak se vláknům přiděluje čas procesoru. Na oko to může vypadat, že obě vlákna běží paralelně, ve skutečnosti chvíli běží první vlákno (Thread #1), chvíli druhé (Thread #2).
Zdroj: Wikipedie

To je celé.

Plyne z toho jeden závěr: se zvyšujícím se počtem běžících vláken se zpomaluje rychlost každého běžícího vlákna, jinými slovy, zpomaluje se na oko práce s celým počítačem.

Moderní procesory jsou však tak brutálně rychlé, že z pohledu lidského vnímání na nich mohou běžet stovky vláken „najednou“. Ve zlomku vteřiny procesor přidělí dostatečný čas každému vláknu a z pohledu uživatele všechny vlákna běží paralelně.

Scheduler

Scheduler je název pro tu část operačního systému, která se stará o správu běžících procesů, vláken a o context switching.

V IT je však scheduler obecnější název pro jakýkoliv mechanismus, který má na starosti nějaké plánování.

Vícejádrové procesory

Moderní procesory jsou ve skutečnosti „multičipy“, které obsahují několik „podprocesorů“ ale těmto podprocesorům se říká „jádra“. Například „procesor s 8 jádry“ ve skutečnosti lze označit za „8 procesorů“, které běží paralelně, každý s frekvencí 5 miliard instrukcí za vteřinu.

V těchto vícejádrových procesorech skutečně běží několik instrukcí najednou. V jakém jádru ale běží jaké konkrétní vlákno si určuje operační systém.

Multithreading je podporován v každém jádře. V každém jádře stále může běžet více vláken najednou ale díky většímu počtu jader lze provozovat větší počet vláken bez znatelné ztráty výkonu v porovnání s nudným, „jednojádrovým“ procesorem.

Nelze ale automaticky říct, že procesor s více jádry je výkonnější, než jednojádrový procesor. Záleží na použití.

Aplikace, která spouští spoustu vláken, jako např. počítačová hra, bude těžit z vyššího počtu jader víc, než z jednojádrového procesoru. Aplikace, ve které běží jen jedno vlákno, bude běžet stejně rychle na jednojádrovém i vícejádrovém procesoru.

Shrnutí

  • HALT je instrukce, kterou operační systém v procesoru spouští, pokud zrovna nemá co dělat. Tato instrukce na velmi krátký časový úsek procesor pozastaví.
  • Procesor, nebo jádro procesoru, zpracovává instrukce vlákna v sérii = za sebou = nejdřív zpracuje jednu instrukci a pak tu, která za ní následuje.
  • Multithreading je schopnost spouštět několik vláken na jednou – ve skutečnosti operační systém neustále přepíná přidělený čas procesoru běžícím vláknům. Tomuto přepínání se říká context switch.
  • Moderní procesory jsou ve skutečnosti „multiprocesory“ – je to několik procesorů najednou. Těmto podprocesorům se říká „jádra“.
  • Operační systém určuje, jaké vlákno běží v jakém jádře.

Proces a vlákno

Určitě jsi sám několikrát zažil postup instalace nějaké aplikace/programu. Nejdřív stáhneš nějaký soubor, ten pak spustíš, něco se nainstaluje a ty pak ten program spustíš.

Instalátory jsou samy o sobě nějaké programy. Aplikace, která neběží, je pouze seznam instrukcí v nějakém úložišti jako třeba HDD/SDD.

Jakmile spustíš nějakou aplikaci tak OS udělá několik věcí.

  • OS vytvoří nový proces
  • V dané aplikaci se najde entry point a přidělí se mu hlavní vlákno pod kterým se proces rozeběhne

Tak a teď jsem na tebe vyblil hromadu nějakejch názvů a víš prd co znamenaj. Takže to rozeberu.

Proces

Proces je prostě jenom pojmenování pro běžící aplikaci. To je fakt úplně všechno. Každý proces může spustit podproces ale Windowsy a Linuxy s podprcesy pracují odlišně.

  • Linux: jakmile hlavní proces skončí tak podprocesy skončí s ním
  • Windows: podprocesy běží i po skončení hlavního procesu

Proces ale není to co běží, proces je jenom způsob seskupování běžících aplikací a jejich vláken. To co „běží“ je ve skutečnosti hlavní vlákno. Viz. níže.

Entry point

Každá aplikace obsahuje entry point, což je místo, kde začínají instrukce tohoto programu. Hlavní vlákno procesu začíná spouštět instrukce v entry pointu.

Vlákno (thread)

Vlákno nebo anglicky „thread“ je něco jako „běžící jednotka“ nebo „přidělený procesor“ nebo přidělená kapacita spouštět instrukce. Vlákno se spustí a spouští instrukce které jsou k tomuto vláknu přidělené. Po provedení všech instrukcí vlákno skončí.

Vlákno bez instrukcí se po nastartování ihned ukončí. Seznam vláken si operační systém spravuje v paměti (kernel space).

U vlákna se tedy rozlišuje jeho stav který může být:

  • Běžící (running)
  • Ukončený (terminated/killed/stopped atd.)

Toto jsou dva základní stavy, které jsou společné pro Windowsy i Linuxy. Oba operační systémy podporují i nějaké další stavy jako např. „pozastavené“, „přerušitelné“, „nepřerušitelné“, to už je ale detail který je mimo rozsah tohoto návodu.

Hlavní vlákno

Hlavní vlákno je vlákno, které z pohledu OS reprezentuje běžící program. Proces je pouze kategorizace, „aplikace/program“ to je jen názvosloví, jak tomu říkají lidé. Co ale skutečně v aplikaci běží je jeho hlavní vlákno.

Běžící aplikace = běžící hlavní vlákno aplikace.

Proč ale „hlavní“?

Protože jakákoliv aplikace – respektive jakékoliv vlákno – si může říct operačnímu systému o vytvoření dalšího vlákna.

Ale pozor: jakmile hlavní vlákno skončí, skončí i všechna ostatní vlákna a celý proces! Toto je stejné pro Windows i pro Linuxy.

Proces se skládá vždy minimálně z jednoho běžícího hlavního vlákna. Ukončení hlavního vlákna = ukončení procesu.

Pozor na to, nepleť si vlákna a procesy. Proces je jen obal okolo hlavního vlákna, potažmo dalších vláken, které v rámci procesu běží. Při skončení hlavního vlákna jsou ukončena i všechna ostatní vlákna, která v procesu patří.

OS nedovoluje procesům, aby jejich vlákna četla data z vláken jiných procesů nebo vlákna jiných procesů ovlivňovala. V rámci jednoho procesu je to ale možné. Každá aplikace má totiž od OS přidělený svůj kus v paměti a co si každá aplikace ve svém kusu paměti dělá a kolik vláken ji tam běží, to je její odpovědnost.

Teď si ale možná říkáš: co je to za magii toto? Proč aplikace potřebuje víc vláken?
Jak je vůbec možný, že aplikace běží s více než jedním vláknem?
A jak je vůbec možný, že v rámci OS může běžet víc aplikací? Tedy víc jak jedno vlákno?

O tom si povíme v příštím díle.

Zajímavost: „Fork bomb“ je název pro záškodnickou aplikaci, která obsahuje jen tuto instrukci: Instrukce A: vytvoř vlákno, jehož obsahem je instrukce A. „Fork bomb“ tedy vytváří vlákna donekonečna, dokud OS nedojde paměť nebo výpočetní kapacita procesoru a počítač se úplně odstaví. („fork“ je název Linuxové funkce pro vytvoření nového procesu)

Shrnutí

  • OS při spuštění aplikace vytváří proces. Proces je pouze kategorizace a pojmenovávání běžících aplikací.
  • Aplikaci je přiděleno hlavní vlákno na entry pointem.
  • Entry point je místo, kde začínají instrukce aplikace.
  • Vlákno je základní běžící jednotka.
  • Jakékoliv vlákno může zažádat OS o vytvoření dalšího vlákna se zadanými instrukcemi.
  • Vlákno může být ve 2 základních stavech: běžící a ukončené. Windows a Linuxy podporují u vláken další různé stavy s různými pravidly, jak se z jednoho stavu lze dostat do jiného.
  • Skončení hlavního vlákna znamená konec celého procesu a všech jeho vláken.

Virtuální paměť

Kernel space a User space

V počítačích je komponenta, které se říká RAM paměť a jak jsem řekl v jednom z předchozích dílů, je to prostě jen hromada flip-flopů vedle sebe. Veškeré informace z RAM paměti zmizí po vypnutí počítače.

Procesor s RAM pamětí interaguje velice rychle a stahuje z ní instrukce, které má rozeběhnout: toto jsou instrukce jak OS tak i softwaru, který pod OS běží.

Proto OS dělí paměť na dvě části:

  • Kernel space: toto je prostor OS a nikoho jiného
  • User space: zde je veškerý ostatní software
    • Každá aplikace zároveň vidí pouze svoji vlastní paměť, OS nedovoluje jednotlivým aplikacím si navzájem sahat na svoje paměti.

Do kernel space má přístup jen operační systém, žádný jiný software se do tohoto prostoru paměti nedostane.

Virtuální paměť

Aplikace a software běžící v OS vůbec na prostor v RAM paměti nevidí. OS zprostředkovává každé aplikaci virtuální paměť což je z pohledu aplikace „neomezený“ prostor který tady někde plave ve vzduchu a software má naprostou svobodu v množství paměti, kterou spotřebuje.

Aby se aplikace vůbec k paměti dostaly tak OS nabízí tyto dvě základní funkce:

  • dej mi bajty z virtuální paměti
  • vem si bajty zpátky
Jak software interaguje s pamětí

Paging / swapping

Software je zodpovědný za to, kolik paměti spotřebuje. Operační systém nemá vůbec žádný názor na to, kolik paměti jaká aplikace potřebuje, OS je prakticky jenom zprostředkovatel. Některé aplikace potřebují víc paměti, některé méně, některé aplikace potřebují někdy více, někdy méně. Záleží, na co počítač používáš.

Co se stane, když RAM paměť dojde? OS provádí tzv. paging což znamená, že OS začne přehazovat malé bloky dat mezi RAM pamětí a nějakým jiným avšak většinou podstatně pomalejším úložištěm než je RAM paměť jako je HDD/SSD.

Čím víc bloků paměti OS přehazuje, tím víc se počítač zpomaluje a kouše, dokud se RAM paměť neuvolní.

Swapping je pojmenování pro starší, již nepoužívaný způsob přehazování celých procesů (ne jen jejich dílčích bloků) mezi RAM a jiným uložištěm, zmiňuji se o tom, že se tento pojem používá dodnes i když moderní PC už swapping nedělají.

Shrnutí

  • OS dělí RAM paměť na dvě části: kernel space a user space
  • Kernel space je prostor paměti, ve které se nachází operační systém
  • User space je prostor paměti, ve které se nachází běžící aplikace.
  • Aplikace běžící v OS vidí pouze svoji vlastní paměť a do kernel space nebo do user space jiných aplikací nevidí
  • Virtuální paměť je způsob, jakým OS zprostředkovává paměť jednotlivým aplikacím.
  • Aplikace mají možnost rezervovat si pro sebe bajty z paměti a nebo tyto bajty vrátit
  • Aplikace jsou zodpovědné za množství paměti, se kterým pracují
  • Paging je způsob, jakým se OS vypořádává s nedostatkem RAM paměti přehazováním datových bloků mezi RAM a jiným úložištěm jako HDD/SSD

Interakce software s OS

Aby software běžící v OS mohl nějakým způsobem interagovat se zařízením – například interagovat s pamětí, s disky, reagovat na stisk klávesnice, musí využít funkce nebo události operačního systému.

Obecně se těmto funkcím říká syscalls, já těmto funkcím říkám nízkoúrovňové funkce a události OS.

Proč „nízko-úrovňové“? Mno…protože těch úrovní může být víc. K tomu se dostaneme později.

V různých OS jsou nízkoúrovňové funkce implementovány odlišně. Ve Windows je jeden kompaktní balík funkcí kterému se říká Win32 API. V Linuxu to není jeden kompaktní balík ale hromada funkcí různě rozházených v Linuxové dokumentaci, souhrnně se těmto funkcím říká syscalls. Taky to zesložiťuje fakt, že Linuxů je víc.

Vztah mezi OS a uživatelskými aplikacemi

Nízko-úrovňové události jsou prostě jen operačním systémem zpracovaná přerušení procesoru. Software v OS má možnost se na tyto události „navěsit“ a díky tomu zprostředkovaně reagovat na události jako je například pohyb myši nebo stisk klávesnice.

Prostředí OS z pohledu software

Software který běží na nějakém OS jako třeba Windows a Linux zpravidla vůbec neví, kde zrovna běží.

OS před softwarem schovává konkrétní složitosti daného zařízení a místo toho vytváří úplně nové koncepty. Podívej se na tabulku níže. V této kapitole jsem pojmenoval nízko-úrovňové funkce a události OS, v následujících kapitolách vysvětlím další pojmy.

ZařízeníCo vidí osco vidí software běžící v os
Fyzická RAM paměťFyzická RAM paměť
Kernel space
User space
Virtuální paměť
HDD/SSD diskyHDD/SSD disky
NTFS, FAT32, ext3, ext4…
Souborový systém
USB zařízeníUSB zařízení
Ovladače
Nízko-úrovňové
funkce a události OS
Fyzická jádra procesoruFyzická jádra procesoru
Scheduler, procesy, vlákna
Context switch
Vlákna
Co vidí OS a co vidí software

Shrnutí

  • Software interaguje s počítačem skrz nízkoúrovňové funkce OS
  • Počítač interaguje se software skrz nízkoúrovňové události OS. Toto jsou jen delegovaná přerušení procesoru.

Interakce OS s procesorem

V nějaké kapitole o procesorech jsem se zmiňoval, že moderní procesory jsou stavěné pro software. Většina procesorů počítá s tím, že na nich poběží operační systém.

Toto bych rád rozvinul trochu víc do detailu protože si myslím, že je důležité pochopit, jak operační systém s procesorem interaguje a co to znamená pro člověka, který s operačním systémem pracuje.

Co všechno může procesor dělat

Už bys z předchozích kapitol měl vědět, že procesor je hlava a srdce celého počítače které komunikuje s ostatními komponentami.

Procesor a komponenty

Co to znamená?

To znamená, že procesor obsahuje instrukce, které na signální úrovni interagují se všemi těmi zařízeními okolo sebe.

To je první důvod, proč je těžké napsat vlastní operační systém. OS obstarává instrukce v procesoru, které interagují s ostatními zařízeními a před obyčejným uživatelem schovává obrovskou složitost a komplexitu těchto interakcí. Různá zařízení mají celou řadu různých „protokolů“ a „kódů“ se kterými komunikují a operační systém na to musí být připravený, jinak se procesor se zařízeními okolo sebe nedorozumí.

Kromě toho, při špatném nebo zlomyslném použití těchto instrukcí je možné počítač nebo jeho komponenty fyzicky zničit!

Režim procesoru

Instrukce procesoru jsou proto rozdělené na dvě kategorie:

  • privilegovaný režim = ty instrukce, ke kterým má přístup jen operační systém
  • uživatelský režim = všechny ostatní instrukce

Při startu počítače si operační systém v procesoru nastaví sám pro sebe privilegovaný režim. Jakýkoliv software, který běží v rámci operačního systému k těmto instrukcím nemá vůbec žádný přístup nebo pouze zprostředkovaně přes operační systém.

Znázornit by se do dalo touto hnusnou malůvkou.

Privilegovaný a uživatelský režim

Co z toho plyne?

Pokud chce aplikace pracovat nějakým způsobem s různými zařízeními, musí to udělat přes funkci operačního systému. Obyčejné aplikace nemají přístup k instrukcím procesoru, které komunikují se zařízeními okolo sebe, musí se k nim dostat zprostředkovaně přes operační systém.

Pokud tedy například programátor chce zapsat na disk, uložit něco do RAM paměti, detekovat stisk klávesy na klávesnici, musí si tyto interakce vykomunikovat s operačním systémem.

Ovladač (driver)

Operační systém ale nemůže znát všechny typy zařízení, které na světě existují a nemůže být zodpovědný za všechny interakce v privilegovaném režimu. Proto mají operační systémy zabudovaný koncept ovladačů nebo driverů, které mají možnost přistupovat k privilegovaným instrukcím procesoru.

Proto je nutný si dávat hodně bacha na to, jaký ovladače si na počítač instalujete a operační systém se tě většinou jasně zeptá, jestli si jseš fakt jistej, že chceš nějakej ovladač instalovat protože teroeticky ti ovladač může zařízení nebo komponentu zničit. Prakticky toto není pro většinu uživatelů problém, OS v dnešní době vědí, jak komunikovat s těmi nejběžnějšími komponentami.

Hypervisor

Toto už je trochu pokročilá věc ale tento tutoriál nemá žádný ambice jít do velkejch detailů takže se o tom zmíním.

Moderní procesory mají ještě virtualizační režim. Tento režim je nad privilegovaným režimem. To znamená, že operační systém nemá přístup k instrukcím ve virtualizačním režimu.

Režimy procesoru seřazené podle možných instrukcí, které mohou v procesoru spouštět


Aplikacím které běží ve virtualizačním režimu se říká hyperisory a to jsou aplikace, které jsou schopné vytvářet a spouštět virtuální zařízení na jednom fyzickém zařízení. To znamená, že na jednom fyzickém zařízení může být provozováno několik virtuálních počítačů, každý se svým vlastním OS.

Vztah mezi hypervisorem, OS, uživatelskými programy s různými režimy procesoru.

Shrnutí

  • Instrukce procesoru lze napsat tak, že dojde k fyzickému poškození komponent v počítači
  • Z toho důvodu se instrukce dělí na několik režimů: privilegovaný a uživatelský režim
  • Operační systém má přístup k privilegovanému režimu. Aplikace pouze k uživatelskému režimu.
  • Pokud chce aplikace provést nějakou operaci v nějaké komponentě počítače, musí to udělat skrz funkce operačního systému.
  • Ovladač je software, který umožňuje správnou interakci procesoru s nějakým zařízením, se kterým OS neumí jinak komunikovat
  • Hypervisor je program, který umožňuje instalovat virtuální zařízení na fyzické zařízení. Hypervisor běží ve virtualizačním režimu procesoru, ke kterému operační systém ve virtuálním zařízení nemá přístup.

Operační systém

Teď už toho víš o počítačích docela dost, že jo. Jak počítače pracují s bity a bajty, jak pracují s čísly, zápornými i desetinnými a jak reprezentují znaky.

Z prvních kapitol už máš zároveň nějakou představu o tom, jakou roli v počítači hraje procesor a ostatní komponenty.

Bare-metal programming

Pokud počítač nemá operační systém tak je to jen kus železa. Procesor čeká na instrukce a pokud žádné instrukce nenajde tak pošle celou tvoji rodinu do koncentráku.

Ale víš co – můžeš klidně bejt ajťák, kterej programuje přímo nad kusem železa. Tomu se říká bare-metal programming v překladu doslova „programování nad holým železem“.

K tomu se pojí i pojem embedded programming které znamená „programování nad vestavěnými zařízeními“ což se vztahuje na různé drobné počítače vestavěné do nějakého zařízení s konkrétním účelem, například bankomaty.

Existují taková mrňavá zařízení jako například raspberri pi nebo Arduino. Toto jsou prostě jenom strašně miniaturní počítače s ARM procesory. Existuje celá komunita ajťáků, kteří se tomu věnují a pokud se ti líbí myšlenka přímého programování nad zařízením tak nejdřív dočti tento návod a pak se zkus podívat na návod jak napsat operační systém pro raspberry pi.

Mé vlastní raspberri pi s přídavným displejem.

Hotový operační systém

Já jsem línej ajťák. Používám odjakživa Windows jak k osobním tak pracovním věcem. Moje práce zahrnuje práci i s nějakým Linuxem. Na telefonu mám Android, což je ve skutečnosti Linux ale jestli se někdy Android pokusí mě nutit do interakcí jako pracuji s Linuxama při práci tak ho vyhodim z okna.

Na macOS jsem nikdy v životě nesáhnul ani mě Apple produkty nikdy nezajímaly a nikdy jsem žádný nevlastnil.

Většina ajťačení kterému se ajťáci věnují je už na úrovni existujícího operačního systému. Bare-metal programming a psaní operačních systémů se věnují jenom nadšenci, lidé co to mají jako koníček nebo studenti co se chtějí něco naučit….a nebo lidé, kteří reálně pracují na operačních systémech jako Windows nebo Linux, které všichni používáme.

Proto v tomto návodu cokoliv, o čem budu dále mluvit, je ve vrstvě operačního systému.

Vrstva operačního systému

Shrnutí

  • Bare-metal programming je praxe psaní softwaru přímo pro fyzické zařízení.
  • Zkusit si napsat vlastní OS pro raspberri pi může být zábava, hraničící s masochismem
  • Většina ajťačení o kterém budu v tomto manuálu mluvit probíhá na existujícím hotovém operačním systému jako Windows, Linux nebo macOS.

Znakové sady

Z předchozích dílů bys už měl vědět, jak počítače pracují s čísly, negativními čísly ale i desetinnými čísly. Už bys měl mít docela dobrej základ. Možná z tebe něco bude!

Pamatuješ si, jak jsem mluvil na začátku o morseovce? S elektrickou lampou můžeš něco někomu zablikat a budou si myslet, že jseš debil. Ale pokud se domluvíš na nějakém kódu, třeba na morseovce, můžeš předat nějakou informaci, třeba „NEJSEM“.

Morseovka je kód, kde kombinací signálů předáváš jednotlivá písmena. Podobný „kód“ je dohodnutý i v počítačích protože obyčejní lidé nechtějí pracovat s bity, obyčejní lidé chtějí pracovat s normálními čísly (v desítkové číselné soustavě) a s abecedou.

Potřebujeme přidat novou vrstvu, kterou bych nazval „bitová interpretace“. Je to prostě pohled na bity způsobem, kterému lidé nejvíc rozumí. Desítkovou číselnou soustavu všichni chápeme a pro komunikaci chceme psát věty, slova, písmena.

Přidaná vrstva bitové interpretace

V počítačích můžeš říct, že nějaká kombinace bitů reprezentuje konkrétní písmeno. Znaková sada je „kód“ který přiřazuje ke konkrétní bitové hodnotě konkrétní znak.

ASCII

Nejznámější a nejstarší znaková sada se jmenuje ASCII. Je důležité ji znát. Běžný počítačový uživatel na ní nejspíš nenarazí ale ajťák nejspíš dřív nebo později jo.

A i kdyby ne, stejně je důležité ji znát, protože všechny důležité znakové sady vychází právě z ASCII.

Tato znaková sada se zapisuje do 7 bitů takže se tam vejde jen 128 hodnot.

ASCII tabulka
Zdroj: http://www.asciitable.com/

Velké „A“ je číslo 65 což je v bitech 1000001, malé „a“ je 97 a podobně.

ASCII je fakt stará znaková sada (1963). Spoustu těch znaků v rozsahu 0-31 původně reprezentovala různé divné stavy, táhla, spínače, tlačítka, světýlka, pípátka a bůhví jaký divný věci, které tehdejší počítače měly.

Dnes už mají počítače hlavně USB klávesnici a myš. Klávesnice předává informace úplně jiným kódem (USB HID, strana 53) který se znakovými sadami nijak nesouvisí. Operační systém se stará o to, aby přeložil signál z klávesnice do aktivní znakové sady.

Unicode

Jak počítače začalo používat mnohem víc lidí všude po světě, začaly vznikat další jazykové sady pro mnoho různých jazyků. Samotné ASCII neumí české znaky jako „ř“ nebo „ň“, pouze anglickou abecedu.

Kdysi byl ve znakových sadách neuvěřitelný bordel, každý používal různé znakové sady. Toto období naštěstí skončilo protože všichni začali používat Unicode což je název organizace která vymyslela znaková sadu se stejným názvem, která má 32 bitový rozsah. Už víš, že 32 bitů je 232 a to je 4294967296 — 4 miliardy možných znaků!

To je víc znaků, než kolik celé lidstvo vůbec vymyslelo. Do 4 miliard se vejdou všechny abecedy světa, všechny symboly jazyků jako čínština které obsahují tisíce různých znaků, dále tam narveš i všechny možné historické znaky, různé varianty různých znaků, dokonce i fiktivní, vymyšlené abecedy…a to jseš pořád někde na čísle 100000? 200000? Pořád máš 4 miliardovej nevyužitej prostor.

A tak přišel nějakej kokot a vymyslel emoji 🤪

UTF-8

Plná znaková sada se jmenuje UTF-32. Každý znak zabírá 4 bajty, jenže většina latinkou psaného textu je už zahrnuta v ASCII, ze kterýho historicky spousta dalších znakových sad vycházela.

UTF-8 je varianta, která tohle zohledňuje. Prvních 8 bajtů odpovídá ASCII a ty další 3 bajty lze vynechat. Pokud ale potřebuji vyjádřit znak, který v ASCII není, jako například české „ř“ nebo emoji tak se využijí i zbývající 2 až 4 bajty. Díky tomu UTF-8 šetří místem a zároveň je kompatibilní s jakýmkoliv textem napsaným v ASCII.

Historické české znakové sady

Každý ajťák by si měl všude vynucovat Unicode. Bez diskuze. Unicode je totiž záruka, že zde lze použít jakýkoliv jazyk a nemusíte už řešit podporu různých znakových sad.

Jediný argument, proč používat jinou znakovou sadu je jen tehdy, pokud musíte pracovat se starým softwarem, který Unicode ještě nezná nebo jste nějakým jiným způsobem donucený použít něco jiného, než Unicode. Je teda dobré vědět, že historicky existují tyto české znakové sady, na které můžete narazit:

  • ISO-8859-2
  • Windows-1250
  • Kód Kamenických (tohle už je fakt hrozně moc stará srágora, pokud na to někde narazíte, polejte počítač benzínem a zapalte ho)

„Rozsypaný čaj“

Upřímně jsem šťastný, že už doba problémů špatných konverzí mezi různými znakovými sadami pominula. Už jen velice vzácně narážím na situace, kdy se mi český text zobrazuje ve špatné znakové sadě, než v jaké byl uložen.

Je ale dobré rozumět tomu, co se děje, když na to narazíte. Jakmile se pokusíte zobrazit nějaký text ve znakové sadě, se kterou daný text nebyl uložen, uvidíte bordel nebo „rozsypaný čaj“.

  • Žluťoučký kůň úpěl ďábelské ódy (uloženo a zobrazeno UTF-8)
  • Ĺ˝luĹĄouÄŤkĂ˝ kůň ĂşpÄ›l ďábelskĂ© Ăłdy (UTF-8 zobrazeno ve Windows-1250)
    • možná to nejde úplně poznat ale všimni si, že písmena bez diakritiky prošla. To právě díky tomu, že UTF-8 i Windows-1250 vycházejí z ASCII, kde jsou znaky anglické abecedy, které jsou stejné i v češtině.

Souhrn

  • Znaková sada je „kód“ který určuje, jak se bity překládají do konkrétních znaků
  • Nejstarší znaková sada, ze které všechny ostatní znakové sady vychází, se jmenuje ASCII.
  • Nejmodernější a všude používaná znaková sada, která obsahuje i emoji, se jmenuje Unicode a má rozsah 4 miliardy znaků, většina tohoto rozsahu je nevyužita.
  • Pro šetření dat existuje varianta UTF-8 která s ASCII znaky pracuje pouze s 8 bity. Zbylé znaky zobrazuje v rozsahu 2 až 4 bajtů.
  • Pokud text uložený v jedné znakové sadě zobrazíš v jiné znakové sadě, zobrazí se ti nesmysly.

ALU

Tato kapitola je poslední kapitola, ve který řešíme, jak procesor pracuje s čísly.

Každý procesor obsahuje část, které se říká ALU – v angličtině „Arithmetic logic unit“, v češtině Aritmeticko-logická jednotka. Tato část procesoru není nic jiného než kalkulačka, která umí dělat operace s celými čísly ve dvojkovém doplňku a s desetinnými čísly v plovoucí desetinné čárce . (Někdy se části procesoru pracující s desetinnými čísly říká FPU – „floating-point unit“ nebo „jednotka plovoucí desetinné čárky“)

Souhrnně ALU (nebo ALU+FPU) není nic jiného, než kalkulačka, která umí všechny možné matematické operace, které jsou v ní sestavené pomocí hradel nad 32 nebo 64 bitovými hodnotami, ať už jde o celá čísla ve dvojkovém doplňku, nebo o desetinná čísla v IEEE 754.

Zpravidla je to zadrátované tak, že procesor ovládá nějakou sadu matematických instrukcí, jejichž provedení deleguje právě do ALU.

Nezapomeň na to, že všechny tyhle matematické operace, všechny tyhle nesmysly okolo dvojkového doplňku a plovoucí desetinné čárky, pořád reálně není nic jiného, než elektřina putující v reálných elektrických obvodech ve fyzické vrstvě!

Vrstva binární aritmetiky

Shrnutí

  • ALU je část procesoru, která se zabývá veškerými matematickými operacemi s celými a desetinnými čísly (někdy se část pracující s desetinnými čísly označuje jako FPU)