Autor Thema: Was genau ist eigentlich ein "Hardware Abstraction Layer" in einem OS?  (Gelesen 18673 mal)

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
Hallo,


ich habe in den letzten Tagen versucht die Frage aus dem Betreff für mich persönlich zu beantworten und bin dabei leider nicht zu einem ordentlichen/eindeutigen Ergebnis gekommen.

In den entsprechenden Wikipedia-Artikeln (deutsch wie englisch) finden sich teilweise widersprüchliche aber auch teilweise sehr weit gefasste Erklärungen.

Zählt schon ein Mechanismus der einem Treiber die physische Adresse von Geräte-Speicher verrät (so das der Treiber dann direkt mit seiner HW sprechen kann) als HAL oder muss ein richtiger HAL wirklich als "Vermittler" zwischen Treiber und Hardware fungieren (so das der Treiber für jeden HW-Zugriff durch den HAL muss)? Oder zählt eher der OS-Kernel zusammen mit den Treibern als HAL auf dem dann die normalen Programme laufen können ohne sich um HW-Details sorgen zu müssen?


Ich würde dazu gerne mal Eure Meinungen lesen.
Was muss ein HAL Eurer Meinung nach mindestens können damit er diesen Namen verdient?


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
Keine Ahnung. Meine Systeme hatten deswegen auch nie einen Teil, der HAL heißt. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
Für mich ist der HAL der Teil eines Kernels, der ihn portierbar macht. Sieht ungefähr so aus:
               << Benutzer
+-----------+
| Anwendung |
+-----------+
               << Userspace-API (z.B. POSIX)
+-----------+
| Kernel    |
+-----------+
               << Kernel-API (z.B. CDI)
+-----------+
| Treiber   |
+-----------+
               << HAL
+-----------+
| Hardware  |
+-----------+
               << Halbleiter
Ein Beispiel ist die Abstraktion eines Bussystems, so dass ein einziger NE2000-Treiber für ISA-, MCA-, PCMCIA-, CardBus- und PCI-Varianten dieser Netzwerkkarten verwendet werden kann.

Der HAL muss nicht als Extrastück existieren, sondern kann auch im Kernel selbst drin sein, ohne so genannt zu werden; es geht auch komplett ohne HAL, dann ist Kernel bzw. Treiber halt nicht ohne weiteres portabel.

Gruß,
Svenska

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
Hallo,


Keine Ahnung.
Ich muss zugeben das mich diese Antwort etwas beruhigt, ich bin also nicht der einzigste der das nicht weiß.


Für mich ist der HAL der Teil eines Kernels, der ihn portierbar macht. Sieht ungefähr so aus: .....
Ein hübsches Diagramm, aber es sagt mir leider nicht was der HAL genau macht. Gibt er nur ne physische Adresse an den Treiber oder muss der Treiber für alle Zugriffe den HAL benutzen?
(das der Kernel zwischen den Anwendungen und den Treibern sitzt ist wohl Deinem eher monolithischem Welt-Bild zuzuschreiben ;) )

Ein Beispiel ist die Abstraktion eines Bussystems, so dass ein einziger NE2000-Treiber für ISA-, MCA-, PCMCIA-, CardBus- und PCI-Varianten dieser Netzwerkkarten verwendet werden kann.
Mit "Abstraktion eines Bussystems" meinst Du wohl "gibt nur ne physische Adresse an den Treiber" oder?
Aber was nützt das? Welche HW (außer die NE2000) gibt es mit identischer Ansteuerung für unterschiedliche Bus-Systeme?

Der HAL muss nicht als Extrastück existieren, sondern kann auch im Kernel selbst drin sein, ohne so genannt zu werden; es geht auch komplett ohne HAL, dann ist Kernel bzw. Treiber halt nicht ohne weiteres portabel.
Also zumindest das "gibt nur ne physische Adresse an den Treiber" sollte man IMHO nicht weglassen, wenn die Treiber anfangen würden selber z.B. im PCI-Config-Space rum zu murkeln dürfte es recht schnell Probleme geben (auf den PCI-Config-Space kann üblicherweise nicht parallel zugegriffen werden).


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
Zählt schon ein Mechanismus der einem Treiber die physische Adresse von Geräte-Speicher verrät (so das der Treiber dann direkt mit seiner HW sprechen kann) als HAL oder muss ein richtiger HAL wirklich als "Vermittler" zwischen Treiber und Hardware fungieren (so das der Treiber für jeden HW-Zugriff durch den HAL muss)?
Inwiefern ist der Unterschied relevant?

