Grundlagenfragen zu (System)Programmierung



  • Hallo liebe Community

    Ich habe einige grundlegende Verständnisfragen zur Programmierung und hoffe dass ihr mich ein etwas aufklären könnt. Hierfür möchte ich ein wenig ausholen.

    Früher waren die Computer vom Prinzip her zwar genau gleich, aber doch einfacher - da weniger Komponente etc. Daher denke ich mir immer, dass es damals für die Leute die sich dafür interessiert hatten, viel einfacher gewesen sein muss Computer von Grund auf zu verstehen. Beschäftigt man sich heute damit, muss man eine Menge an Wissen nachholen. Wenn ich mir beispielsweise die Geschichte von Linux anschaue - im Hinblick auf die Entwicklung des Kernels - stellen sich mir einige Fragen.

    Frage 1:

    Der Kernel stellt - unteranderem - eine Schnittstelle zwischen der Hardware und der Software. Um diese Schnittstelle zu realisieren, benötigt es Kenntnisse darüber, wie mit dieser Hardware zu kommunizieren ist. Woher kriegt man diese Informationen?

    Der Kernel ist so grundlegend, dass diesem gar kein Fundament zu Verfügung steht. Im Gegenteil, er soll das Fundament darstellen.

    Frage 2:

    Der Linux Kernel wurde in C geschrieben (mit Hilfe des Minix OS - als Umgebung quasi) und wurde anschliessend mit einem entsprechenden Compiler, für den Prozessor auf dem das Ganze laufen soll, übersetzt Wie bringt man es nun zustande, dieses Programm auszuführen / zu booten? Über ein Laufwerk geht das ja wohl schlecht - da dies zu diesem Zeitpunkt noch gar nicht lauffähig ist.

    Frage 3:

    Gibt es für mich eine Möglichkeit, die Sicht der Dinge aus der damaligen Zeit nachvollziehen zu können, indem man mit einem einfachen Programmierboard oder einem Emulator eine solche Umgebung schaffen kann um darauf Grundbausteine zu entwickeln?

    Bin für jede Antwort sehr dankbar 🙂

    Gruss



  • anneXus schrieb:

    Frage 1:(...)Woher kriegt man diese Informationen?

    Vom Hardwarehersteller, aus offenen Standards, aus nicht-so-offenen Standards (wenn man die entsprechenden Verträge unterschreibt), durch Reverse-Engineering oder aus der Lektüre von Code der auch mit dieser Hardware umgehen kann (z.B. Open Source Kernels/Treiber).

    anneXus schrieb:

    Frage 2:(...)Über ein Laufwerk geht das ja wohl schlecht - da dies zu diesem Zeitpunkt noch gar nicht lauffähig ist.

    Wieso sollte das nicht lauffähig sein? Jeder PC hat ein BIOS (oder EFI oder sonst ein Boot-ROM). Und da ist Code drinnen, mit dem alle möglichen Boot-Datenträger gelesen werden können.
    Dieser Boot-Code im ROM des PCs sorgt dafür dass ein Teil des OS geladen wird. Auf BIOS Systemen ist das typischerweise der erste Block eines Datenträgers, der auch oft als Boot-Block bezeichnet wird. Auf BIOS Systemen kann der darin befindliche Code dann über vom BIOS zur Verfügung gestellte Funktionen weitere Blöcke von diesem Datenträger nachladen. Wie es mit EFI genau geht weiss ich nicht, aber etwas ähnliches wird es dort wohl auch geben.

    Bzw. falls das deine Frage war: du brauchst auf jeden Fall irgend einen "Bootstrapper" Code in einem ROM. (Bzw. in irgend einem Speicher der bei "power on" nicht erst beschrieben werden muss um den gewünschten Code zu enthalten. Das muss natürlich nicht zwingend ein ROM sein, kann auch irgend ein NVRAM sein.) Dieses ROM muss in den Adressraum der CPU eingeblendet sein. Und zwar genau an der Adresse wo die CPU beim "power on" loslegt. Dazu müssen natürlich sämtliche beteiligten Chips passende "power on" Defaults haben.

    anneXus schrieb:

    Frage 3:

    Gibt es für mich eine Möglichkeit, die Sicht der Dinge aus der damaligen Zeit nachvollziehen zu können, indem man mit einem einfachen Programmierboard oder einem Emulator eine solche Umgebung schaffen kann um darauf Grundbausteine zu entwickeln?

    Was genau willst du verstehen/nachvollziehen? Und wie viel Zeit willst du dafür opfern?
    Wenn du nur wissen willst wie man es anstellt ein OS auf ner PC Plattform zu booten, dann schlage ich vor im "Projekt: OS-Development" Forum zu fragen.
    Ein Emulator den man dafür verwenden kann ist "Bochs x86".
    Eine andere Möglichkeit wäre VirtualBox. Wobei du mit "Bochs x86" vermutlich besser alte Hardware emulieren kannst.
    ps: QEMU als Emulator wäre auch eine Möglichkeit.



  • hustbaer schrieb:

    anneXus schrieb:

    Frage 1:(...)Woher kriegt man diese Informationen?

    Vom Hardwarehersteller, aus offenen Standards, aus nicht-so-offenen Standards (wenn man die entsprechenden Verträge unterschreibt), durch Reverse-Engineering oder aus der Lektüre von Code der auch mit dieser Hardware umgehen kann (z.B. Open Source Kernels/Treiber).

    Ich habe die Frage eher so verstanden, dass der TE meint, der Kernel würde diese Informationen irgendwie zur Laufzeit bekommen oder zusammensuchen. Das wär natürlich falsch und die Antwort von hustbaer ist richtig. Der Kernel "weiß" schon, was er zu tun hat. Die grundlegenden Schnittstellen sind alle spezifiziert. Für konkrete Geräte gibt es dann gerätespezifische Treiber, bzw. unter Linux Kernelmodule. Es gibt z.B. den IPC Bus, und den kann man enumerieren. Damit findet man alle Geräte (und das können auch interne Chips auf dem Mainboard sein, z.B. ein USB Controller) und kriegt dann raus, was das Geräte sind (über IDs). Dann wird ein Treiber geladen, der schon weiß, wie man mit diesem Gerät kommuniziert. Sagen wir, du hast irgendwelche LEDs in deinem Notebook. Und die kann man an- und ausmachen, indem man bestimmte Werte in ein Geräteregister schreibt. Bei einem Lenovo Notebook könnten das ganz andere Werte und Register als bei einem HP Notebook sein. Aber der entsprechende Treiber weiß das schon.
    Woher der Treiberentwickler das weiß hat hustbaer ja schon geschrieben.


  • Mod

    anneXus schrieb:

    **Frage 1:**Der Kernel stellt - unteranderem - eine Schnittstelle zwischen der Hardware und der Software. Um diese Schnittstelle zu realisieren, benötigt es Kenntnisse darüber, wie mit dieser Hardware zu kommunizieren ist. Woher kriegt man diese Informationen?

    Die Leute, die Hardware bauen, wollen, dass diese benutzt wird. Sie halten sich entweder an bekannte Standards; veröffentlichen die Spezifikationen; oder stellen selber Programme zur Verfügung (Treiber), damit die Hardware genutzt werden kann.

    Frage 2:

    Der Linux Kernel wurde in C geschrieben (mit Hilfe des Minix OS - als Umgebung quasi) und wurde anschliessend mit einem entsprechenden Compiler, für den Prozessor auf dem das Ganze laufen soll, übersetzt Wie bringt man es nun zustande, dieses Programm auszuführen / zu booten? Über ein Laufwerk geht das ja wohl schlecht - da dies zu diesem Zeitpunkt noch gar nicht lauffähig ist.

    Doch, genau so macht man das. Das BIOS bekommt ein Laufwerk angesprochen. Wie kommt das BIOS in den Computer? Das ist quasi fest eingebrannt auf einem der Chips. Dies ist auch eine Möglichkeit, Software in einen Computer zu bekommen, wenn man zum Beispiel für Geräte entwickelt, die keine Laufwerke haben. Dann wird die Software eben direkt in das Gerät überspielt.

    Frage 3: Gibt es für mich eine Möglichkeit, die Sicht der Dinge aus der damaligen Zeit nachvollziehen zu können, indem man mit einem einfachen Programmierboard oder einem Emulator eine solche Umgebung schaffen kann um darauf Grundbausteine zu entwickeln?

    Sicht aus welcher Zeit? Grundbausteine für was? Wenn wir mal von etwas ausgehen, das irgendwie unter den Begriff Mikrocomputer passt (auf PCs brauchen wir uns also gar nicht zu beschränken), dann sind die im Groben alle gleich. Was du über die Grundlagen der Kernelentwicklung für den Atari ST lernen kannst, das kannst du auch an einem heutigen Computer lernen (siehe z.B. Subforum OS-Development). Wenn du noch Grundlegenderes lernen willst: Was denn? Das Wesentliche habe ich gerade erklärt, so spannend ist das nicht.

    edit: Oh, viel zu spät.



  • Ach so, Informationen darüber was in einem PC für Geräte/Chips drinstecken gibt es auf verschiedensten Wegen.

    Für Legacy-Hardware gibt es erstmal gewisse Dinge von denen man einfach ausgeht. Also dass an Port so-und-so ein Keyboard Controller zu finden ist, den man über Bit so-und-so dazu veranlassen kann die Reset Leitung der CPU zu ziehen uswusf.

    Dann gibt es die Plug-and-Play Tables im BIOS. D.h. an bestimmten Adressen gibt's Tabellen in denen Informationen über diverse Geräte verzeichnet sind.

    Und sobald man mal die Bus-Treiber am Laufen hat (PCI, PCIe, USB, ...) kann man diese verwenden um die Geräte zu enumerieren, und diverse IDs zu den Geräten auszulesen. Also z.B. Class-IDs und Vendor/Product IDs.

    Wie das alles im Detail funktioniert weiss ich nicht. Lässt sich aber auch aus den selben Quellen in Erfahrung bringen die ich bereits genannt habe.



  • Mechanics schrieb:

    Es gibt z.B. den IPC Bus, und den kann man enumerieren.

    Was issn das? Nie gehört. Haste nen Link dazu?



  • anneXus schrieb:

    Frage 1:[list]Der Kernel stellt - unteranderem - eine Schnittstelle zwischen der Hardware und der Software. Um diese Schnittstelle zu realisieren, benötigt es Kenntnisse darüber, wie mit dieser Hardware zu kommunizieren ist. Woher kriegt man diese Informationen?

    Die Informationen liefern die Prozessorhersteller (Intel, AMD, Via usw.) bzw. diejenigen, die die Prozessorarchitektur (ARM, Intel, TI) entworfen haben.

    Wenn man die Opcodes kennt, also diese Informationen hat, dann kann man dafür auch Assembler schreiben und sobald man Assembler hat, kann man darauf basierend
    ein OS oder einen C Compiler schreiben um z.B. dann das OS in einer Hochsprache für die Systemprogrammierung wie z.B. C zu entwerfen.

    Frage 2:

    Der Linux Kernel wurde in C geschrieben (mit Hilfe des Minix OS - als Umgebung quasi) und wurde anschliessend mit einem entsprechenden Compiler, für den Prozessor auf dem das Ganze laufen soll, übersetzt Wie bringt man es nun zustande, dieses Programm auszuführen / zu booten? Über ein Laufwerk geht das ja wohl schlecht - da dies zu diesem Zeitpunkt noch gar nicht lauffähig ist.

    Doch, das Laufwerk ist lauffähig.
    Diese Aufgabe übernimmt das BIOS bzw. UEFI, welches z.B. auf den MBR der Festplatte oder bei Disketten auf den 1. Sektor zeigt.

    Natürlich gibt's da noch kein Dateisystem, die Logik ist daher entsprechend dumm, denn es wird der Code bei einer bestimmten Anfangsadresse ausgeführt.

    Der Code kann z.B. ein Bootloader sein und der läd dann entweder einen anderen OS Kernel oder er ist so intelligent und komplex, dass er sogar Dateisysteme lesen und von da den OS Kernel lesen kann.
    Normalerweise kann ein Bootloader kein Dateisystem lesen, deswegen wird die Einsprungsadresse an dem die Kerneldatei liegt, im Bootloader gespeichert.
    Dies ist auch der Grund, warum man normalerweise Kerneldateien unter /boot nicht verändern oder verschieben kann, ohne die Informationen für die Bootloader lilo oder grub upzudaten.

    Frage 3:

    Gibt es für mich eine Möglichkeit, die Sicht der Dinge aus der damaligen Zeit nachvollziehen zu können, indem man mit einem einfachen Programmierboard oder einem Emulator eine solche Umgebung schaffen kann um darauf Grundbausteine zu entwickeln?

    Klar, kauf dir ein Embeddded Board eines µC und lade dir die Handbücher über die Architektur herunter.

    Prinzipiell kannst du das aber auch schon bequem mit einem Emulator machen.
    Lade dir z.B. den x86 Emulator Bochs herunter und schreibe deinen eignen Bootloader der dann ein OS Starten soll.

    Der Vorteil von Bochs gegenüber einem Embedded Board ist, dass es wesentlich einfacher ist, denn du hast ja einen Bildschirm und somit eine Ausgabe.
    So etwas ist bei einem Embedded Board nicht immer vorhanden und wenn doch, dann ist das oft nur ein 2*20 Zeichen Textdisplay.
    Kaputt machen kannst du mit einem Emulator bei deinem PC auch nichts und trotzdem kannst du x86 Code lernen.

    Der Nachteil ist allerdings, dass so etwas heute nur noch in seltenen Fällen auf dem PC gebaucht wird.
    Also wenn du einen Bootloader oder ein OS schreiben willst.
    Ein Embedded Board mit µC erlaubt dir hier kleine Embedded Hardware für alles mögliche zu verwenden, wo kein PC verfügbar ist oder zu teuer ist.

    Noch einfach ist es aber, wenn du einfach Assmeblerprogrammierung lernst, dann bist du schon ziemlich nah an der HW.



  • Erstmal danke an alle für eure Antworten.

    hustbaer schrieb:

    Was genau willst du verstehen/nachvollziehen? Und wie viel Zeit willst du dafür opfern?
    Wenn du nur wissen willst wie man es anstellt ein OS auf ner PC Plattform zu booten, dann schlage ich vor im "Projekt: OS-Development" Forum zu fragen.

    Einiges wurde durch eure Antworten sehr gut verständlich. Worum es mir geht, ist dass, das ich verstehen möchte wie man aus "lebloser" Hardware ein derartiges Zusammenspiel durch Software erreicht und vor allem wo der Initialpunkt ist.

    Zu der Frage wie viel Zeit ich hier einstecken möchte. Da es zu meinem Beruf gehört - zwar überhaupt nicht mein Schwerpunkt, aber mich doch sehr interessiert - bin ich natürlich bereit mich mit diesem Thema intensiver zu beschäftigen. Allgemein mit der Programmierung. Der Thread bezieht sich zwar auch auf andere Punkte aber nur weil ich das als Grundlage hierfür empfinde.

    Mechanics schrieb:

    Ich habe die Frage eher so verstanden, dass der TE meint, der Kernel würde diese Informationen irgendwie zur Laufzeit bekommen oder zusammensuchen.

    Nein, dass der Kernel bereits wissen muss wie mit der Hardware zu kommunizieren ist bzw. das Protokoll kennen, ist mir bewusst.

    Könnt ihr für den Einstieg in dieses Thema ein bestimmtes Buch empfehlen? Bzw. allgemein vor dem Einstieg in die Programmierung? Ich habe manchmal das Gefühl dass es nicht viel bringt vertieft beispielsweise C++ zu lernen, wenn eventuell noch andere Kenntnisse fehlen. Für C++ habe ich bereits den C++ Primer.


  • Mod

    anneXus schrieb:

    Könnt ihr für den Einstieg in dieses Thema ein bestimmtes Buch empfehlen?

    Literatur, wie ein Computer funktioniert? Die Frage ist zu unklar, um konkrete Empfehlungen zu geben.



  • SeppJ schrieb:

    Literatur, wie ein Computer funktioniert? Die Frage ist zu unklar, um konkrete Empfehlungen zu geben.

    Nein. Grundsätzlich geht es mir um Programmierung. Daher formuliere ich mal die Frage anders. Was für Vorkenntnisse wären hilfreich und interessant beim Einstieg in die Programmierung (evntl. Mathematik etc.)? Wissen über die Funktionsweise eines Computers ist vorhanden - das ist nicht der Punkt.


  • Mod

    anneXus schrieb:

    Was für Vorkenntnisse wären hilfreich und interessant beim Einstieg in die Programmierung (evntl. Mathematik etc.)?

    Eigentlich gar nichts, außer Grundfertigkeiten beim Bedienen eines Computers und hilfreicherweise auch über die grundlegende Funktion (nicht zwingend notwendig, aber nützlich). Gerade die Dinge, nach denen du hier im Thread gefragt hast, dürften ungefähr 0 Relevanz beim Programmieren haben, außer, du entscheidest dich irgendwann in ferner Zukunft mal, mit an einem Betriebssystemkernel zu programmieren.

    Mathematik ist natürlich immer überall nützlich.



  • hustbaer schrieb:

    Mechanics schrieb:

    Es gibt z.B. den IPC Bus, und den kann man enumerieren.

    Was issn das? Nie gehört. Haste nen Link dazu?

    Ja ja, ich meinte natürlich PCI. Aber ich denke von "IPC" im Sinne von Interprocess Communication hast du schon was gehört? Man kann in jede diese Abkürzungen viel reininterpretieren.

    anneXus schrieb:

    Nein. Grundsätzlich geht es mir um Programmierung. Daher formuliere ich mal die Frage anders. Was für Vorkenntnisse wären hilfreich und interessant beim Einstieg in die Programmierung (evntl. Mathematik etc.)? Wissen über die Funktionsweise eines Computers ist vorhanden - das ist nicht der Punkt.

    Versteh ich nicht ganz. Du sagst, das wär dein Beruf. Was genau, Hardware oder Programmierung? Wenn Programmierung, dann solltest du doch wissen, was man da für Vorkenntnisse braucht? Oder meinst du "Systemprogrammierung" (ein sehr schwammiger Begriff) im Speziellen? Dafür braucht man sicher keine Mathematik und muss auch nicht mal besonders viel programmieren können, eher robust programmieren. Du brauchst hauptsächlich C und Assembler.
    Wahnsinnig viele Vorkenntnisse braucht man nicht. Ich musste in einem Projekt was in ein spezielles BIOS einbauen, war jetzt auch überhaupt nicht mein Schwerpunkt damals. Das ist alles sehr plattformspezifisch, man muss die fetten Dokus vom Mainboard und Prozessorhersteller durchwühlen und sich die Infos zusammensuchen, die man braucht. Ist natürlich ein tolles Gefühl, wenn es dann mal funktioniert, ist aber nichts, was ich unbedingt öfters machen wollen würde. Weil die Kenntnisse kaum wiederverwendbar sind. Bei der nächsten Plattform sind die Register, Adressen und Werte wieder komplett anders und das was du über die eine Plattform weißt (wenn du es nicht sofort wieder verdrängt hast), hilft bei der nächsten Plattform kaum weiter.



  • anneXus schrieb:

    Was für Vorkenntnisse wären hilfreich und interessant beim Einstieg in die Programmierung (evntl. Mathematik etc.)? Wissen über die Funktionsweise eines Computers ist vorhanden - das ist nicht der Punkt.

    Wie beim Auto ("Was für Vorkenntnisse wären hilfreich und interessant beim Einstieg in das Autofahren"): Einsteigen und losfahren, das Weitere gibt sich.

    Wenn Du "alte" Technik erschmökern willst, rate ich zu PC-Intern von Michael Tischer (3. Aufl.):

    http://www.amazon.de/PC-Intern-3-0-Michael-Tischer/dp/3890115918/ref=sr_1_2?s=books&ie=UTF8&qid=1386105043&sr=1-2

    Die späteren Auflagen beschäftigen sich mehr mit Windows-Programmierung, nicht ganz uninteressant, aber da gibt es mittlerweile bessere/ausführlichere Lektüre. Wenn Du es schaffst, eine MSDOS-Umgebung auf Deinen Computer zu bringen (was möglich ist) und die alten Programme (Turbo Pascal, Turbo Assembler) auftreiben kannst, kannst Du das Buch auch direkt als Lehrbuch verwenden. An den Prinzipien hat sich im Großen und Ganzen nichts geändert.

    viele grüße
    ralph



  • Mechanics schrieb:

    hustbaer schrieb:

    Mechanics schrieb:

    Es gibt z.B. den IPC Bus, und den kann man enumerieren.

    Was issn das? Nie gehört. Haste nen Link dazu?

    Ja ja, ich meinte natürlich PCI.

    Oki, dann klar mir die Sache ist.

    Aber ich denke von "IPC" im Sinne von Interprocess Communication hast du schon was gehört? Man kann in jede diese Abkürzungen viel reininterpretieren.

    Hihi, ja, sicher. Aber "IPC Bus" macht in dem Zusammenhang auch mit IPC=Interprocess Communication keinen Sinn 😉



  • Wissen über die Funktionsweise eines Computers ist vorhanden

    Anscheinend weniger als durch deinen "Beruf" erwartet. Einstiegspunkt ist der Bootsektor. Anfang ist: Schreiben eines kleinen Programmes, dass beim Start durch eine Bootdiskette ausgefuehrt wird und eine Nachricht am Bildschirm ausgibt, bsp. Hallo Welt.



  • rkhb schrieb:

    Wenn Du "alte" Technik erschmökern willst, rate ich zu PC-Intern von Michael Tischer (3. Aufl.):

    Vielen Dank für den Tipp.

    knivil schrieb:

    Wissen über die Funktionsweise eines Computers ist vorhanden

    Anscheinend weniger als durch deinen "Beruf" erwartet. Einstiegspunkt ist der Bootsektor. Anfang ist: Schreiben eines kleinen Programmes, dass beim Start durch eine Bootdiskette ausgefuehrt wird und eine Nachricht am Bildschirm ausgibt, bsp. Hallo Welt.

    Dass der Bootsektor als erstes für den Start gelesen wird, ist mir natürlich bewusst. Aber danke für deinen Tipp.

    Gruss
    annexus



  • Alles wichtige ist, was passiert dann ...



  • Suchst du etwas wie Write Great Code von Randall Hyde (No Starch Press)?



  • Lade dir Bochs als virtuelle Maschine runter, lern x86 Assembler und mach deine ersten Versuche im Bootsektor (512byte) der virtuellen Diskette von Bochs.

    Der Code im Bootsektor ist der erste Teil, der von dir stammt, alles davor erledigt die Firmware des Computers.
    Die macht aber auch nichts anderes, als dass sie die 512 byte von der Diskette in den RAM kopiert und dann diesen Code ausführt.



  • lalalalal schrieb:

    Der Code im Bootsektor ist der erste Teil, der von dir stammt, alles davor erledigt die Firmware des Computers.

    Muss nicht sein, ich hab auch schon mal am BIOS vom Bochs rumgebastelt.


Anmelden zum Antworten