Autor Thema: Treiberprogrammierung  (Gelesen 8344 mal)

bscreator

  • Gast
Gespeichert
« am: 18. September 2010, 22:16 »
Hallo,

bin bei meinem OS gerade dabei, die Schnittstellen zur "Außenwelt" einzurichten.
Leider hab ich noch nie nen Treiber programmiert und somit auch keine Ahnung, wo man da anfangen soll.

1. Wo beginnt man, wenn man z.B. die serielle Schnittstelle programmieren will, oder z.B. den Treiber für einen USB-Speicherstick schreiben möchte ?

2. Da ihr bestimmt schon einige Treiber programmiert habt, wäre ich euch dankbar, wenn ihr mir ein Beispiel eines einfachen und kurzen Treibers, egal welche Schnittstelle, zeigen könntet, damit ich das mal üben kann.

Vielen Dank,
bscreator

Programm Noob

  • Gast
Gespeichert
« Antwort #1 am: 19. September 2010, 01:32 »
Also vom USB-Stick Bist du noch ganz weit weg. Guck dir CDI und les im Wiki. Serialle schnittstelle ist sher einfach.

Was für einen Kerneltypen schreibst du?
Wo kann man dein OS ansehen?

Wir können deine Fragen und Aussagen auch lesen, wenn sie nicht FETT geschrieben sind.

Programm Noob

Programm Noob

  • Gast
Gespeichert
« Antwort #2 am: 19. September 2010, 01:34 »
Du hast noch keine printf Funktion und auch keinen Tastaturtreiber?

Dann solltest du dich erstmal um sowas kümmern.

Programm Noob

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 19. September 2010, 01:37 »
Hallo,


Wo beginnt man, wenn man z.B. die serielle Schnittstelle programmieren will,
Also die Serielle Schnittstelle ist eine recht einfache Schnittstelle (wenn man nicht gleich noch asynchronen I/O möchte und das will man nicht gleich beim ersten Versuch) und man benötigt vor allem eine Sende-Methode (von einem Client zum Treiber) und eine Möglichkeit wo die Empfangenen Bytes abgeliefert werden sollen (vom Treiber zu einem Client). Wie das im Detail funktioniert hängt von den Konzepten Deines OS ab, das ist eben genau der Part wo Du kreativ sein musst bzw. darfst. Wenn Du in diesem Punkt unsicher bist dann solltest Du konkrete Fragen stellen.

oder z.B. den Treiber für einen USB-Speicherstick schreiben möchte?
Also das ist schon eine wirklich ganz andere Klasse, ich glaube das noch keines der hier vertretenden Hobby-OSe sowas kann (falls doch dann Bitte ich um Entschuldigung).

Da ihr bestimmt schon einige Treiber programmiert habt, wäre ich euch dankbar, wenn ihr mir ein Beispiel eines einfachen und kurzen Treibers, egal welche Schnittstelle, zeigen könntet, damit ich das mal üben kann.
Ich würde eher vorschlagen das Du versuchst die elementaren Komponenten im Computer, Tastatur und Bildschirm (Text reicht fürs erste), anzusteuern und Dir mal ein Konzept überlegst wie man diese beiden Komponenten als cin und cout einem C-Programm anbieten könnte (eine funktionierende Konsole ist IMHO eine gute Basis für weitere Entwicklungen in Deinem OS), also was Deine C-Library für Dein OS im Detail machen soll damit ein beliebiges standard-konformes C-Programm damit arbeiten kann (wenn Du nicht C benutzt dann eben die passenden Äquivalente in der von Dir benutzten Programmiersprache).


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 #4 am: 19. September 2010, 03:29 »
Hallo,

du solltest dir zwei Schnittstellen überlegen:

(a) Wie soll der Treiber auf Kernel & Hardware zugreifen können, d.h. Ressourcenzuteilung bzw. -verteilung?

Ein Ansatz ist die simple Zuteilung von nicht näher bezeichneten (busabhängigen) Ressourcen (z.B. IRQs, DRQs, I/O-Ports oder physischen & virtuellen [nicht-auslagerbaren] Speicheradressen) an Treiber, die diese vom System anfordern können und dann direkt darauf zugreifen können - wenn die Treiber der Meinung sind, mit dieser Hardware etwas anfangen zu können. Diese Ressourcenverteilung muss exklusiv sein, d.h. es darf nur einen Treiber je Hardware geben.