Zitat
Oder zählt eher der OS-Kernel zusammen mit den Treibern als HAL auf dem dann die normalen Programme laufen können ohne sich um HW-Details sorgen zu müssen?
Das kann man sicher auch so verwenden, aber sicher nicht beim OSDev, sondern eben aus Userspacesicht.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
Hallo,

Ein hübsches Diagramm, aber es sagt mir leider nicht was der HAL genau macht. Gibt er nur ne physische Adresse an den Treiber oder muss der Treiber für alle Zugriffe den HAL benutzen?
Das ist ein Implementierungsdetail. Der HAL ist eine Abstraktionsschicht, kein festgelegtes Protokoll. Für verschiedene Ebenen kann es auch unterschiedlich aufgebaut sein; bei ISA-/PCMCIA-Geräten wirst du neben "Adressraum" auch "I/O-Raum" und "DMA-Leitung" abstrahieren müssen, was bei PCI natürlich nicht zielführend ist.

(das der Kernel zwischen den Anwendungen und den Treibern sitzt ist wohl Deinem eher monolithischem Welt-Bild zuzuschreiben ;) )
Meinetwegen reden die Anwendungen auch direkt mit dem Treiber, aber der muss irgendwie auf die Hardware zugreifen. Und das tut er über den HAL, wie ist egal. Wenn er es direkt tut (weil Treiber privilegiert sein können), dann ist dein HAL eben ein Dummy/nicht existent.

Mit "Abstraktion eines Bussystems" meinst Du wohl "gibt nur ne physische Adresse an den Treiber" oder?
Aber was nützt das? Welche HW (außer die NE2000) gibt es mit identischer Ansteuerung für unterschiedliche Bus-Systeme?
Ich weiß, dass du Bussysteme nicht abstrahieren möchtest, wie es fast keiner tut. Grundsätzlich gehört aber mehr dazu als die physische Adresse, nämlich auch die Adresse des Gerätes auf dem Bus (bei I²C eine 7-Bit-Zahl, bei PCI-Geräten Busnummer usw., bei ISA-Geräten die I/O-Leitungen). Dann brauchst du Sende- und Empfangsmöglichkeiten, da nicht jedes Bussystem über MMIO verfügt. Für manche Bussysteme gibt es noch obskure Parameter (Taktgeschwindigkeit bei I²C/SPI) usw.

Für den PCI-Bus läuft das auf einen physischen Speicherbereich hinaus, wenn du den PCI-Adressraum mittels MMIO ansprechen kannst.

Identische Ansteuerung bei verschiedenen Bussystemen hast du inzwischen nur noch selten. Beispiele sind am Parallelport angeschlossene SCSI-Geräte (Scanner, CD-Laufwerke, früher auch Festplatten). Ansonsten betrifft das jegliche Hardware, die über einen Buswandler angeschlossen wird.

In die andere Richtung bringt Busabstraktion auch was, denn eine andere Hardwarearchitektur hat auch einen PCI-Bus, der aber vielleicht ganz anders angesprochen werden muss. Abstrahierst du an der Stelle, funktionieren plötzlich alle Treiber trotzdem. Für dein komplett anders aufgebautes Betriebssystem auf deiner einen komplett anders aufgebauten Hardwareplattform ist alles das natürlich nicht relevant, da brauchst du auch nichts, was sich irgendwie HAL nennen könnte.

Gruß,
Svenska
Cheftheoretiker

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
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. Ich will immer das selbe Interface haben und was dahinter passiert ist mir egal.
Das würde dann also eigentlich auf alle Standard-Geräte-Treiber zutreffen (Grafik, Sound, Eingabe, Speichermedien usw.).

Ansonsten wüsste ich auch nicht wie ich nen HAL definieren würde.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
Bleiben dann überhaupt noch Treiber übrig? ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
Nicht wirklich ;)

Im Endeffekt ist ein HAL auch "nur" ein Interface, was halt immer gleich bleibt, egal was für Hardware dahinter steckt.
Noch ein Bsp. wäre das Mappen einer Page. Denn es ist egal wieviele Page-Level dahinter stecken, ist immer das gleiche Interface.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
Hallo,


