Das Video kommt von YouTube: erst beim Abspielen verbindet sich die Seite mit YouTube (Google).
Betriebssysteme erklärt | Vom Transistor zur KI #3
Das Wichtigste aus dem Video
Tipp auf eine Zeit – das Video springt genau dorthin.
Transkriptautomatisch erstellt · 345 Zeilen
- Heute werden wir über Betriebssysteme sprechen. Das ist der dritte Teil meiner Reihe vom Transistor zur KI. Falls ihr die anderen beiden Videos noch nicht
- gesehen habt, checkt die gerne ab. Bevor wir anfangen, kurz zurück zum letzten Video. Ihr habt Fragen gestellt. Zwei davon haben mich besonders gefreut, weil
- sie zeigen, dass ihr nicht einfach konsumiert, sondern nachdenkt. Die erste, wenn Maschinencode direkt auf die CPU wirkt, warum hat dann jedes
- Betriebssystem seine eigene ausführbare Datei? Also Windows hat z.B. pun Excel Dateien und Linux 11. Müsste man die nicht einfach austauschen können? Die
- zweite Frage war, wir haben gesagt, alles sind nur Transistoren, die miteinander verschachtelt sind, aber welcher Transistor gibt als erstes das
- Signal? Irgendwo muss das alles doch anfangen, also das klassische Henner Ei Problem. Beide Fragen beantworte ich am Ende dieses Videos vollständig und von
- Grund auf. Und wenn ihr bei diesem Video selbst Fragen habt, schreibt sie gerne in die Kommentare. Die besten nehme ich mit ins nächste Video. Jetzt aber
- Betriebssysteme. Zu allererst klären wir die Frage, warum es überhaupt Betriebssysteme gibt. Du drückst im Grunde einen Knopf, eine App öffnet
- sich. Das Ganze klingt simpel, aber dein Computer macht in diesem Moment etwa eine Million Dinge gleichzeitig. Er lädt Daten aus dem RAM, schreibt auf die
- Festplatte, wartet auf deine Maus, spielt Audio ab und hält dabei 15 andere Programme am Laufen. Aber wer koordiniert das alles? Niemand oder
- besser gesagt etwas etwas, das so tief im System sitzt, dass die meisten gar nicht darüber nachdenken. Das Betriebssystem. Und bevor ich erkläre,
- was das ist, kurze Frage. Stell dir vor, jedes Programm dürfte einfach direkt mit der Hardware reden, direkt mit dem RAM, direkt mit der CPU oder direkt mit der
- Festplatte. Was passiert dann? Du hast Chaos. Zwei Programme wollen gleichzeitig in die gleiche Speicheradresse schreiben. Ein Programm
- hält die CPU fest und lässt keine anderen ran. oder ein schlecht geschriebenes Tool überschreibt die Daten eines anderen Tools. Das
- Betriebssystem existiert, weil wir einen Vermittler brauchen, einen Kontrolleur, eine Abstraktion, die jedem Programm das Gefühl gibt, es sei allein auf dem
- Computer, obwohl gerade 100 andere laufen. Ein Betriebssystem ist also ein Programm. Das klingt unspektakulär, ist es aber nicht. Es läuft ununterbrochen
- im Hintergrund, während du arbeitest, spielst oder streamst. Er startet Programme, es verwaltet den Speicher, es teilt die CPU auf, es spricht mit
- Geräten, es verwaltet Dateien und es sorgt dafür, dass nichts in den Bereich des anderen eindringt. Das Betriebssystem ist super interessant,
- weil es quasi die Schicht zwischen deiner Hardware und allem, was du als Software kennst, ist. Ohne dem Betriebssystem gibt es keine Apps, kein
- Browser, kein Spotify und im Grunde nur Silizium. Jetzt stellt sich die Frage, wie kommt das Betriebssystem überhaupt ins Leben? Wenn der Computer startet,
- wer startet überhaupt das Betriebssystem? Wenn du deinen Computer einschaltest, ist der Arbeitsspeicher leer. Die CPU weiß also nichts. Das
- Betriebssystem liegt irgendwo auf der Festplatte. Also wie kommt es von dort in den Betrieb? Das Ganze läuft in Stufen ab. Stufe 1: Strom fließt, die
- CPU springt an eine fest einprogrammierte Adresse. Dort liegt die Firmware. Firmware ist quasi Software, die direkt in einem Chip auf dem
- Motherboard gespeichert ist. Kein RAM, kein Laufwerk, sondern unveränderlich eingebrannter Code. Auf alten Systemen hieß diese Firmware BIOS, auf modernen
- System heißt sie UAFi. Der Unterschied ist, UAFI ist schneller, unterstützt größere Festplatten und hat eine grafische Oberfläche. Aber die Grundidee
- ist dieselbe. Die Firmware prüft als erstes, ob die Hardware grundlegend funktioniert. Also ist der RAM vorhanden, antwortet die Grafikkarte,
- sind die Eingabegeräte da? Dieser Schritt heißt Post, also Power on Self Test. Danach startet die Stufe 2. Die Firmware sucht nach einem Bootlaufwerk,
- also Festplatte, USB, Netzwerk, irgendwo muss ein Bootloader liegen. Ein Bootloader ist ein kleines spezialisiertes Programm mit einer
- einzigen Aufgabe, das eigentliche Betriebssystem laden. Die Firmware lädt ihn in den RAM und übergibt die Kontrolle und damit beginnt die Stufe 3.
- Der Bootloader auf Linux System z.B. Grab, lädt den Kernel in den Arbeitsspeicher und startet ihn. Der Kernel ist der Kern des Betriebssystems,
- dazu gleich mehr. Der Kernel übernimmt, aber er allein macht das System noch nicht benutzbar. Er startet deshalb als allererstes einen einzigen Prozess, den
- Init Prozess. Auf modern Linux System heißt das System die. Init ist im Grunde der Startschuss für alles, was du als laufendes System kennst. Er fährt der
- Reihe nach alle Dienste hoch, also Netzwerkverbindungen aufbauen, Grafik initialisieren, den Login Bildschirm anzeigen, Hintergrunddienste starten und
- so weiter. Jeder Prozess, der danach läuft, direkt oder indirekt, wurde von Init gestartet. Er ist der einzige Prozess, den der Kernel selbst startet.
- Den Rest startet Init. Ab diesem Moment ist das System hochgefahren. Aber lasst uns hier mal etwas genauer auf den Kernel schauen. Der Kernel ist der Kern
- des Betriebssystems. Der Name kommt nicht von ungefähr. Er ist der Teil, der wirklich mit der Hardware redet. Alle anderen, also deine Apps, deine Shell,
- dein Browser, bittet den Kernel nur um Dinge. Der Kernel entscheidet dann, ob und wie er das umsetzt. Der Kernel verwaltet die Hardware, indem es z.B.
- über die Treiber die Geräte steuert. Es verwaltet den Speicher, also wer bekommt wie viel oder wer darf auf welche Adressen zugreifen und es verwaltet auch
- die Prozesse. Das heißt, welches Programm läuft wann auf der CPU? Der Kernel hat besondere Rechte. Er läuft mit vollen Systemrechten im sogenannten
- Kernel Mode. Das bedeutet, er darf alles und genau deshalb läuft normaler Code nicht im Kernel. Das werden wir uns später noch genauer anschauen, aber bis
- dahin haben wir noch einiges vor. Und zwar läuft jetzt der Kernel, das ist gut, aber wie startet jetzt ein Programm? Du doppelklickst auf eine App,
- aber was passiert da eigentlich? Der Desktop ist übrigens selbst ein Prozess, bemerkt den Klick und sagt dem Kernel: "Sarte dieses Programm." Der Kernel ruft
- daraufhin den Loader auf. Der Loader ist Teil des Betriebssystems und hat eine klare Aufgabe. Eine ausführbare Datei von der Festplatte nehmen und daraus ein
- laufiges Programm im Arbeitsspeicher machen. Das Ganze läuft so ab. Zuerst liest der Loader die ausführbare Datei. Auf Windows ist das eine Punkt Exe. Auf
- Linux ein 11 Binary. 11 steht für Executable and Linkable Format. Es ist kein einfacher Text, sondern ein strukturiertes Format, das dem Loader
- genau sagt, hier liegt der Code und hier liegen die Daten und hier fängst du an. Dann legt der Loader den Code im RAM ab und richtet zwei wichtige
- Speicherbereiche ein, den Stack und den Hieb. Über die haben wir schon im letzten Video gesprochen. Dann lädt der Loader die benötigten Shared Libraries
- nach. Das sind Codebibliotheken, die nicht im Programm selbst stecken, sondern separat auf dem System liegen und sich mehrere Programme gleichzeitig
- teilen. Wenn zehn Programme alle Fenster zeichnen wollen, müssen sie nicht alle den gleichen Code mitbringen. Sie nutzen einfach alle dieselbe Library, also
- weniger Speicherverbrauch und weniger Redundanz. Zuletzt setzt der Loader den EntryP, also die Adresse der ersten Instruktion, die ausgeführt werden soll.
- Die CPU bekommt diese Adresse und legt los. Erst jetzt, nach alldem entsteht ein Prozess. Wichtig, eine Datei auf der Festplatte ist kein Prozess. Sie ist nur
- Potenzial, ein Prozess zu werten. Ich habe hier den Programmstart noch mal dargestellt. Also, wir sehen hier quasi noch mal den Ablauf, den ich gerade
- beschrieben habe, ne? mit Startadresse. CPU beginnt zu laufen und ab da wird ein Programm quasi zu einem Prozess und das erklärt im Grunde den Programmstart. Wir
- können also einfach mal weitergehen zu einem Prozess und einmal erklären, was ein Prozess überhaupt ist. Ein Prozess ist, wie eben gerade beschrieben, ein
- laufendes Programm. Das klingt simpel, ist es auch, wenn man es richtig denkt. Jeder Prozess hat seinen eigenen Speicherbereich. Er sieht den Speicher
- anderer Prozesse nicht. Das ist wirklich wichtig. Er hat eigene Ressourcen, also geöffnete Dateien, Netzwerkverbindungen, Handles. Er ist aber isoliert und das
- Schöne, du kannst hunderte Prozesse gleichzeitig haben und jeder glaubt, er ist allein. Das heißt, wir merken uns, jeder Prozess, ich m
- alles einzelne Prozesse, die dann selber noch mal in ihrem Prozess einen Speicherbereich haben und so weiter. Die sind alle separiert voneinander. Das
- heißt, jeder Prozessor hat seinen eigenen Speicherbereich, seinen eigenen Stack und Hieb und so weiter. Sie können auch nicht der hier der Prozess kann
- jetzt nicht auf den Speicher eines anderen Prozesses zugreifen, aber was ist, wenn ein Programm intern mehrere Dinge gleichzeitig tun soll? Dann kommen
- Threats ins Spiel. Ein Thread ist eine Ausführungseinheit innerhalb eines Prozesses. Stell dir vor, ein Programm lädt eine große Datei vom Netzwerk. Wenn
- es das in einem einzigen Durchlauf tut, friert die Benutzeroberfläche ein, bis der Download fertig ist. Das wäre eine schlechte Erfahrung für den Nutzer bzw.
- wir sagen dazu oft eine schlechte User Experience. Mit Threads kann das Programm sagen, einer kümmert sich um die UI, einer liedt die Datei, einer
- verarbeitet die Daten. Alles gleichzeitig innerhalb desselben Prozesses. Threats teilen sich den Speicher des Prozesses und das ist der
- gravierende Unterschied. Ich male das hier jetzt noch mal kurz auf. Wir haben jetzt hier einen Prozess, so und wir haben einen weiteren Prozess.
- So, die beiden Prozesse teilen sich nicht den Speicher, sie haben unterschiedliche Speicher. Okay, so. Jetzt kannst du aber innerhalb eines
- Prozesses mehrere Threads haben. Das heißt, wir haben z.B. Thread 1, dann haben wir hier Ther.
- So, also mehrere Arbeiter. Ihr könnt euch diese Threads wie so mehrere kleine Arbeiter innerhalb eines Prozesses vorstellen. Der eine arbeitet die
- Grafikoberfläche ab, der andere zieht Daten aus dem Internet und der hier verarbeitet die Daten, die der aus dem Internet holt. Sie teilen sich aber
- einen Speicher. Unterschiedliche Prozesse teilen sich nicht denselben Speicher, aber mehrere Threats innerhalb eines Prozesses teilen sich den
- Speicher. Okay, also Threads teilen sich den Speicher, laufen parallel und ermöglichen im Grunde Multitasking innerhalb eines Programms. Das ist ihre
- Stärke, aber genau da liegt auch eine Gefahr. Denn wenn zwei Threats gleichzeitig auf dieselbe Variable zugreifen, einer liest und der andere
- schreibt, ohne sich abzusprechen, passiert etwas türkisches, eine sogenannte Race Condition. Um Race Conditions zu verdeutlichen, habe ich
- hier mal zwei Threats aufgezeichnet. Okay? Beide Threats sollen, wenn sie mit ihrer Arbeit fertig sind, eine Variable runterzählen. Sagen wir mal, die
- Variable steht hier und die Variable ist aktuell auf einer fünf. So, Fred 1 liest jetzt diese fünf, aber Fred 2 liest diese fünf auch vielleicht zurelben
- Zeit. Was dann passiert? Fred 1 sagt 5 - 1. Er will ihn ja runterzählen, aber Fred 2 hat zurelben Zeit die 5 gelesen und sagt jetzt hier auch 5 - 1 bzw.
- Thread 2 liest den Wert 5, bevor Thread 1 jetzt seine vier hier zurückschreibt. Jetzt schreibt Fred 1: "Okay, ich habe vier, aber Fred 2 hat trotzdem noch die
- fünf gelesen und hat hier als Ergebnis auch die vier. Schreibt also jetzt auch die vier zurück. Das heißt, beide haben eine Operation ausgeführt und beide
- haben -1 gemacht und das Ergebnis ist trotzdem falsch. Hier müsste eigentlich eine drei stehen. Und das Ergebnis ist nicht nur falsch, sondern noch
- schlimmer. Der Fehler tritt vielleicht nur einmal pro 1000 Durchläufen auf, weil er vom genauen Timing abhängt. Solche Bugs sind schwer zu
- reproduzieren, schwer zu finden und können den Produktionssystem jahrelang unbemerkt schlummern. Wir brauchen also einen Weg, wie sich Freats absprechen
- können. Ein Mechanismus, der sagt, nur einer von euch darf hier gleichzeitig rein. Dieser Mechanismus heißt Mutex. Schauen wir uns den ganz kurz an. Mutex
- steht für Mutual Exclusion und ist wie ein Schloss an einer Tür. Es gibt genau einen Schlüssel. Wenn also nehmen wir mal unser Beispiel, der erste Fred den
- Newte Teex auf dieser Variable hält, muss Fred 2 warten, bis Fred 1 fertig ist. Das würde also wie folgt aussehen. Machen wir mal alles hier zurück. Fr 1
- nimmt sich jetzt diese Variable hier und blockiert die sozusagen somit. Sagen wir mal, hier ist jetzt so eine Art Schloss drumherum. Blockiert diese, das heißt
- Fred 2 fragt jetzt zwar an, aber die ist blockiert. Das heißt, er bekommt sie nicht. Das heißt, Fred 1 macht jetzt erstmal 5 - 1 und schreibt den Wert 4
- zurück. Zack, das Schloss wird wieder freigegeben und jetzt kann Fred 2 die 4 nehmen und macht 4 - 1 und schreibt die 3 zurück. Und damit hätten wir ein
- korrektes Ergebnis und die Race Condition gelöst. Aber was ist, wenn wir nicht nur gleichzeitig rein dürfen, sondern eine begrenzte Anzahl haben?
- Stell dir eine Datenbankverbindung vor, die maximal zehn gleichzeitiger Anfragen erlaubt. Ein Meext würde hier zu stark einschränken. Was wir brauchen ist ein
- Meex mit Zähler, also ein Simmer vor. Stell dir einen Parkplatz mit zehn Plätzen vor. Der Simmer vor zählt, wie viele Plätze frei sind. Zehn Threads
- dürfen gleichzeitig rein. Der elfte wartet. Wenn einer rausfährt, geht der Zähler wieder hoch. Simpel, effektiv und überall dort nützlich, wo mehrere
- Threats gleichzeitig auf eine begrenzte Ressource zugreifen müssen. Mutex und Simfor lösen das Problem des gleichzeitigen Zugriffs, aber sie führen
- ein neues Problem ein. Was passiert, wenn Fres anfangen, sich gegenseitig warten zu lassen? Schauen wir uns das Beispiel hier unten an. Fred 1 wartet
- auf Ressource 1. Ressource 1 gehört aber gerade Fred 2. Fred 2 wartet auf Ressource 2 und Ressource 2 gehört in dem Moment aber Fred 1. Sie blockieren
- sich hier gegenseitig und beide warten und zwar für immer. Keiner gibt nach und keiner kommt weiter. Das ist ein sogenannter Deadlock. Das System hängt
- nicht, weil die CPU voll ist, sondern weil zwei Freds sich gegenseitig blockieren. Kein Fehler, kein Crash, einfach Stillstand. Deadlocks sind einer
- der Hauptgründe für Programme, die plötzlich einfach einfrieren ohne ersichtliche Ursache. Und wie löst man das? Auch hier gibt's mehrere
- Strategien, wie z.B. Timeouts, feste Reihenfolgen und so weiter, aber das ist fürs große Ganze erstmal nicht so wichtig. Falls ihr wollt, kann ich dazu
- ein separates Video machen, aber hier reicht's erstmal davon gehört zu haben. Wir haben also jetzt Prozesse, Threats und Mechanismen, die Sie in Schach
- halten, aber wir haben noch ein offenes Problem. Wir haben potenziell hunderte von Prozessen und nur eine oder wenige CPUs. Wer entscheidet also, wer wann
- dran ist? Das Ganze passiert über das Scheduling bzw. Scheduling. Das Scheduling ist die Kunst, viele Prozesse auf wenige CPUs so zu verteilen, dass
- sich alles flüssig anfühlt. Die CPU kann nämlich nur einen Prozess gleichzeitig ausführen pro Kern. Das ist sehr interessant, wenn man darüber nachdenkt,
- weil du hast vielleicht 200 Prozesse laufen. Was macht also das Betriebssystem? Es wechselt und zwar extrem schnell. Jeder Prozess bekommt
- eine kleine Zeitscheibe zugeteilt, einen sogenannten Time Slice, typischerweise nur wenige Millisekunden. Der Prozess läuft, die Zeit läuft ab, er wird
- pausiert und dann ist der nächste dran. So schnell, dass es sich anfühlt wie Parallelität, obwohl es im Kern Sequenzen sind. Also bitte macht euch
- das mal bewusst. Den Großteil, den ihr am Rechner macht, passiert nicht parallel. Es wirkt nur wie Parallelität, weil extrem schnell zwischen Prozessen
- hin und her gewechselt wird. Aber wer entscheidet, wer als nächstes dran ist? Dafür gibt es Scheduling Algorithmen. Der einfachste ist Round Robin. Bei dem
- Algorithmus bekommt jeder gleich viel Zeit. Ist also im Grunde fair, aber in der Praxis reicht das nicht, denn nicht alle Prozesse sind gleich wichtig.
- Deshalb arbeiten moderne Betriebssysteme mit Prioritäten. Jeder Prozess hat eine Prioritätsstufe. Prozesse mit hoher Priorität bekommen mehr CPUZit, öfter
- oder länger. Ein Systemprozess, der Sicherheitschecks durchführt, hat höhere Priorität als ein Hintergrundprozess, der Daten komprimiert. Besonders
- interessant ist die Behandlung von interaktiven Prozessen, also Prozessen, die auf eine Eingabe warten. Ein Texteditor z.B. sitzt die meiste Zeit
- Idle bzw. im Leerlauf, tut nichts und wartet. Sobald du aber eine Taste drückst, muss er sofort reagieren, sonst fühlt sich die UI träger an. Das
- Betriebssystem erkennt solche Prozesse und bevorzugt sie in dem Moment, wo sie aktiv werden. Das ist kein Zufall, das ist bewusstes Design. Das Gegenteil sind
- CPU intensive Prozesse, Videoencoding, Simulation und Kompilierung. Diese laufen im Hintergrund, brauchen viel Zeit, aber niemand wartet aktiv auf ihre
- Ausgabe. Sie bekommen niedrige Prioritäten und müssen warten, bis interaktive Prozesse fertig sind. Es gibt noch eine weitere wichtige
- Unterscheidung. Prätives versus kooperatives Scheduling. Beim kooperativen Modell, das frühere Systeme wie altes MacOS genutzt haben,
- entscheidet der Prozess selbst, wann er die CPU abgibt. Das Problem, ein schlecht geschriebenes oder hängendes Programm gibt sie nie ab und blockiert
- alles. Beim prätiven Modell, dem Standard auf allen modernen Betriebssystemen, kann das Betriebssystem Prozess die CPU jederzeit
- entziehen. Egal, was der Prozess gerade tut, das Betriebssystem hat das letzte Wort. Das Betriebssystem ist dabei nicht fair im naiven Sinne. Es ist
- strategisch. Sein Ziel ist nicht Gleichheit, sondern dass sich das System flüssig anfühlt. Okay, kommen wir zum nächsten interessanten Punkt und zwar
- virtuellen Speicher und der ist wirklich interessant. Stell dir vor, du vermietest Wohnungen. Sagen wir mal, du hast 20 Mieter, aber nur 10 Wohnungen.
- Also, du hast mehr Leute, die in eine Wohnung rein wollen, als dass du Wohnungen hast. Das klingt erstmal nach Betrug. Aber was ist, wenn die Mieter
- nie alle gleichzeitig zu Hause sind? Genauso funktioniert virtueller Speicher. Jeder Prozess glaubt, er hat einen riesigen exklusiven Adressraum für
- sich allein. Auf einem 4 Bitsystem sind das theoretisch mehrere 100 TB, mehr als irgendjemand je braucht. Natürlich existiert dieser Speicher nicht
- wirklich, aber der Prozess weiß das nicht. Und das ist der Punkt. Das Betriebssystem gibt jedem Prozess virtuelle Adressen. Intern übersetzt es
- diese Adressen still und heimlich auf echte physische Adressen im RAM. Der Prozess A denkt z.B. Er liegt bei Adresse 0x1000. In Wirklichkeit liegt er
- ganz woanders. Prozess B denkt dasselbe und liegt wieder woanders. Das Ganze bringt drei Dinge auf einmal. Isolation, also kein Prozess sieht den Speicher
- eines anderen. Sie leben in getrennten Welten, auch wenn sie sich denselben physischen RAM teilen und Flexibilität. Das Betriebssystem kann Speicher intern
- verschieben und neu organisieren, ohne dass irgendein Prozess davon mitbekommt. Und Schutz. Wenn ein Prozess auf eine Adresse zugreift, die ihm nicht gehört,
- fängt das Betriebssystem es ab. Kein stilles Überschreiben und kein Datenchaos. Aber wie werden diese virtuellen Adressen eigentlich
- organisiert? Das Betriebssystem braucht im Grunde einen Weg, den Speicher clever aufzuteilen. Nicht als einen großen Block, sondern in kleine hunterbare
- Stücke. Diese Stücke heißen Pages. Der gesamte Adressraum, virtuell wie physisch wird in gleich große Blöcke aufgeteilt. Dieser virtuelle Speicher
- ist also das, was euer Prozess eigentlich sieht und dieser physische Memory hier, das ist euer RAM. Und ihr seht, wir teilen die in gleich große
- Blöcke auf. Das heißt, jeder dieser Blöcke hier ist in etwa 4 KB groß. Also sowohl hier im virtuellen Speicher als auch im physischen Speicher. Der RAM
- besteht aus sogenannten Page Frames, also das sind diese gleich großen physischen Slots. Das Betriebssystem hier hält eine Tabelle, welche virtuelle
- Page in welchem physischen Frame liegt. Diese Tabelle heißt Page Table. Hier wird sie Memory Map genannt. Und jetzt kommt der eigentliche Trick. Nicht alle
- Pages müssen gleichzeitig im RAM sein. Das Betriebssystem lädt nur die Pages, die gerade wirklich gebraucht werden. Alles andere liegt auf der Festplatte
- und wartet. Wenn ein Prozess auf eine Adresse zugreift, deren Page gerade nicht im RAM ist, passiert ein sogenannter Page Fault. Das
- Betriebssystem bemerkt das, holt die Page von der Festplatte nach, legt sie in einen freien Frame und aktualisiert diese Page Table hier. Der Prozess läuft
- weiter, als wäre nichts gewesen. Du bemerkst davon also nichts, außer vielleicht einer kurzen Verzögerung. Das System hier wirkt also viel größer, als
- das eigentlich ist. Jeder Prozess bekommt seine Illusion von unbegrenztem Speicher, während das Betriebssystem im Hintergrund jongliert. Ihr seht es hier
- auch im Bild, ne? Der virtuelle Speicher wird größer dargestellt als der eigentliche physische Speicherplatz. Aber was passiert, wenn hier der RAM so
- voll ist, dass auch dieses Jonglieren nicht mehr reicht? Wenn wirklich kein freier Frame mehr übrig ist, dann muss das Betriebssystem eine Entscheidung
- treffen und zwar welche Page fliegt raus? Es wählt eine Page hier aus dem physischen Memory, die lange nicht mehr genutzt wurde und schiebt sie auf die
- Festplatte und zwar in einen reservierten Speicherbereich, den sogenannten Swapbereich. Der Frame ist jetzt frei und kann einer neuen Page
- gegeben werden. Das heißt, wir tauschen im Grunde hier Pages aus. Die Festplatte hier fungiert also langsame Verlängerung des RAMs. Wenn die ausgelagerte Page
- wieder gebraucht wird, holt das Betriebssystem sie wieder zurück und muss dafür möglicherweise wieder eine andere rausschieben. Das funktioniert,
- bis es nicht mehr funktioniert. Wenn das System ständig Pages rein und rausschiebt, weil der RAM chronisch zu voll ist, spricht man von Trashing. Die
- CPU verbringt mehr Zeit damit, Pages zu verschieben, als tatsächlich Arbeit zu erledigen. Die Festplatte rattert und alles stockt. Jeder von uns hatte schon
- mal dieses Gefühl. Wenn du z.B. zu viele Browser Tabs offen hast und zu wenig RAM. Wichtig, Swap ist kein Ersatz für RAM, er ist ein Notnetz. Wir müssen ja
- quasi aus einer langsameren Festplatte die Daten bzw. dem Frame erstmal auf den RAM ziehen und das kostet Zeit. Aber jetzt stellt sich eine Frage. Wer
- übersetzt eigentlich die virtuellen Adressen bei jedem einzelnen Speicherzugriff schnell genug, ohne dass man irgendetwas merkt? Das macht die
- sogenannte Memory Management Unit. rein in Software würde diese Übersetzung also von virtuellen Adressen zu physischer Adresse bei jedem einzelnen
- Speicherzugriff passieren. Tausende Male pro Sekunde prozess. Das wäre viel zu langsam. Deshalb macht das keine Software, das macht Hardware. Die MMU
- ist eine Komponente direkt in der CPU. Das Betriebssystem definiert die Page Tables. Also virtuelle Adresse X liegt bei physischer Adresse Y. Die MMU führt
- diese Übersetzung dann in Hardware aus und zwar bei jedem Speicherzugriff in immens schneller Zeit, ohne dass die Software eingreifen muss. Software
- definiert also die Regeln, aber die Hardware setzt sie um. Das ist eigentlich das Muster hinter vielen Dingen, die wir in dieser Reihe gesehen
- haben. Das Betriebssystem legt fest, was erlaubt ist und die Hardware stellt sicher, dass es durchgesetzt wird, schneller, als dass es jede Software tun
- könnte. Wir haben jetzt also Speicher im Rahmen. Prozesse laufen, Seiten werden geladen und ausgelagert, aber wenn der Computer ausgeht, ist alles weg. Für
- dauerhafte Speicherung brauchen wir etwas anderes und dafür brauchen wir ein Dateisystem. Für alles, was überleben soll, also sowas wie Dokumente,
- Programme oder das Betriebssystem selbst, brauchen wir die Festplatte. Aber eine rohe Festplatte ist erstmal nur eine sehr lange Sequenz von Nullen
- und Einsen. Kein Anfang, kein Ende, keine Struktur. Wie findet man da irgendwas? Genau dafür gibt es das Dateisystem. Das Dateisystem ist die
- Struktur, die festlegt, wie Daten auf einem Speichermedium organisiert werden. Es definiert, was eine Datei ist, was ein Ordner ist und wie Fade aufgebaut
- sind, wann wurde die Datei erstellt, wer darf sie lesen, wie groß ist sie, wo auf der Festplatte liegen die Dateien tatsächlich. Ohne Dateisystem weiß
- niemand, wo eine Datei anfängt und wo sie aufhört. Bekannte Dateisysteme sind z.B. EXT4 auf Linux oder NTFS auf Windows oder APFS auf MacOS. Sie
- unterscheiden sich im Grunde in ihren Details, also wie sie z.B. mit großen Dateien umgehen, wie sie sich nach einem Absturz erholen, wie effizient sie
- Speicher nutzen. Aber die Grundidee ist überall dieselbe. Struktur über Chaos legen. Das Betriebssystem kommuniziert mit dem Dateisystem über eine weitere
- Schicht und die führt uns direkt zur nächsten Frage. Wie redet das Betriebssystem eigentlich mit der Hardware darunter? Hardware ist
- vielfältig. Eine Grafikkarte von Nvidia funktioniert anders als eine von AMD. eine Festplatte von Samsung anders als eine von Western Digital. Jedes Gerät
- hat seine eigene Sprache, seine eigenen Befehle und seine eigene Art zu antworten. Das Betriebssystem kann diese Vielfalt nicht kennen. Es wäre unmöglich
- für jede Hardwarekombination der Welt speziellen Code im Kernel zu haben. Die Lösung: Treiber. Ein Treiber ist ein Programm, das als Übersetzer fungiert.
- Auf der einen Seite spricht er mit dem Betriebssystem in einer standardisierten generischen Sprache. Auf der anderen Seite spricht er mit dem spezifischen
- Gerät in dessen eigener Sprache. Das Betriebssystem sagt z.B. Schreibe diese Daten. Der Treiber übersetzt das in die konkreten Befehle, die genau dieses
- Gerät versteht. Das Geniale daran, Programme wissen gar nicht, mit welcher Hardware sie reden. Sie sprechen mit dem Treiber. Der Treiber spricht dann mit
- dem Gerät. Du kannst die Grafikkarte wechseln, ohne dass eine einzige App angepasst werden muss, solange es einen Treiber gibt. Also wieder Abstraktion.
- Es ist immer wieder dasselbe Prinzip. Und jetzt stellt sich die nächste Frage: Wie bitten Programme eigentlich das Betriebssystem um etwas? Wie läuft diese
- Kommunikation ab? Also sauber kontrolliert und sicher. Programme laufen in der Regel im User Mode. Das haben wir bereits festgelegt. Sie dürfen
- nicht direkt mit Hardware reden. Im Grunde ist das ja auch der Grund, warum wir Betriebssysteme haben. Sie dürfen also nicht einfach in beliebige
- Speicherbereiche schreiben. Sie dürfen nicht selbst entscheiden, wann sie auf die Festplatte zugreifen. Wenn Sie etwas brauchen, müssen Sie fragen. Die
- Schnittstelle für diese Anfrage heißt System Call. Kurz SIS Call. Wenn ein Programm eine Datei öffnen will, ruft es nicht selbst die Festplatte an. Es ruft
- z.B. den Open Befehl auf. Das Betriebssystem übernimmt, prüft, ob das Programm überhaupt das Recht hat, diese Datei zu öffnen, führt die Operation aus
- und gibt das Ergebnis zurück. Gleiches gilt für alles, was mit dem System zu tun hat. Also z.B. Netzwerkpakete senden, Speicher anfordern, einen neuen
- Prozess starten, die Uhrzeit abfragen und und. Jedes Mal dasselbe Muster. Programm fragt, Betriebssystem entscheidet und Betriebssystem handelt.
- Der Syscall ist der einzig legitime Weg aus dem User Mode heraus. Kein Umweg, kein Trick, keine Abkürzungen. Das Betriebssystem ist der Vermittler immer.
- Merkt euch das. Aber rohes Ciscalls direkt aufzurufen ist umständlich und fehleranfällig. Deshalb gibt es eine Zwischenschicht, die das für uns
- übernimmt und zwar Systembibliotheken. Du kannst z.B. in deinem C-Programm sowas wie Print F aufrufen. Du willst also Text ausgeben, relativ simpel. Was
- du dabei nicht siehst, Print F ist kein Sys Call. Es ist eine Funktion der Standardbibliothek. Auf Linux z.B. die GLPC auf Windows die Win 32 API. Diese
- Bibliothek nimmt deinen Aufruf, bereitet alles vor und ruft intern die richtigen Sys Calls auf. Du selbst siehst davon aber nichts. Die Systembibliothek ist
- also eine weitere Komfortschicht. Sie vereinfacht, validiert und abstrahiert. Sie übersetzt die menschenfreundliche Sprache, die Programmierer schreiben, in
- die präzisen strickten Aufrufe, die der Kernel versteht. Programmierer bzw. Entwickler orientieren sich an der Bibliothek und die Bibliothek selbst
- redet mit dem Kernel. Das ergibt eine klare Schichtung Programm, Bibliothek, SS Call, Kernel. Jede Schicht hat ihre Aufgabe. Jede Schicht verbirgt die
- Komplexität der Schicht darunter. Also auch hier seht ihr wieder dieses Konzept der Abstrahierung, richtig? Wir greifen nicht direkt auf den Kernel zu, sondern
- auf Ciss. Und auch nicht auf Cis direkt, sondern auf Bibliotheken. Das heißt, wir abstrahieren im Grunde hoch, so dass es anwenderfreundlich wird. Aber damit das
- alles sicher funktioniert und damit ein Programm den Kernel nicht einfach übernehmen kann, brauchen wir noch das Konzept, das wir bisher nur angedeutet
- haben. Die CPU ist im Grunde nicht naiv. Sie weiß, dass nicht jeder Code gleich viel Vertrauen verdient. Deshalb kennt sie verschiedene Privilegstufen. Auf x86
- System heißen sie Rings. Ring 0 ist der mächtigste und Ring 3 ist der eingeschränkteste. In der Praxis nutzen moderne Betriebssysteme hauptsächlich
- zwei davon. Der Kernel läuft in Ring Null, dem Kernel Mode. Er darf alles, also direkter Zugriff auf Hardware, beliebige Speicheradressen und und keine
- Einschränkung. Normale Programme laufen in Ring 3, dem sogenannten User Mode. Sie dürfen deutlich weniger. Also, was wir uns hier im Grunde merken können,
- ist alles, was über das einfachste hinausgeht, geht über den Kernel. Das ist kein Zufall, das ist das tragende Designprinzip des gesamten Systems.
- Stell dir vor, ein Programm hat einen Bug oder schlimmer, es wurde kompromettiert, jemand hat Chartcode eingeschleust. Im User Mode kann dieser
- Code nur das, was das Programm darf, nicht mehr. Es kann nicht ins Betriebssystem einbrechen. Es kann nicht den Speicher anderer Prozesse
- manipulieren. Es kann nicht die Hardware direkt ansprechen. Es stürzt ab allein und der Rest läuft weiter. User Mode bedeutet Isolation, Kernel Mode bedeutet
- Macht und Verantwortung. Ein Bug im Kernel Mode kann das gesamte System zum Absturz bringen. Deshalb läuft dort so wenig Code wie möglich. Aber wie
- wechselt das System zwischen diesem Modi? und zwar kontrolliert sicher und ohne, dass ein Programm einfach in den Kernel Mode springen kann. Und zwar
- läuft das Ganze über den Mode Switch. Ein Programm im User Mode kann nämlich nicht einfach entscheiden, ich wechsel jetzt in den Kernel Mode. Das wäre ein
- fundamentales Sicherheitsproblem, denn jedes Programm könnte sich beliebige Rechte nehmen. Stattdessen läuft der Wechsel streng kontrolliert ab. Das
- Programm ruft ein SIS Call auf, z.B. Open. Und anstatt die Operation selbst auszuführen, löst es eine spezielle CPU Instruktion aus. Auf modernen X86 System
- heißt sie Sis Call. Das ist kein normaler Funktionsaufruf. Es ist ein Signal an die CPU selbst. Also die Instruktion selbst heißt CSC. Ich habe
- eben gerade auch schon SSCs beschrieben, aber auch die Instruktion heißt CSC. Die CPU reagiert darauf, genauso wie sie auf einen Interrupt reagiert. Auf Interrupts
- kommen wir später zu sprechen. Die CPU unterbricht den laufenden Code, sichert den aktuellen Zustand und springt zu einer fest definierten Adresse im
- Kernel. Eine Adresse, die das Programm weder kennt noch beeinflussen kann. Der Kernel übernimmt, führt die angeforderte Operation aus, prüft Rechte und liefert
- das Ergebnis. Dann schaltet die CPU zurück in den User Mode. Das Programm läuft weiter, als wäre nichts gewesen. Der gesamte Vorgang ist super schnell
- abgearbeitet. Du merkst davon nichts, aber er passiert bei jedem Dateizugriff, jedem Netzwerkpaket und jeder Speicheranfrage hunderte Male pro
- Sekunde prozess. User Mode und Kernel Mode trennen also Macht von Anwendung. Der Mode Switch ist die einzig kontrollierte Brücke dazwischen und
- genau das macht sie so wichtig. Wir haben jetzt also verstanden, wie ein einzelnes Programm mit dem Kernel kommuniziert, aber was ist, wenn zwei
- Programme miteinander kommunizieren müssen, obwohl sie strikt voneinander isoliert sind? Und damit kommen wir zur Interprozesskommunikation.
- Prozesse sind ja eigentlich isoliert, darüber haben wir vorhin schon gesprochen. Jeder hat seinen eigenen Speicher und seine eigene Welt. Das ist
- gut für Sicherheit und Stabilität, aber es wirft eine praktische Frage auf. Was ist, wenn Sie zusammenarbeiten müssen? Ein Webserver empfängt z.B. eine Anfrage
- und muss sie an einen Datenbankprozess weitergeben. Ein Programm schreibt z.B. die Logs ein anderes liest und analysiert sie. Eine App besteht z.B.
- aus einem Front-Endend und einem Backend Prozess, die ständig Daten austauschen. All das ist normale Realität, aber direkt in den Speicher des anderen
- Schreiben darf keiner. Dafür gibt es Interprozesskommunikation, kurz IPC. Pipes sind hier das einfachste Modell. Ein Prozess schreibt, ein
- anderer liest. Einseitig und simpel. Das Pipesymbol, das du vielleicht aus der Shell kennst, ist genau das. Die Ausgabe eines Programms wird direkt zur Eingabe
- des nächsten. Shared Memory ist das schnellste Modell. Das Betriebssystem gibt zwei Prozessen Zugriff auf denselben physischen Speicherbereich.
- Kein Kopieren, direkte Kommunikation. der Haken. Sobald zwei Prozesse gleichzeitig schreiben, sind wir wieder bei Race Conditions.
- Synchronisierungsprobleme, die wir bei Freds gesehen haben, gelten hier genauso. Dann gibt es noch Sockets. Sockets sind das flexibelste Modell,
- ursprünglich für Netzwerkkommunikation gedacht, aber sie funktionieren genauso lokal zwischen zwei Prozessen auf demselben Rechner. Fast alles Moderne
- baut darauf, also http, Datenbankverbindungen, Microservices, ein Prozess sendet und der andere empfängt, als würden sie über ein
- Netzwerk reden, auch wenn sie nebeneinander auf derselben Maschine laufen. IPC ist also der Grund, warum komplexe Systeme aus vielen kleinen
- isolierten Prozessen bestehen können und trotzdem als Ganzes funktionieren. Da ich Security Background habe, sind Rechte und Sicherheiten natürlich
- besonders interessant. Das Betriebssystem weiß nämlich nicht, ob du gute Absichten hast. Es geht davon aus, dass du sie hast, aber es vertraut nicht
- darauf. Deshalb verwaltet es Rechte nicht nur für Programme, sondern für alles. Also Nutzer, Gruppen, Dateien, Prozesse. Jeder Nutzer hat eine
- eindeutige User ID. Jede Datei gehört einem Nutzer und einer Gruppe. Und für jede Datei legt das Betriebssystem drei Dinge fest. Darf der Besitzer sie lesen,
- schreiben und ausführen? Darf die Gruppe das? Und darf jeder andere das. Neun Bits und damit ist der Zugriff für alle Fälle geregelt. In Linux sieht das z.B.
- so aus und auch ein Prozess läuft immer im Kontext eines Nutzers mit dessen Rechten nicht mehr und nicht weniger. Wenn das Programm versucht auf eine
- Datei zuzugreifen, für die es keine Berechtigung hat, verweigert das Betriebssystem den Zugriff ohne Ausnahme, ohne Diskussion. Das klingt
- simpel und konzeptuell ist es das auch, aber es ist einer der wirksamsten Mechanismen gegen Angriffe. Das zugrunde liegende Prinzip heißt Least Privilege.
- Gib jedem Nutzer, Programm, Dienst nur die Rechte, die er wirklich braucht. Nicht mehr. Wenn ein Programm kompromettiert wird, kann der Angreifer
- nur das, was das Programm darf. Ein Webserver, der z.B. von einem Angreifer übernommen wurde, der nur Dateien in einem bestimmten Ordner lesen darf, kann
- nicht das gesamte System übernehmen, selbst wenn er gehackt wird. Lease Privilege ist also kein Feature. Es ist eine Philosophie und sie zieht sich
- durch das gesamte Design moderner Betriebssysteme. Jetzt möchte ich noch mal ganz kurz über Netzwerke sprechen, wobei ich dazu ein dediziertes Video
- machen werde. Also es wird eine eigene Sektion sein. Hier gehen wir erstmal auf Programme und Anwendung und dann wird danach eine Internetsektion kommen. Aber
- hier sprechen wir mal ganz kurz darüber. Wenn eine App Daten senden will, ruft sie einen Sys Call auf. Sie übergibt Daten und eine Zieladresse. Mehr muss
- sie nicht wissen. Den Rest übernimmt das Betriebssystem. Das Betriebssystem verpackt die Daten in TCP Segmente, verpackt diese in IP und gibt sie an den
- Netzwerktreiber weiter und der schickt sie raus auf die Leitung. Macht euch hier bitte keine Sorgen, wenn ihr jetzt TCP, IP und so weiter alles noch nicht
- verstanden habt. Dazu kommen wir noch. Ich will einfach nur, dass ihr es schon mal gehört habt. Auch hier gibt es eine Abstraktion, die das für Programme
- sichtbar macht. Die heißt Socket. Wir haben vorhin schon darüber gesprochen. Das ist wieder dasselbe Muster. Komplexität nach unten verstecken und
- oben eine saubere Schnittstelle lassen. Eine App muss also nicht wissen, wie ein IP-Paket aussieht. Sie muss nur wissen, wohin sie sie senden will. Das
- Betriebssystem ist der unsichtbare Netzwerkvermittler für jeden Prozess auf dem System. Aber wie gesagt, Netzwerke werden wir in einem separaten Video
- deutlich genauer betrachten. Also gehen wir einfach mal weiter. Das Betriebssystem verwaltet auch noch Zeit. Das klingt erstmal trivial, ist es aber
- nicht. Ohne Zeitkontrolle kein Scheduling und ohne Scheduling kein Multitasking. Und ohne einen zuverlässigen Taktgeber gibt es keine
- Zeitkontrolle. Hardwareetimer im System generieren in regelmäßigen Abständen Interrupts, ein Signal an die CPU, dass die Zeit vergangen ist. Bei jedem dieser
- Interrupts hat das Betriebssystem die Möglichkeit einzugreifen, den laufenden Prozess zu unterbrechen, den nächsten zu starten und die Systemuhr zu
- aktualisieren. Ohne diesen Timer Interrupt könnte ein Prozess, der in einer Endlosschleife gerät, die CPU für immer festhalten. Mit ihm hat das
- Betriebssystem immer die Möglichkeit, das Steuer zurückzunehmen, egal was der laufende Prozess tut. Zusätzlich synchronisiert das Betriebssystem die
- Systemzeit über NTP, das Network Time Protocol, also mit weltweiten Zeitservern. So wissen alle Prozesse auf allen Systemen, was die Uhr geschlagen
- hat. Zeit ist im Betriebssystem also keine Nebensache. Sie ist das Fundament, auf dem Scheduling, Logging, Sicherheitszertifikate und verteilte
- Systeme aufbauen. Wir haben ja vorhin darüber gesprochen, dass z.B. Prozesse, die eine Eingabe erwarten, eine höhere Priorität bekommen. Aber woher weiß das
- Betriebssystem eigentlich, wann du eine Taste drückst oder wann ein Netzwerkpaket ankommt oder wann die Festplatte einen Lesevorgang
- abgeschlossen hat? Es könnte permanent nachfragen, also in einer endlosschleife einfach fragen. Wurde eine Taste gedrückt? Nein. Wurde eine Taste
- gedrückt? Nein. Wurde eine Taste gedrückt? Nein. Das nennt man Polling. Und es ist so ineffizient, wie es klingt. Die CPU wäre damit vollständig
- beschäftigt, auf Ereignisse zu warten, statt Arbeit zu erledigen. Stattdessen gibt es Interrupts. Die Hardware sendet ein Signal direkt an die CPU, ein
- Interrupt Request, kurz IRQ. Die CPU unterbricht sofort, was sie gerade tut, sichert ihren aktuellen Zustand und springt zu einem sogenannten Interrupt
- Handler, einem kleinen Stück Code im Kernel, der genau für diesen Interrupt vorbereitet ist. Der Händler läuft, Ereignis wird verarbeitet und der
- Zustand wird wiederhergestellt. Die CPU macht weiter als wäre nichts gewesen. Das Betriebssystem wartet also nicht aktiv auf Hardware. Es lebt sein Leben
- und wenn die Hardware etwas zu sagen hat, unterbricht sie es sofort gezielt und effizient. Dieser Mechanismus, also CPU unterbricht sich, sicher Zustand und
- springt woanders hin, steckt übrigens auch hinter etwas, das wir schon besprochen haben und zwar dem Kontextwechsel. Der Kontextwechsel ist
- das, was Multitasking erst möglich macht und er ist eleganter als er klingt. Wenn das Scheduling entscheidet, Prozess A hat seine Zeitscheibe aufgebraucht,
- jetzt ist Prozess B, dann da muss die CPU den Zustand von A vollständig sichern. Also alle Register, den Programmcounter, der zeigt, wo wir im
- Code gerade waren, den Stackpointer, die Flags und so weiter, alles landet im Speicher. Dann lädt die CPU den gesicherten Zustand von B und läuft
- weiter, als hätte B nie pausiert. Das passiert hunderte Male pro Sekunde. Du merkst davon überhaupt nichts. In Wirklichkeit ist es also extrem
- schnelles Abwechseln. Kein Prozess läuft wirklich gleichzeitig mit einem anderen auf einem einzelnen Kern. Echte Parallelität gibt es nur mit mehreren
- CPU-Kern. Dann laufen tatsächlich mehrere Prozesse zur gleichen Zeit und zwar einer pro Kern. Alles andere ist eine sehr überzeugende Illusion. Wir
- haben also jetzt das Fundament verstanden, also wie ein Betriebssystem intern funktioniert. Lass uns also jetzt mal einen Blick nach außen werfen.
- Welche Betriebssysteme gibt es und warum sind sie so verschieden? Und dabei fokussiere ich mich jetzt erstmal nur auf Linux und Windows. Linux ist ein
- Betriebssystem Kernel, aber es ist mehr als das. Es ist ein Experiment, das bewiesen hat, dass offene Zusammenarbeit funktioniert. Ich habe schon ein
- separates Video zu Linux gemacht. Schaut euch das gerne an, wenn ihr wollt. Der Quellcode ist hier öffentlich. Jeder kann ihn lesen, verändern,
- weiterverteilen. Aus diesem offenen Kern ist ein Ökosystem von hunderten sogenannten Distributionen entstanden. Also Ubunto, Debian, Fedora, Arch Linux.
- Sie alle basieren auf demselben Linux Kernel, unterscheiden sich aber in allem Drumherum, also Paketverwaltung, Desktopumgebung und Zielgruppe. Ubunto
- z.B. für Einsteiger, Arsch für alle, die alles selber kontrollieren wollen, Debian für Stabilität und so weiter. Auf dem Desktop ist Linux eine Minderheit.
- Auf Servern dominiert es. Fast die gesamte Cloud Infrastruktur weltweit läuft auf Linux. Von Amazon über Google bis zu den Systemen hinter den meisten
- Apps auf deinem Telefon. Der Grund ist simpel. Linux ist extrem modular. Du kannst einen minimalen Kernel bauen, der nur das Nötigste macht. Kein grafisches
- Interface, keine unnötigen Dienste und maximale Effizienz. Perfekt für Server, die rund um die Uhr laufen und nie abgelenkt werden wollen. Der Kernel
- selbst ist monolitisch, aber dazu kommen wir gleich. Lass uns noch kurz über Windows sprechen. Windows ist im Grunde das Gegenteil von Linux in fast jeder
- Hinsicht. Es ist close source, kommerziell und ein Unternehmen entscheidet, was im Kernel landet und was nicht. Kein öffentlicher Code, kein
- externer Beitrag, dafür ein klares Ziel. Es muss auf allem laufen. Das ist der Kern von Windows, also Kompatibilität. Windows läuft auf Hardware von hunderten
- Herstellern in Unternehmensumgebungen, die seit Jahrzehnten gewachsen sind mit Software, die manchmal älter ist als manche ihrer Nutzer. Jede neue Windows
- Version muss alte Programme noch ausführen können. Code, der vor 20 Jahren geschrieben wurde, soll heute noch funktionieren. Das hat aber seinen
- Preis. Jahre von Legacy Code, der nie entfernt werden kann, weil irgendwo noch irgendjemand davon abhängt. Der Kernel von Windows ist Windows NT. Er existiert
- in dieser Form seit den frühen 90ern. Er ist gewachsen, erweitert, angepasst worden, aber das Fundament ist dasselbe. Aber warum gibt es überhaupt
- unterschiedliche Betriebssysteme? Na ja, weil es unterschiedliche Probleme und unterschiedliche Ziele gibt. Das klingt offensichtlich, aber steckt mehr
- dahinter, als man zunächst denkt. Ein Betriebssystem ist kein neutrales Werkzeug. Jede Designentscheidung ist ein Tradeoff. Was du gewinnst, gibst du
- irgendwo anders auf. Ein Desktop Betriebssystem optimiert z.B. für den Menschen am Bildschirm, also Benutzeroberfläche,
- Reaktionsgeschwindigkeit, breite Hardwarekompatibilität, ein riesiges Softwareökosystem und so weiter. Der Nutzer soll nie warten, nie verwirrt
- sein, nie etwas installieren müssen, das nicht sofort funktioniert. Wie gut das bei Windows funktioniert, lasse ich jetzt mal im Raum. Ein Server optimiert
- für Maschinen, die mit Maschinen reden, also keine grafische Oberfläche nötig. Dafür maximale Stabilität, Netzwerkleistung und die Fähigkeit,
- tausende gleichzeitige Verbindungen zu verwalten. Der Server soll jahrelang laufen ohne Neustart. Dann gibt es noch Embedded OS für Router, Kameras,
- Industrieanlagen und Co. Security Betriebssysteme, die optimiert sind für Vertrauen, minimale Angriffsfläche und so weiter. Also im Kern unterschiedliche
- Ziele, unterschiedliche Probleme, unterschiedliche Betriebssysteme. Ich möchte nur noch ganz kurz über Kernel Architekturen sprechen. Wir haben Linux
- und Windows angesprochen, aber wir haben noch nicht geklärt, warum sie intern so anders gebaut sind. Das liegt an einer grundlegende Frage im
- Betriebssystemesign. Was gehört in den Kernel und was nicht? Es gibt drei Antworten darauf. Einmal den monolitischen Kernel wie bei Linux.
- Alles läuft im Grunde im Kernel Mode, also Treiber, Dateisystem, Netzwerkstack und so weiter. Ein großer zusammenhängender Block mit vollen
- Rechten. Der Vorteil ist Performance, also direkte Aufrufe, keine teuren Mode Switches zwischen Komponenten und maximale Geschwindigkeit. Der Nachteil
- ist Risiko. Ein Bug in einem Treiber, der im Kernel Mode läuft, kann das gesamte System zum Absturz bringen. Du kennst das vielleicht, der Kernel Panic
- auf Linux. Dann gibt es noch den Micro Kernel. Der Kernel macht nur das absolute Minimum: Prozessverwaltung, Speicherverwaltung und grundlegende
- Kommunikation. Alles andere Treiber, Dateisystem, Netzwerk läuft im User Mode, also normale Prozesse. Der Vorteil: Ein fehlerhafter Treiber stürzt
- nur sich selbst ab. Das System läuft weiter. Der Nachteil: Jede Kommunikation zwischen Komponenten kostet einen Mode Switch. Das summiert sich und macht
- Micro Kernels in der Praxis langsamer. Und zu guter Letzt gibt es hybride Kernel wie Windows NT und MacOS. Ein pragmatischer Kompromiss. Kernfunktionen
- laufen im Kernel Mode für Performance und weniger kritische Teile laufen im User Mode für Sicherheit. kein reines Ideal, aber in der Praxis sehr
- erfolgreich. Wenn du dich fragst, woher der Bluescreen of Death kommt, genau hier. Windows NT ist Hybrid, aber Treiber laufen teilweise trotzdem im
- Kernel Mode. Ein Fehlerhafter Grafiktreiber reicht und das System ist weg. Drei Philosophien, drei Tradeoffs und keine ist falsch. Zum Abschluss ein
- Blick auf etwas, dass wir in diesem Video und in den vorherigen Videos die ganze Zeit implizit genutzt haben, ohne es direkt anzusprechen. Wir haben von
- RAM gesprochen, von Festplatten, von Pages, die rein und rausgeschoben werden, aber wir haben nie gefragt, warum gibt es überhaupt verschiedene
- Arten von Speicher? Warum nicht einfach einen, der schnell, groß und günstig ist? Die Antwort: Na ja, weil es physikalisch nicht möglich ist. Schnelle
- Speicher sind teuer und klein. Großer Speicher hingegen ist langsam und günstig. Das ist kein Designfehler, das ist ein Naturgesetz der
- Halbleitertechnik. Die Lösung ist eine Hierarchie. Ganz oben haben wir Register, die sind direkt in der CPU. Das sind wenige Dutzend Bites, die
- Zugriffszeiten in Nanosekunden ermöglichen. Und hier rechnet die CPU tatsächlich. Darunter haben wir den Cash aufgeteilt in L1, L2 und L3. Das sind
- Kilby bis Megabyes. Die sind nahezu so schnell wie Register. Die CPU hält hier die Daten, die sie gerade oder demnächst braucht. Darunter haben wir den RAM, das
- ist schon Gigabyte Bereich, also deutlich langsamer als der Cash, aber immer noch schnell genug für laufende Programme. Alles, was aktiv genutzt
- wird, soll hier liegen. Ganz unten haben wir Discs, also SSDs, Festplatten und so weiter. Das sind hunderte Gigabytes bis Terabtes. Hier haben wir Millisekunden
- statt Nanosekunden, ein Faktor von 1000 oder mehr. Hier liegt also alles, was dauerhaft gespeichert werden muss, aber die Performance ist sehr, sehr langsam.
- Das Betriebssystem verwaltet diese Hierarchie ständig, ohne dass irgendjemand es bemerkt. Wie vorhin besprochen, wir haben heute eine weitere
- riesige Schicht aufgedeckt und zwar Betriebssysteme. Von der Frage, warum es überhaupt ein Betriebssystem braucht bis zu den Architekturen, die hinter Linux
- und Windows stecken. Bootprozess, Kernel, Prozesse, Threats, Synchronisierung, Scheduling, virtueller Speicher und und alles hängt zusammen
- und alles baut aufeinander auf. Das Betriebssystem ist die unsichtbare Grundlage von allem, was du am Computer tust. Na ja, ganz ganz so unsichtbar ist
- sie nicht, aber jeder Klick, jede Datei, jede Verbindung läuft im Grunde durch die Schichten, die wir heute besprochen haben. Du siehst es nicht immer, aber
- jetzt weißt du, dass es da ist. Und jetzt, wie besprochen die zwei Fragen aus dem letzten Video? Wenn Maschinecode direkt auf die CPU wirkt, warum hat dann
- jedes Betriebssystem seine eigene ausführbare Datei, also Windows und Linux 11? Müsste man die nicht einfach austauschen können? Im Grunde hast du
- recht, aber nur zur Hälfte. Ich habe es eben gerade in diesem Video erst erklärt. Der Maschinencode selbst ist tatsächlich austauschbar, solange die
- CPU Architektur stimmt. Ein X6 Befehl ist ein X86 Befehl, egal ob er in einer Echse oder in einem 11 steckt. Aber eine ausführbare Datei ist mehr als
- Maschinencode. Sie ist ein Container mit einem Format und einer Struktur, die dem Betriebssystem sagt, wo fängt der Code an, wo liegen die Daten und welche
- Bibliotheken brauchst du. Windows kennt z.B. für das Excel Dateienformat Linux nur 11. Nicht weil der Code inkompatibel wäre, sondern weil der Loader des
- jeweiligen Betriebssystems nur sein eigenes Format besteht. Dazu kommt Programme rufen z.B. Betriebssystemfunktion auf, eine Windows
- App ruft z.B. Create File auf, eine Linux App ruft dagegen Open auf. Das sind verschiedene SIS Calls und verschiedene Bibliotheken und somit
- verschiedene Konventionen. Du könntest also den reinen Maschinencode nehmen, aber alles drumherum würde nicht passen. Genau das macht Tools wie z.B. Wine.
- Interessant. Die emulieren nicht die CPU, die emulieren das Windows Drumherum, den Loader, die SISCS und die Bibliotheken. Frage 2: Wir haben gesagt,
- alles sind nur Transistoren, die verschachtelt sind, aber welcher Transistor gibt das erste Signal ab? Irgendwo muss das doch alles anfangen.
- Im Grunde musst du es hier so vorstellen, die Schaltkreise sind physisch so design, dass beim Anlegen von Spannung bestimmte Transistoren
- sofort einen definierten Zustand einnehmen, bevor irgendeine Software auch nur eine Zeile ausführt. Das heißt, per Design, wenn Spannung durchfließt,
- gehen die in bestimmte Zustände. Das ist also kein Code, das ist Schaltungsdesign, also Hardware Logik, die beim ersten Stromfluss automatisch
- die richtige Konstellation erzeugt. Das Ergebnis ist, die CPU zeigt mit ihrem Instruction Pointer, also die Instruktion, die als nächstes ausgeführt
- werden soll, zwangsläufig auf den Resetvektor. Nicht weil jemand es ihm sagt, sondern weil die Schaltung gar nichts anderes zulässt. Der Resetvektor
- ist dann wiederum nur eine Adresse auf X86, wä diese hier und dort liegt typischerweise einzelner Jumpbefehl, der auf den eigentlichen Firmware Code
- weiter verweist und dann passiert das hier, was ich hier schon beschrieben habe. Also das Ganze ist kein Zufall, sondern nur Physik und Design. Und damit
- endet dieses Video hier. Wenn ihr bezüglich Betriebssysteme Fragen habt, dann einfach rein in die Kommentare und ich bin auch mega auf euer Feedback
- gespannt.
Zum Nachlesen
Kernel (Betriebssystem)Ein Kernel (englisch [ˈkɝːnəl], übersetzt Kern), auch Betriebssystemkern (oder verkürzt Systemkern), ist der zentrale Bestandteil eines Betriebssystems.
BetriebssystemBetriebssysteme bestehen in der Regel aus einem Kernel (deutsch: Kern), der die Hardware des Computers verwaltet, sowie speziellen Programmen, die beim Start …
Prozess (Informatik)Ein Prozess ist die Ablaufumgebung für ein Programm auf einem Rechnersystem sowie der darin eingebettete Binärcode des Programmes während der Ausführung. Ein …
MultitaskingDer Begriff Multitasking [ˌmʌltiˈtɑːskɪŋ] (engl.) bzw. Mehrprozessbetrieb bezeichnet die Fähigkeit eines Betriebssystems, mehrere Aufgaben (Tasks) …