(b) Wie sollen die Anwendungsprogramme auf den Treiber zugreifen können?

Hier brauchst du eine Abstraktion je Geräteklasse, eine Tastatur ist ein Eingabegerät für Zeichen (eine serielle Schnittstelle auch), ein Bildschirm ist eine zweidimensionale (oder zeilenweise) Ansammlung von Zeichen und/oder Pixeln, eine Diskette/Festplatte/CDROM/USB-Stick ist eine eindimensionale Ansammlung von Datenblöcken.

Ob du diese beiden Teile getrennt (Abstraktion der Bussysteme) oder zusammen (es gibt nur PCI, der Rest sind Ausnahmen) behandelst, bleibt dir überlassen. Genauso, ob du beide Teile verschachtelbar einplanst (USB ist ein Bussystem, welches Ressourcen für den Hostcontroller benötigt, aber selbst wieder Ressourcen bereitstellt) oder das ganze lieber in Bibliotheken verpackst ("USB" ist ein Gerät, der einzige Nutzer ist die "lib-usb").

Wichtig ist, dass du einerseits diese Schnittstellen möglichst einfach entwickelst, andererseits aber so komplex aufbaust, dass du dich nicht zu sehr einschränkst.

Die serielle Schnittstelle braucht IRQ und I/O-Ports und liefert eine Folge von Zeichen und Fehlern. Der USB-Stick liefert Datenblöcke, ist aber nur über ein vollwertiges und initialisiertes Bussystem erreichbar, welches wiederum IRQ- und DMA-Leitungen und Speicheradressen benötigt.

Gruß,
Sebastian

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 19. September 2010, 10:00 »
Hallo,


zu den Ausführen von Svenska möchte ich noch hinzufügen das man bei der Geräte-Abstraktion eventuell immer ganze Geräte mit all ihren Ressourcen verwalten sollte so das ein Treiber entweder ein komplettes Gerät bekommt oder eben nichts, das separate Verwalten einzelner Ressourcen finde ich persönlich eher ungeschickt. Sieh Dir mal die Datenstrukturen von CDI an dort gibt es fertige Strukturen die ein PCI-Gerät gut beschreiben. Alles was nicht PCI ist kann man ja, nachdem man die Liste aller PCI-Geräte erstellt hat, einfach wie PCI-Geräte mit anhängen (für eine serielle Schnittstelle z.B. einfach eine Geräte-Struktur erstellen welche den einen I/O-Port-Bereich und den einen IRQ beschreibt).

Die DMA-Kanäle als Ressource zu Verwalten könnte sich als unnötig herausstellen, es gibt nur noch ein einziges Gerät das den klassischen ISA-DMA benutzt: der Floppy-Controller. Ich würde daher vorschlagen das ganze ISA-DMA-Zeugs einfach mit in den Floppy-Treiber zu integrieren und die I/O-Ports des DMA-Controller einfach dem Floppy-Controller hinzufügen. Das ganze gilt natürlich nur wenn Du auch wirklich mit Floppys arbeiten möchtest (ansonsten kannst Du Dir den ISA-DMA auch ganz sparen), ich realen PCs sind die in den vergangenen Jahren faktisch ausgestorben (wenn Du einen älteren PC als Testplattform benutzen möchtest dann ist Floppy natürlich trotzdem nützlich). Eine gute USB-Unterstützung eröffnet Deinem OS ganz andere Welten, stellt aber auch ganz andere Anforderungen.


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 #6 am: 19. September 2010, 10:51 »
Hallo,

sind die DMA-Leitungen nur für ISA-DMA zuständig?
Wie läuft das dann mit den DMA-Modi von IDE-Controller/Netzwerkkarte/[PCI-Gerät hier einsetzen]...?

Gruß,
Sebastian

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #7 am: 19. September 2010, 12:09 »
sind die DMA-Leitungen nur für ISA-DMA zuständig?
Ja

Zitat
Wie läuft das dann mit den DMA-Modi von IDE-Controller/Netzwerkkarte/[PCI-Gerät hier einsetzen]...?
PCI-Geräte können selbst direkt auf den Hauptspeicher zugreifen und brauchen damit keinen eigenen DMA-Chip mehr.
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

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 19. September 2010, 12:40 »
Hier brauchst du eine Abstraktion je Geräteklasse, eine Tastatur ist ein Eingabegerät für Zeichen (eine serielle Schnittstelle auch), ein Bildschirm ist eine zweidimensionale (oder zeilenweise) Ansammlung von Zeichen und/oder Pixeln
Man sollte alles so einfach wie möglich machen, aber eben auch nicht einfacher. ;)