Inwiefern ist der Unterschied relevant?
Zum einen beeinflusst das sicher massiv die Performance und zum anderen ist es IMHO schon ein wesentlicher konzeptioneller Unterschied ob Speicher einfach eingeblendet (in den Treiber-Kontext reingemappt) wird um dann damit direkt zu arbeiten oder ob man für jeden Zugriff durch eine Art Service muss. Da IMHO heute jede Architektur auf linearem Speicher basiert bringt es also absolut nichts den Speicher wegzuabstrahieren so das es offensichtlich praktischer ist ihn einfach in den Treiber einzublenden.

Das kann man sicher auch so verwenden, aber sicher nicht beim OSDev, sondern eben aus Userspacesicht.
Ist mir klar, aber es ist eben meine Frage ob dann das gesamte OS (zumindest die niederen Schichten bestehend aus Kernel und Treibern) als ne Art HAL zu betrachten ist.


Das ist ein Implementierungsdetail. Der HAL ist eine Abstraktionsschicht, kein festgelegtes Protokoll.
Hm, das ist richtig aber irgendwie keine Antwort auf meine Frage. Gerade um dieses Implementierungsdetail geht es mir ja eigentlich, was genau ist es das einen HAL definiert oder darf das jeder nach eigenem Geschmack und Bedarf frei festlegen?
In allen relevanten OSen gibt es etwas das HAL genannt wird und so weit ich das überblicken kann ist das meistens recht dünn aufgebaut (also eher die Variante "gibt nur ne physische Adresse an den Treiber").

Meinetwegen reden die Anwendungen auch direkt mit dem Treiber, aber der muss irgendwie auf die Hardware zugreifen. Und das tut er über den HAL, wie ist egal.
Nein, mir ist das für diese Frage nicht egal. Gerade um dieses wie geht es mir doch.

Wenn er es direkt tut (weil Treiber privilegiert sein können), dann ist dein HAL eben ein Dummy/nicht existent.
Für direkten Zugriff auf Speicher muss kein Programm privilegiert sein es reicht wenn das OS ihm die gewünschten Speicherbereiche zugänglich macht (was zwar auch wieder eine Art von Privileg ist aber eben rein in SW und nicht in HW in Form von Ring 0 o.ä.).

Ich weiß, dass du Bussysteme nicht abstrahieren möchtest
Ich würde das anders formulieren: ich möchte nichts machen das mir keinen Vorteil bringt und das Abstrahieren von BUS-Systemen bringt eben keinen. Selbst auf einem klassischen PC (von Heute) ist der Floppy-Controller die absolut letzte Komponente die noch auf ISA (inklusive ISA-DMA) basiert so das ich persönlich ganz klar empfehlen würde den ganzen ISA-Kram (inklusive ISA-DMA) direkt in den Floppy-Treiber zu integrieren und das ganze als einen Blob zu betrachten.

wie es fast keiner tut.
Ja eben, wozu auch. Die NE2000 ist die einzigste mir bekannte HW die es auf mehr als einem BUS-System gab und zwar so das man mit dem selben Treiber arbeiten konnte. Ich kenne keine weitere HW auf die das zutrifft. Gemessen daran erscheint mir (und wohl auch anderen) der Aufwand die Busse zu abstrahieren dann doch zu hoch.

Grundsätzlich gehört aber mehr dazu als die physische Adresse, nämlich auch die Adresse des Gerätes auf dem Bus (bei I²C eine 7-Bit-Zahl, bei PCI-Geräten Busnummer usw., bei ISA-Geräten die I/O-Leitungen).
Das ist ein sehr schönes Beispiel. PCI ist wimre der einzigste Bus der es mit standardisierten On-Board-Mitteln erlaubt die physische Position (also die reale Slot-Nummer auf dem Main-Board) zu ermitteln, sogar über mehrere Gehäuse hinweg (für PCI gibt es ja solche tollen externen PCI-Erweiterungs-Boxen wo man noch ein paar zusätzliche Karten unterbringen kann). Aber die SW kann mit diesen Informationen üblicherweise kaum was anfangen so dass das wohl nicht ganz dem entspricht worauf ich mit meiner Frage hinaus wollte.

