Hallo,
Dann hast du die falsche Frage gestellt: Du willst nicht wissen, was ein HAL ist, sondern wie du es konkret implementieren musst.
Nein nein, wie ich in meinem konkreten Projekt den Treibern ermöglichen möchte ihre Geräte zu finden und anzusprechen weiß ich recht genau, die Frage die sich mir stellt: "ist das was ich in meinem OS haben möchte wirklich ein HAL oder ganz was anderes oder eine Mischform?" und deswegen hätte ich gerne eine möglichst allgemeingültige Definition was genau ein HAL in einem typischen OS ist.
Du vergisst den MCA, dort ging das auch. Aber es gab m.W. keine MCA-auf-MCA-Brücken.
Hä, was willst Du damit sagen? Ich vermute das wir beide in diesem Forum (fast) die einzigsten sind die überhaupt eine einigermaßen konkrete Vorstellung vom MCA haben wobei ich ehrlich sagen muss das ich noch nie in meinem Leben MCA-Hardware mit eigenen Augen gesehen oder mit eigenen Händen berührt hab (im Gegensatz zu EISA). Ein seit 20 Jahren totes Bussystem als Gegenbeispiel aufzuführen ist IMHO nicht zweckdienlich. Nebst dessen das MCA zwar P&P hatte aber wimre nicht in der Lange war die Karten ihrer realen physischen Position auf dem Main-Board (Slot-Nummer o.ä.) zuzuordnen.
Es sind trotzdem Busse. Und wenn du eine USB-PCI-Bridge haben könntest, dann liegt dahinter irgendwo trotzdem ein PCI-Bus.
Ich finde Du klammerst Dich zu arg an dem Wort
Bus fest.
Nur weil USB und PCI beides als Busse bezeichnet werden (obwohl beides, zumindest seit PCI-Express, nur reine geswitchte Punkt-zu-Punkt-Verbindungen sind) heißt das noch lange nicht das es dort konzeptionelle Gemeinsamkeiten gibt! PCI kennst Speicher- und IO-Ressourcen und jeder Teilnehmer kann welche anbieten aber auch selbstständig auf die Angebote anderer Teilnehmer zugreifen (der nicht PCI-konforme Teil des PC, also CPUs und Haupt-Speicher, wird hinter der Host-Bridge wegabstrahiert, aus Sicht der restlichen PCI-Komponenten). USB hingegen kennt nur Kommunikations-Pipelines die auch immer mit einem Ende bei einem Host-Controller (quasi der Wurzel des USB-Baums) enden müssen und auch nur der Host kann von sich aus aktiv werden alle Devices müssen grundsätzlich auf das Polling vom Host warten (ja ich weiß es gibt noch USB-2-Go aber das macht wimre auch nicht so viele Änderungen an den USB-Grundkonzepten). Zwischen PCI und USB gibt es IMHO keine funktionalen Übereinstimmungen so das es wohl absoluter Blödsinn ist beide hinter einer gemeinsamen Abstraktion zu verstecken, nebst dessen das es keine Geräte mit identischer Ansteuerung für PCI und USB gibt (geht einfach nicht da die Konzepte zu unterschiedlich sind). Noch nicht einmal die Vendor-IDs sind identisch vergeben so das man schon bei den elementarsten P&P-Funktionen zwischen PCI und USB unterschieden muss.
PCI mit I²C oder SPI in einen Topf zu werfen macht IMHO noch viel weniger Sinn da die Unterschiede nur noch mehr werden.
Um mal das Beispiel der USB-PCI-Bridge zu nehmen: Wenn du soetwas anschließt und dieses Teil als PCI-Bus an dein Betriebssystem einbindest und alle Treiber für PCI-Geräte funktionieren damit, dann hast du eine Busabstraktion (Hardwareabstraktion für PCI), also ein HAL, den du im Gerätetreiber für diese Bridge implementierst. Eine weitere Implementation des gleichen HALs liegt dann im Kernel für den normalen, CPU-erreichbaren, MMIO-addressierbaren PCI-Bus.
Wenn man wirklich PCI über USB tunneln möchte (was sicher irgendwie funktionieren könnte wenn auch nicht sonderlich gut) dann wäre dieser Tunnel für die PCI-Hardware und die Treiber völlig transparent (also aus PCI-Sicht unsichtbar), anders lassen sich Dinge wie Busmasterring oder klassische Interrupts der Geräte hinter dem Tunnel nicht realisieren. Klar benötigt dieser Tunnel eine Konfiguration aber ein HAL ist das IMHO absolut nicht (weil ja für die PCI-Geräte und PCI-Treiber alles so bleibt wie es die PCI-Spec festlegt).
Ich nehme an Du meinst den Zugriff auf den PCI-Config-Space. Ja der sollte immer über einen Service vom OS-Kernel laufen und zwar nicht nur wegen der Portabilität sondern auch weil diese Zugriffe serialisiert werden müssen.
Damit hast du schlagartig ein HAL für PCI erfunden. Es abstrahiert zwar nur PCI, aber es macht PCI-Gerätetreiber (theoretisch) unabhängig von der Hardware, in der der PCI-Bus verbaut ist.
Das ist maximal ein HAL für den PCI-Config-Space aber nicht für PCI als ganzes.
hatte im Kopf eine Menge #defines, welche die Pins und die GPIOs angeben, an denen der Baustein angeschlossen ist. Prinzipiell ist das auch schon ein "HAL". Denn es macht den USB-Treiber unabhängig von den konkreten Pins des Microcontrollers.
Hm, also wenn das schon als HAL zählt dann ist der HAL wirklich einfach eine recht freie Sache die jedes OS für sich individuell definieren kann.
Das soll keine Wertung des Mikrocontroller-Codes sein, so oder so ähnlich hätte ich das sicher auch realisiert, aber es zeigt eben dass das was man unter einem HAL versteht doch sehr differenziert sein kann.
In deinem konkreten Fall brauchst du keine extra deklarierte HAL, da du genau eine Architektur hast. Und da bei dir ja alles MMIO-adressierbar ist, reicht also ein Syscall "gib mir physischen Speicher" für die systemweise HAL aus.
Falls ich mein OS jemals auf x86 portieren sollte (was sich nicht lohnt weil Segmentierung im 64Bit-Modus ja leider abgeschafft wurde also nur ein reines 32Bit-System entstehen kann) dann sehe ich momentan keine konzeptionellen Hindernisse, ich denke das alles was ich bis jetzt an Konzepten entwickelt habe auch auf x86 funktionieren würde (wenn auch vieles davon nicht so elegant wie auf einer HW die speziell nach meinen Wünschen designt wurde).
Die HAL für USB wird bei dir schon etwas dicker werden; optimalerweise ist sie sämtlicher Code, der in jedem Treiber vorhanden sein muss.
Ich hoffe nicht das ich identischen Code in allen Treibern haben muss (automatisch generierte IPC-Stubs zählen da jetzt mal nicht), das ist ja gerade das was ich mit einer Abstraktion vermeiden will.
Ich würde sogar soweit gehen, bestimmte Treiber mit in den HAL zu packen. So wäre ein Bsp. für nen HAL der Timer-Treiber....
Treiber sind kein HAL - HAL ist eine Hardwareabstraktionsschicht.
Das heißt also der HAL abstrahiert z.B. den PCI-Config-Space aber benutzt seinerseitz wieder einen austauschbaren Treiber der dann den Zugriff tatsächlich durchführt? Aber was bleibt dann für den HAL selber übrig?
Die Summe aller solcher APIs, die jeweils ein Stückchen Hardware abstrahieren, ist der HAL.
Das trifft aber auch auf Treiber zu oder auf das OS als ganzes (aus Sicht der Applikationen).
Wie willst du eine Abstraktion allgemein erklären? Es geht schließlich auch ohne...
Nur weil man ohne eine Abstraktion auskommen kann heißt das IMHO nicht das man eine Abstraktion nicht erklären könnte.
Aber ich merke das meine Frage einen ungeahnten Schwierigkeitsgrad hat.
Ein Treiber für den Interruptcontroller führt einfach zu sauberer Programmierung; der Kernel selbst (als privilegiertes Medium; ja ich weiß, monolithisches Denken) könnte ja auch ständig direkt in dessen Registern rumpfuschen und fröhlich Interrupts hooken, ohne den Überblick zu verlieren.
Der eigentliche Kernel hat aber für die HW-IRQs gar keine Verwendung, der muss diese an die Treiber weiter vermitteln und mit einer möglichst guten API anbieten. IRQs müssen IMHO auf allen größeren CPU-Architekturen durch den Kernel gehen weil die ja immer einen Modus-Wechsel verursachen (ja ich weiß das x86 da mit seinen Task-Gates eine Sonderrolle einnimmt).
So ähnlich funktioniert mein System auf dem Microcontroller, aber da gibt es nur drei relevante Interrupts, kein IRQ-Sharing und nur 64K RAM. Und der Code ist von der Menge her noch erträglich.
Klar, weil Du ein sauber abgetrenntes System hast, aber das ist nicht mit einem General-Purpose-OS vergleichbar.
Der typische Benutzer sieht ein Fenster mit Word drin und der Computer ist "der graue Kasten unterm Tisch". Es geht ihm nicht darum, die Maus zu bewegen, sondern er "klickt auf den Druckerbutton und dann kommt bedrucktes Papier aus dem Drucker".
Sorry, aber das kannst Du Deiner Oma so erklären,
hier sind wir auf
lowlevel.eu und da ist diese Art von Erklärung IMHO weniger geeignet.
SCNR
Dein Ziel ist es aber, die Anwendung zu bedienen.
Absolut richtig, trotzdem kann ich als OS-Dever nicht den langen und komplizierten Weg der Informationen vom User bis zur eigentlichen Applikation und zurück ignorieren.
Der Benutzer bedient Hardware, die wiederum einen Treiber erfordert, damit sie mit dem Betriebssystem kommunizieren kann und am Ende der Kette sitzt die Anwendung, die dann die entsprechende Aktion ausführt.
Exakt.
Hm, es gibt zwei Teilaspekte ....
Eben genau deswegen ist es offensichtlich so enorm schwierig den HAL als Einzel-Komponente exakt zu definieren. Was wir als HAL betrachten das hängt sehr davon ab aus welcher Richtung wir schauen und wie das umgebende OS aufgebaut ist.
Es erscheint mir wirklich so das die Definition des HAL eine sehr subjektive und dehnbare Angelegenheit ist. Ich bin also einer Antwort auf meine ursprüngliche Frage nicht wirklich näher gekommen, schade. Ich danke Euch trotzdem für Eure Mithilfe.
Grüße
Erik