Eine Tastatur ist definitiv nicht dasselbe wie eine serielle Schnittstelle. Wenn du mal nicht an eine Shell denkst, in der man Befehle eintippt, sondern z.B. an ein Spiel, in dem man läuft, solange man eine Taste gedrückt hält oder wonöglich sogar mehrere Tasten gleichzeitig drücken können muss, bist du mit Tastatur = ASCII-Zeichen ziemlich schnell am Ende.

Genauso beim Bildschirm. Einen einfachen Framebuffer bereitzustellen ermöglicht es dir zwar, bunte Pixel auf den Bildschirm zu bekommen, aber einen hardwarebeschleunigten Treiber kannst du damit vergessen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bscreator

  • Gast
Gespeichert
« Antwort #9 am: 19. September 2010, 12:44 »
Hallo,

erstmal danke ich euch allen für eure zahlreichen Antworten. Also mein OS läuft (immernoch und trotz vieler Widersprüche im Forum) im Real-Mode, bei dem ja ein sehr großer Teil der Treiberentwicklung, speziell für Tastatur und Monitor, ganz einfach über Interrupts funktioniert.

Zitat
Du hast noch keine printf Funktion und auch keinen Tastaturtreiber?

Dann solltest du dich erstmal um sowas kümmern.
Sollt ich also dementsprechend erstmal versuchen, die IN und OUT Funktionen für die Tastatur und den Monitor zu verwenden und dann daraus eigene Interrupts zu erstellen, oder ? Denn C kann ich im RM sowieso vergessen.

Zitat
Eine Tastatur ist definitiv nicht dasselbe wie eine serielle Schnittstelle. Wenn du mal nicht an eine Shell denkst, in der man Befehle eintippt, sondern z.B. an ein Spiel, in dem man läuft, solange man eine Taste gedrückt hält oder wonöglich sogar mehrere Tasten gleichzeitig drücken können muss, bist du mit Tastatur = ASCII-Zeichen ziemlich schnell am Ende.
Also sollt ich zuerstmal ein altes Gerät ausgraben, das noch den seriellen Anschluss benutzt und versuchen, mit diesem "sinnvoll" zu kommunizieren, oder ?