Dann brauchst du Sende- und Empfangsmöglichkeiten, da nicht jedes Bussystem über MMIO verfügt.
Prominentes Beispiel wäre der USB. Aber alle diese Busse die nicht direkt für die CPU erreichbar sind stellen doch eh eine ganz andere Kategorie dar. Eben weil sie nicht für die CPU (und der darauf laufenden SW) erreichbar sind müssen die mit einem Host-Controller-Treiber abstrahiert werden. Ist das dann eine Art von HAL?

In die andere Richtung bringt Busabstraktion auch was, denn eine andere Hardwarearchitektur hat auch einen PCI-Bus, der aber vielleicht ganz anders angesprochen werden muss. Abstrahierst du an der Stelle, funktionieren plötzlich alle Treiber trotzdem.
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. Ich denke für PCI ist das die minimalste Anforderung an einen HAL, aber reicht das damit der Name HAL auch berechtigt ist?

Cheftheoretiker
Genau deswegen hatte ich gehofft das auch Du Dich an dieser Frage beteiligst. ;)
Ich möchte eher eine akademische Antwort auf meine Frage als eine Aufzählung praktischer Umsetzungen.


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....
Auch der "Treiber" für den Interrupt-Controller gehört in diese Kategorie. Es gibt also einige Geräte die so elementar sind das sie direkt im OS-Kernel bzw. dessen HAL-Schicht behandelt werden müssen.

Ansonsten wüsste ich auch nicht wie ich nen HAL definieren würde.
Da sind wir hier wohl recht viele. ;)


Mein ersten Fazit (nach weniger als 24 Stunden): wirklich genau weiß das hier wohl auch keiner.
Offensichtlich ist die Antwort auf meine Frage dermaßen akademisch das sie in der hier gelebten Praxis keine Rolle spielt.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 13. February 2011, 11:56 »
Das Problem ist wahrscheinlich auch, aus welcher Sicht willst du wissen was der HAL ist? Denn z.B. aus Kernel-sicht wäre es halt, das du viele Sachen immer über das selbe Interface (z.B. Timer, Irqs) nutzen kannst. Aus Sicht der Treiber ist es wichtig, das sie auch immer das selbe Interface haben, ob nun z.B. per USB oder per PCI angebunden (ob das so möglich ist, bin ich mir gar nicht so sicher).

Aber der eigentliche Grund sowas wie nen HAL zu haben, ist portabilität (und auch Einfachheit für z.B. den Treiber-Programmierer)! Wenn du das nicht brauchst, kannst du ihn dir eigentlich auch sparen.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 13. February 2011, 15:10 »
Hallo,

Das ist ein Implementierungsdetail. Der HAL ist eine Abstraktionsschicht, kein festgelegtes Protokoll.
Gerade um dieses Implementierungsdetail geht es mir ja eigentlich, was genau ist es das einen HAL definiert oder darf das jeder nach eigenem Geschmack und Bedarf frei festlegen?
Dann hast du die falsche Frage gestellt: Du willst nicht wissen, was ein HAL ist, sondern wie du es konkret implementieren musst. ;-)

Gerade um dieses wie geht es mir doch.

Selbst auf einem klassischen PC (von Heute) ist der Floppy-Controller die absolut letzte Komponente die noch auf ISA (inklusive ISA-DMA) basiert so das ich persönlich ganz klar empfehlen würde den ganzen ISA-Kram (inklusive ISA-DMA) direkt in den Floppy-Treiber zu integrieren und das ganze als einen Blob zu betrachten.
An der Stelle ist dein HAL für ISA-DMA nicht existent, der Treiber muss die Privilegien besitzen, um auf dem Bus seine Dinge tun zu dürfen.

PCI ist wimre der einzigste Bus der es mit standardisierten On-Board-Mitteln erlaubt die physische Position (also die reale Slot-Nummer auf dem Main-Board) zu ermitteln, sogar über mehrere Gehäuse hinweg (für PCI gibt es ja solche tollen externen PCI-Erweiterungs-Boxen wo man noch ein paar zusätzliche Karten unterbringen kann).
Du vergisst den MCA, dort ging das auch. Aber es gab m.W. keine MCA-auf-MCA-Brücken.

Aber alle diese Busse die nicht direkt für die CPU erreichbar sind stellen doch eh eine ganz andere Kategorie dar.
Es sind trotzdem Busse. Und wenn du eine USB-PCI-Bridge haben könntest, dann liegt dahinter irgendwo trotzdem ein PCI-Bus.