Viele Grüße und vielen Dank,
bscreator (RM it's the best... :-D)
« Letzte Änderung: 19. September 2010, 12:54 von bscreator »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 19. September 2010, 12:47 »
Also mein OS läuft (immernoch und trotz vieler Wiedersprüche im Forum) im Real-Mode, bei dem ja ein sehr großer Teil der Treiberentwicklung, speziell für Tastatur und Monitor, ganz einfach über Interrupts funktioniert.
Genaugenommen schreibst du so keine Treiber, sondern benutzt einfach nur die schon vorhandenen des BIOS.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bscreator

  • Gast
Gespeichert
« Antwort #11 am: 19. September 2010, 13:45 »
Hallo,

erstmal danke ich euch allen für eure zahlreichen Antworten. Also mein OS läuft (immernoch und trotz vieler Widersprüche im Forum) im Real-Mode, bei dem ja ein sehr großer Teil der Treiberentwicklung, speziell für Tastatur und Monitor, ganz einfach über Interrupts funktioniert.

Zitat
Du hast noch keine printf Funktion und auch keinen Tastaturtreiber?

Zitat
Dann solltest du dich erstmal um sowas kümmern.
Sollt ich also dementsprechend erstmal versuchen, die IN und OUT Funktionen für die Tastatur und den Monitor zu verwenden und dann daraus eigene Interrupts zu erstellen, oder ?
Denn C kann ich im RM sowieso vergessen.

vielen Dank,
bscreator (RM it's the best...  :-D)

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 19. September 2010, 13:57 »
Hallo,

naja, wenn du Tastatur & Serielle als Zeichenketteneingabe betrachtest, vereinfachst du die Programmierung der Shell enorm. Dein Spiel könnte an den Tastaturtreiber ja ein Flag (z.B. KEYB_RAW) mitgeben, so dass der Treiber die Make- und Break-Codes direkt mitgibt. Das muss das Spiel dann explizit unterstützen.

Dafür wäre es der Shell egal, ob du nun über CON oder COM1 das System bedienst.

Ähnliches für die Grafikkarte. Der erste Treiber wird sicherlich ein VGA- oder VESA-Treiber sein und damit per se unbeschleunigt (Android nutzt übrigens auch keine 3D-Funktionen der Grafikchips auf den Geräten!). Wenn man sich dann an einem beschleunigten Hardwaretreiber versuchen möchte, kann man die Schnittstelle ja um Funktionen wie BitBlt oder so erweitern. Als Anfang reicht der dumme Framebuffer aber.

Gruß,
Sebastian

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 19. September 2010, 20:37 »
Hallo,

Wie läuft das dann mit den DMA-Modi von IDE-Controller
IDE ist da tatsächlich noch interessant. Wenn man den IDE-Host-Controller im klassischen Modus betreibt könnte der in den normalen DMA-Modi (nicht UDMA) eventuell schon noch theoretisch den ISA-DMA benutzen aber ob das mit den heutigen Chip-Sätzen überhaupt noch geht kann ich echt nicht sagen weil ich nicht genau weiß wo der ISA-DMA-Controller eigentlich heutzutage drin ist. Im Zweifelsfall würde ich sagen das man mit IDE den klassischen ISA-DMA nicht mehr benutzen kann und damit auf PIO beschränkt ist. Wenn der IDE-Host-Controller im Enhanced-IDE-Mode (oder wie auch immer der heißt) läuft ist er eh ein vollwertiges PCI-Device kann kann als Busmaster selber direkt auf den Hauptspeicher zugreifen (dann stehen auch die UDMA-Modi zur Verfügung).

Netzwerkkarte/[PCI-Gerät hier einsetzen]...?
Alle echte PCI-Hardware hat niemals den ISA-DMA-Controller benutzt weil es am PCI-Slot dafür keine Leitungen gibt. PCI-Geräte können selber direkt auf den Haupt-Speicher zugreifen ohne dazu die Hilfe eines externen Zusatzchips zu benötigen.

siehe auch http://www.lowlevel.eu/wiki/DMA


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

bscreator

  • Gast
Gespeichert
« Antwort #14 am: 20. September 2010, 09:48 »
Hallo,

Zitat
naja, wenn du Tastatur & Serielle als Zeichenketteneingabe betrachtest, vereinfachst du die Programmierung der Shell enorm.
So hab ich mir meine OS-Shell auch vorgestellt. Wenn ich mir jetzt meinen Tastaturtreiber selbst schreibe, also nur mit IN und OUT, dann kann man über Port 0x80, soviel ich noch weiss, die Tastatur ansprechen. Jedoch hatte ich immer ein Problem mit dem Zuordnen der SCAN-Codes zu "richtigen" ASCII-Zeichen.

Könnt ihr mir da vielleicht helfen ?

Gruss,
bsc

Programm Noob

  • Gast
Gespeichert
« Antwort #15 am: 20. September 2010, 10:16 »
such mal mit GOOGLE NACH scancodes

bscreator

  • Gast
Gespeichert
« Antwort #16 am: 21. September 2010, 12:04 »
Hi,
also mein Tastaturtreiber sieht bisher folgendermaßen aus :

while:
in al, 0x64
test al,0000010b   ;Ausgabepuffer leer ?
jne while
           
mov al, 0xD1       ;Wir moechten auf Outputport schreiben
out 0x64, al

wait2:
in al, 0x64        ;Eingabepuffer leer ?
test al,00000001b
jne wait2   

Kleine Erklärung:
1. Warten bis Ausgabepuffer leer ist, bzw. Bit 1 = 0
2. Wenn leer, dann Befehl zum Schreiben auf Inputport, d.h. 0xD1 an 0x64 senden
3. Solange warten bis eine Taste gedrückt wurde, d.h. Bit 0 auf 1 prüfen.

Der Fehler liegt darin, dass Bit 0 niemals 1 ist, da AL=0xD1


Wie kann ich
- Ich dem KBC klar machen kann, dass er warten soll, bis eine Taste auf Tastatur gedrückt wurde ?
- und wie kann ich den Scancode der gedrückten Taste auslesen ?


Gruss,
bsc

 

Einloggen