Eben weil sie nicht für die CPU (und der darauf laufenden SW) erreichbar sind müssen die mit einem Host-Controller-Treiber abstrahiert werden. Ist das dann eine Art von HAL?
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.

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.

Ich denke für PCI ist das die minimalste Anforderung an einen HAL, aber reicht das damit der Name HAL auch berechtigt ist?
Wenn du es dann HAL nennst, ja. Nennst du es anders, nein.

HAL ist nur eine Abstraktion für dich. Je portabler dein Betriebssystem sein muss, desto dicker muss diese Schicht sein, umso mehr potentielle Unterschiede muss sie abstrahieren können.

Oder ein anderes Beispiel; ich habe einen Microcontroller (STM32) für USB-Host-Operation programmiert. Der Treiber für diesen Controller (kein *HCI, sondern USB_OTG_FS), 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. Mehr ist als HAL auch nicht nötig, da es eine CPU-interne Logik ist, die nur auf ähnlichen Controllern existieren 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.

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, die Ausführungen helfen...

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.

Die API, wie man einen Treiber anspricht und wie man Informationen über dessen Fähigkeiten (Auflösung, Zählweite, Interruptfähigkeit) bekommt, ist eine Hardwareabstraktion eines Timers. Für Interruptcontroller ist das ähnlich; welche Interrupts gibt es, wie sind sie geroutet, wie registriert/entfernt man einen Interrupthandler und was muss man in einem solchen beachten gehören in eine API. Diese API abstrahiert dann Interrupts.

Die Summe aller solcher APIs, die jeweils ein Stückchen Hardware abstrahieren, ist der HAL.
Und ob man den jetzt so nennt oder nicht, ist unerheblich.

Gibt es dazu Einwände/Widersprüche?

Offensichtlich ist die Antwort auf meine Frage dermaßen akademisch das sie in der hier gelebten Praxis keine Rolle spielt.
Wie willst du eine Abstraktion allgemein erklären? Es geht schließlich auch ohne...

Gruß,
Svenska

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 13. February 2011, 15:13 »
Hallo,


Das Problem ist wahrscheinlich auch, aus welcher Sicht willst du wissen was der HAL ist?
Es geht mir eher um die akademische/theoretische Sicht: Was ist ein HAL? Was sind seine Aufgaben?

Aber der eigentliche Grund sowas wie nen HAL zu haben, ist portabilität (und auch Einfachheit für z.B. den Treiber-Programmierer)! Wenn du das nicht brauchst, kannst du ihn dir eigentlich auch sparen.
Ich denke ein HAL dient zu mehr als nur zur Portabilität. Wozu hat Windows einen HAL?
Wenn ein Treiber über eine zentrale Stelle die Ressourcen seines Gerätes holen kann dann ist das IMHO besser als wenn der Treiber selber anfangen müsste z.B. im PCI-Config-Space nach seinen Geräten und deren Ressourcen zu suchen (das wäre ja quasi wie ein Rückschritt in die Zeit als proben noch angesagt war). Also steht da auch ganz klar Einfachheit für den Treiberprogrammierer und die Vermeidung von doppelten Code ganz vorne.
Auch das Abstrahieren des Interrupt-Controllers ist eigentlich unumgänglich weil sonst der Kernel den Überblick verliert (vor allem bei geshareten IRQs). Darüber das wir nicht mehr (so wie zu seligen DOS-Zeiten) mit jedem Programm in der IDT rummurkseln und wild Interrupts hooken müssen sind wir doch eigentlich sehr froh. Oder?


@Svenska:
Zu Deinem Diagramm von gestern Nachmittag hab ich noch eine Frage: Wieso ist der Benutzer (ich nehme mal an das Du damit den Menschen meinst) ganz oben und kommuniziert direkt mit den Anwendungen (ich nehme mal an das Du damit die normalen User-Space-Applikationen meinst)? Ich persönlich habe noch nie mit einer Anwendung direkt kommuniziert, ich konnte bisher immer nur mit der Hardware eines Computers interagieren. Eigentlich müsste Dein Diagramm komplett andersherum aufgebaut sein bis auf den Benutzer der muss oben bleiben. IMHO sind die Applikationen die am tiefsten versteckteste Komponente in einem Computer.



Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 13. February 2011, 15:32 »
Ich denke ein HAL dient zu mehr als nur zur Portabilität. Wozu hat Windows einen HAL?
Der Windows NT-Kernel ist unglaublich portabel. Er läuft auf mehreren Prozessorarchitekturen mit jeweils darunterliegenden Systemarchitekturen. Und weil er dafür ursprünglich mal erdacht wurde, gibt es eine entsprechend ausgezeichnete Hardwareabstraktion. Bei NetBSD ist das ähnlich.

Auf der anderen Seite steht Linux, welches nie für Portabilität entwickelt wurde. Dort gibt es ursprünglich auch keinen HAL, sondern jedes Subsystem selbst bringt eine eigene Hardwareabstraktion mit. Die Summe aller Teile ist dann trotzdem ein HAL, aber es gibt keine Stelle, wo du ihn finden könntest.

Also steht da auch ganz klar Einfachheit für den Treiberprogrammierer und die Vermeidung von doppelten Code ganz vorne.
Das ist der Sinn einer jeden Abstraktion. ;-)

Auch das Abstrahieren des Interrupt-Controllers ist eigentlich unumgänglich weil sonst der Kernel den Überblick verliert (vor allem bei geshareten IRQs).
Naja, eher nicht. 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. (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.)

Wenn du einen Interrupt-Controllertreiber schreibst, dann hast du die Möglichkeit, mehrere identische dieser zu verwenden (2 PICs), außerdem kannst du es auf eine andere Architektur portieren, die z.B. andere Interruptmechanismen benutzt.

Zu Deinem Diagramm von gestern Nachmittag hab ich noch eine Frage: Wieso ist der Benutzer (ich nehme mal an das Du damit den Menschen meinst) ganz oben und kommuniziert direkt mit den Anwendungen (ich nehme mal an das Du damit die normalen User-Space-Applikationen meinst)?
Das ist eine Frage der Richtung, aus der du auf ein System draufguckst. 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".

Ich persönlich habe noch nie mit einer Anwendung direkt kommuniziert, ich konnte bisher immer nur mit der Hardware eines Computers interagieren.
Dein Ziel ist es aber, die Anwendung zu bedienen. Die Anwendung wiederum stellt die Schnittstelle zwischen dem Benutzer und dem Betriebssystem dar. Das Betriebssystem steuert die Hardware an (oder sitzt der Benutzer mit einem Taktgeber vorm Bildschirm und taktet die Pixel da rein? :-P) und um das zu tun, bedient sich das Betriebssystem eines Treibers.

Das ist die Sichtweise des Systems.

Eigentlich müsste Dein Diagramm komplett andersherum aufgebaut sein bis auf den Benutzer der muss oben bleiben. IMHO sind die Applikationen die am tiefsten versteckteste Komponente in einem Computer.
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.

Das ist die Sichtweise des Datenflusses.

Gruß,
Svenska

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 13. February 2011, 22:08 »
Ist also CDI der HAL von tyndur?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 13. February 2011, 22:35 »
CDI ist, soweit ich das verstehe, die API, über die das Betriebssystem mit Treibern kommuniziert. Die Treiber selbst nutzen den HAL, um mit der Hardware zu kommunizieren. Also ist CDI erstmal kein HAL für Tyndur.

Ein CDI-Treiber für PCI wäre somit Teil des HAL, ein CDI-Treiber für Netzwerkkarten nicht.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 13. February 2011, 22:39 »
Hm, es gibt zwei Teilaspekte, würde ich sagen: Zum einen abstrahiert CDI für das OS die Hardware, die der Treiber ansteuert weg, so dass das OS einfach nur eine Netzwerkkarte statt einer e1000 ansteuert (das geht wohl in die Richtung dessen, was oben genannt wurde, nämlich dass das ganze OS ein HAL für Programme ist), zum anderen abstrahiert es aber auch für den Treiber wiederum die tieferen Schichten. Wenn ein Treiber z.B. Speicher braucht oder einen IRQ haben will, ruft er wieder eine CDI-Funktion auf.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 14. February 2011, 11:01 »
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
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 14. February 2011, 11:28 »
Damit sind wir also zum Ergebnis gekommen, dass Namen Schall und Rauch sind. Nichts neues eigentlich. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 14. February 2011, 12:43 »
Hallo,


Damit sind wir also zum Ergebnis gekommen, dass Namen Schall und Rauch sind. Nichts neues eigentlich. ;)
Tja, offensichtlich. :(


Und was ist nun die Moral von der Geschicht? Den HAL den gibt es nicht!


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

 

Einloggen