LeadingZero
16.06.2007, 13:32
Hallo
Ich bin neu hier im Forum und suche ganz dringend ein paar Antworten bezüglich meiner Soundkartenprogrammiererei.
Seit ungefähr 8 Jahren programmiere ich Grafikdemos in Assembler und bin zu der Lösung gekommen, daß eine schnelle Basicsprache mit genügend Spezialbefehlen ausreichend ist, um Desktop, Anwendungen und Spiele darauf laufen zu lassen. Kurzerhand hab ich die passende Basic-Sprache entwickelt und schon kurze Zeit später hatte ich mein erstes selbstentwickeltes Desktopsystem, das eigentlich alle Eigenschaften hat wie Win98 auch, nur daß ich eben noch nicht damit ins Internet gehen kann. Es gibt Multitasking, eine "DirectX"-Schnittstelle für Desktop- und 3dGrafik, Tastatur&Maus, Smartdrive, total generalisierte Strukturen für jeden und alles und pi pa po...
Nur leider ist die Framerate bei 800x600 nur 8FPS mit meinem 500MHz-AMD3dnow-Computer. Und außerdem muß man mit der Zeit gehen, was bedeutet: Ich brauche einen schnelleren Computer.
Nur leider gibt es keine schnelleren Computer mit ISA-Steckplätzen mehr und ich muß wohl oder übel auf PCI umsteigen.
Jetzt hab ich mit den Leuten von CREATIVE gesprochen und die meinten, daß sie keine Hardwareinformationen über ihre Soundkarten herausgeben, ich mich lediglich an Directsound, Opensound oder ASIO halten müsse, um deren Soundkarten anzusprechen.
Darum hab ich mir den (just) freigewordenen Sourcecode vom Linux Opensound-Soundsystem runtergeladen und stehe nun vor einem Problem:
- a: Ich hab keine Erklärung wie das IOCTL-System überhaupt funktioniert und was PCI für einen Standard darstellt.
- b: Ich brauche eine Übersicht über die grundlegende Aufbaustruktur eines PCI-Soundtreibers, damit ich mir den Quellcode des Opensound-Soundsystems zu Bemüte führen kann, ohne einen Nervenzusammenbruch zu erleiden :-) Ohne fremde Hilfe müßte ich ja quasi Linux (mit dem ich eigentlich nix zu tun hab) compilieren, installieren, ausprobieren und immer wieder redundante Codefragmente entfernen und den Vorgang wiederholen, bis Linux nix mehr enthält was entfernt werden könnte, ohne daß der Soundtreiber verrückt spielt !? Ich weiß nicht. Das ist echt hardcore. Zu einer einfachen Funktion (Gif-Loader) eine Umkehrfunktion zu entwickeln (Gif-Saver) ist ja nicht sooo schwer. Doch diese Sache hier erinnert mich so ziemlich an das, was ich über Einwegfunktionen gelernt hab :-(
Wer kann mir helfen, mich in das PCI-/IOCTL-System einzuarbeiten bzw. erklären, welche Layer zum Soundtreiber dazu gehören. Das Internet läßt wenig ergoogeln...
Hallo
Ich bin neu hier im Forum und suche ganz dringend ein paar Antworten bezüglich meiner Soundkartenprogrammiererei.
Seit ungefähr 8 Jahren programmiere ich Grafikdemos in Assembler und bin zu der Lösung gekommen, daß eine schnelle Basicsprache mit genügend Spezialbefehlen ausreichend ist, um Desktop, Anwendungen und Spiele darauf laufen zu lassen. Kurzerhand hab ich die passende Basic-Sprache entwickelt und schon kurze Zeit später hatte ich mein erstes selbstentwickeltes Desktopsystem, das eigentlich alle Eigenschaften hat wie Win98 auch, nur daß ich eben noch nicht damit ins Internet gehen kann. Es gibt Multitasking, eine "DirectX"-Schnittstelle für Desktop- und 3dGrafik, Tastatur&Maus, Smartdrive, total generalisierte Strukturen für jeden und alles und pi pa po...
Nur leider ist die Framerate bei 800x600 nur 8FPS mit meinem 500MHz-AMD3dnow-Computer. Und außerdem muß man mit der Zeit gehen, was bedeutet: Ich brauche einen schnelleren Computer.
Nur leider gibt es keine schnelleren Computer mit ISA-Steckplätzen mehr und ich muß wohl oder übel auf PCI umsteigen.
Jetzt hab ich mit den Leuten von CREATIVE gesprochen und die meinten, daß sie keine Hardwareinformationen über ihre Soundkarten herausgeben, ich mich lediglich an Directsound, Opensound oder ASIO halten müsse, um deren Soundkarten anzusprechen.
Darum hab ich mir den (just) freigewordenen Sourcecode vom Linux Opensound-Soundsystem runtergeladen und stehe nun vor einem Problem:
- a: Ich hab keine Erklärung wie das IOCTL-System überhaupt funktioniert und was PCI für einen Standard darstellt.
- b: Ich brauche eine Übersicht über die grundlegende Aufbaustruktur eines PCI-Soundtreibers, damit ich mir den Quellcode des Opensound-Soundsystems zu Bemüte führen kann, ohne einen Nervenzusammenbruch zu erleiden :-) Ohne fremde Hilfe müßte ich ja quasi Linux (mit dem ich eigentlich nix zu tun hab) compilieren, installieren, ausprobieren und immer wieder redundante Codefragmente entfernen und den Vorgang wiederholen, bis Linux nix mehr enthält was entfernt werden könnte, ohne daß der Soundtreiber verrückt spielt !? Ich weiß nicht. Das ist echt hardcore. Zu einer einfachen Funktion (Gif-Loader) eine Umkehrfunktion zu entwickeln (Gif-Saver) ist ja nicht sooo schwer. Doch diese Sache hier erinnert mich so ziemlich an das, was ich über Einwegfunktionen gelernt hab :-(
Wer kann mir helfen, mich in das PCI-/IOCTL-System einzuarbeiten bzw. erklären, welche Layer zum Soundtreiber dazu gehören. Das Internet läßt wenig ergoogeln...
Speziell dazu kann ich dir wenig helfen, aber ich habe einen Literaturtipp für dich: Linux Device Drivers (http://www.amazon.de/Linux-Device-Drivers-Jonathan-Corbet/dp/0596005903/ref=pd_bbs_sr_1/302-4451431-3608036?ie=UTF8&s=books-intl-de&qid=1187774349&sr=8-1) sowie Linux Kernel Handbuch (http://www.amazon.de/Kernel-Handbuch-Leitfaden-Design-Implementierung/dp/3827322472/ref=pd_bbs_sr_2/302-4451431-3608036?ie=UTF8&s=books&qid=1187774349&sr=8-2)
Aber für ein paar Grundsätzliche Fragen kann ich dir auf die Sprünge helfen. PCI ist - wie ISA auch - "nur" ein Bussystem. Das heißt eine Konvention für den Transport von Daten über ein elektronisches Interface sowie der Aufbau der Kommunikation mit einem Gerät und die dazugehörigen Datentypen.
Technik:
PCI ist grundsätzlich ein Plug&Play-System, also basiert auf der freien Zuordnung von Ressourcen. Die Schnittstelle ist ein 32-Bit-Interface (64Bit in besonderen Steckplätzen) und läuft mit 33MHz synchron (66MHz). Die maximale theoretische Datenrate beträgt 133MB/s, real erreichbar sind mit Arbitrierungsverlusten ca. 120MB/s. Ein PCI-Device kann bis zu Vier Interrupts belegen, INTA bis INTD, die Interrupts sind priorisierbar. PCI ist DMA-fähig und bietet, wenn der Standard komplett umgesetzt wird, out-band-signaling über SBA (side band addressing). Moderne PCI-Geräte unterstützen Powermanagement und können anfordern, daß das Taktsignal auf dem Steckplatz abgeschaltet wird. Elektrisch ist PCI ein 5V (3,3V) Spanngungsgesteuertes-single-ended interface (im Gegensatz zu PCIe). Interrupts können tasksynchron level-triggered sein, oder edge triggered. Address- und Datenbus sind nicht gemultiplexed sondern einzeln ausgeführt. PCI ist ein paralleles Interface, Signallaufzeiten sind daher kritisch. Aus diesem Grund wird beim Design von PCI-Geräten dringend empfohlen, die Interfaces fully buffered auszuführen.
Logik:
PCI-Geräte bekommen ihre Ressourcen vom Betriebssystem zugewiesen und informieren daher BIOS und Betriebssystem darüber, welche Ressourcen sie benötigen und welche Defaulteinstellungen sie bevorzugen. Das heißt, das alte ISA-Chaos von unbekannten oder doppelt belegten Ressourcen kann nicht mehr vorkommen.
Jedes PCI-Device muß sich während der Identifizierungsphase melden und initialisieren. Dabei teilt es dem BIOS/Betriebssystem seine Identifizierung und die gewünschten Ressourcen mit. Die Identifizierung besteht je Device aus einer Vendor-ID (die eindeutig von der PCI-SIG vergeben wird) und einer Device-ID mit. Anhand der Vendor- und Device-ID ist das Gerät eindeutig identifierbar.
Auf einem PCI-Steckplatz oder einer Platine können *mehrere* Devices angemeldet werden. Die Steuerungselektronik zählt sie alle durch und behandelt sie gleich. Eine Soundkarte meldet sich daher meistens als Soundkarte, MIDI-Port und Joystickport an, beherbergt mithin also 3 Devices mit jeweils eigenen Ressourcen. Jedes Device kann einzeln aktiviert und deaktiviert werden. Ein deaktiviertes Gerät muß sich vom Bus abmelden und darf sich bis zur erneuten Reset/Arbiter-Phase nicht mehr melden.
Jeder PCI-Steckplatz hat vier Interruptleitungen. Die Zuordnung zu Systeminterrupts ist Designfrage des Motherboardherstellers und des Chipssatzes/BIOS. PCI erlaubt *ausdrücklich* Interruptsharing, also daß sich mehrere Geräte einen Systeminterrupt teilen. Daher ist ein wichtiger Teil des PCI-Treibers das Interrupt-Steering, also das Zuordnen der des Interrupts zu einer Quelle.
Ressourcen:
PCI kennt vier Ressourcentypen: Memorymapped IO, IO, Interrupt und DMA. Memorymapped IO sind Speicherbereiche, die in den Systemspeicher eingeblendet werden, z.B. der Bildschirmspeicher. Normalerweise blenden sich die PCI-Geräte in der sog. PCI-Area in den Speicher ein, dieser Bereich ist das obere Gigabyte (halbe Gigabyte) des 4GB-Addressraums. Zudem können sie sich auch unter 1MB einblenden, VGA-Karten also bei B800:0000. IO ist der "normale" IO-Bereich, wie er mit den Befehlen IN und OUT angesprochen werden kann. Im Gegensatz zu ISA ist der IO-Bereich bei PCI-Geräten aber 64KB groß (ISA: 1KB), bei neueren PCI-Geräten sogar theoretisch 4GB. Genutzt werden praktisch aber nur 64KB. Interrupts sind Interruptquellen, pro Steckplatz und Device maximal 4. Interrupts können level- und edge-triggered sein. DMA-Channel können explizit angefordert werden und beschreiben DMA-Transaktionen, die über den PCI-Controller gesteuert ablaufen. Damit kann man gewisse Datenraten garantieren.
Integration:
PCI braucht im Gegensatz zu ISA eine explizite Softwareunterstützung, allein für die Aufzählung und die Initialisierung der Geräte. Diese Unterstützung liegt heuzutage sowohl im BIOS als auch im Betriebssystem. Das BIOS zählt die Geräte auf und initialisiert sie. Dazu gibt es auch ein eigenes PCI-BIOS, da hilft dir Ralph Browns Interruptlist weiter. Das PCI-BIOS ist (wie das VESA-BIOS auch) zweigeteilt, es gibt einen Realmode-Teil und ein Protected Mode Interface, dieses muß aus dem Realmode heraus angefordert werden. Mit diesem PCI-BIOS kann man auf die Geräte zugreifen und deren Konfiguration auslesen. Viele Geräte lassen sich nur aus dem PM heraus vollständig nutzen, weil ihre Ressourcen jenseits der 1MB-Grenze liegen.
Eine Einstellung im BIOS-Setup regelt bei allen moderenen Rechnern, inwieweit das BIOS die PCI-Geräte initialisiert. Diese Einstellung findet sich meist im PCI-Menü und heißt "Plug&Play OS: Enabled/Disabled". Ist Plug&Play-OS auf "enabled" gesetzt, zählt das PCI-BIOS die Geräte nur auf und initialisiert sie. Ressourcen werden nur pro forma vergeben. Ist Plug&Play OS auf "disabled" gesetzt, führt das BIOS die komplette Initialisierung durch und *fixiert die Ressourcen*. Die Resourcen sind den Geräten dann bis zum nächsten Reset fest zugewiesen. Für Betriebssysteme mit eigenem PCI-Treiber wie Windows, Linux, BSD, Solaris etc. sollte Plug&Play-OS auf enabled stehen. Für Betriebssysteme ohne PCI-Treiber wie DOS oder OS/2, sollte die Einstellung tunlichst auf "disabled" stehen.
Programmierung:
Hast man das PCI-Gerät aus der BIOS-Liste ausgelesen, kann man dessen Ressourcen abfragen, also Adressräume, DMACh und Interrupt. Der Zugriff erfolgt dann wie unter DOS: Also per Speicherzugriff oder IN/OUT und Interrupts. Im Hinterkopf behalten muß man halt, daß die Ressourcen nicht fix sind, man kann also nicht davon ausgehen, daß eine Soundkarte auf Adresse 220 liegt und den Interrupt 5 bedient.
Wie findet man nun ein Gerät? Dazu braucht man dessen Vendor- und Device-ID! Dazu muß man Tabellen wälzen (z.B. auf der Webseite der PCI-SIG) oder den Hersteller fragen. Intels Vendor ID ist z.B. (bezeichnenderweise) 0x8086, die von Creative ist 0x1102. Die Device-ID beschreibt dann das Gerät des Herstellers, diese Device-ID darf er selber aussuchen. Viele Soundblaster-Karten haben die Device-ID 0x0004.
Hat man ein Gerät anhand der Vendor- und Device-ID eindeutig erkannt, kann man davon ausgehen, daß das Gerät vorhanden, funktionsfähig und initialisiert ist. Also, Ressourcen auslesen, programmieren, fertig... 8-)
Was nun Linux macht, bzw. der Treiber, ist aus dem PCI-Treiber die Ressourcen auszulesen und das Gerät zu bedienen.
Da aber unter Linux und anderen UNIXodien Betriebssystemen jedes Gerät und jede Ressource eine Datei ist (everything is a file), benutzt auch der Treiber diese Semantik. Es gibt also im /dev/-Zweig des (virtuellen) Dateisystems auch ein Soundkarten-Device. Gesteuert wird das Device über IOCTL-Aufrufe, also Aufrufe an die Kontroll-Pipe. Dort werden Konfigurationsparameter, wie Samplerate oder Wortbreite des Samples gesetzt oder ausgelesen. Die eigentlichen Sounddaten kann man dann durch normale Filezugriffe auf das Device schicken.
Felix Kaiser
22.08.2007, 20:23
Wenn du bisher nur ISA Soundkarten programmiert hast denke ich mal, dass du Sound Blaster programmiert hast. Das wird dir bei den meisten PCI Soundkarten wenig helfen. AC97 ist der Standard, der inzwischen auch schon wieder von HD Audio abgelöst wird, nach und nach. Bei AC97 musst du mittels Busmastering Audiodaten (z.B. PCM oder was es da für Formate gibt) mit einer festen Datenrate (z.B. 48kHz) an einen Kanal übertragen. Genauer hab ich mich damit noch nie befasst. Aber in die Richtung gehts. Gibt AC97 Chips die in der Hardware SoundBlaster emulieren können, so dass man nur die Legacy Ports freischalten braucht, beispielsweise bei VIA oder C-Media. Aber bei vielen anderen muss SoundBlaster emuliert werden über Software. Ist eine lustige Geschichte, erfordert residente DOS Treiber und funktioniert nur bei Zugriffen mit niedrigerem GPL als IOPL. Ansonsten kann der Treiber die E/A Zugriffe nicht abfangen und auf die AC97 Hardware übertragen. Unnötig zu erwähnen, dass dabei Rechenleistung in der Softwareemulation verschossen wird.
Sich an quelloffenen Treibern orientieren ist da eigentlich der beste Tipp. Muss ja nicht Linux sein. Systeme wie NetBSD verfügen über viel klarere Strukturen im Kernel. Da ist alles am richtigen Platz und der Quelltext ist nicht mit Workarounds verseucht. ;-)
LeadingZero
10.09.2007, 14:41
Jo, vielen lieben Dank für eure Mühe.
Ich muß das alles erstmal schlucken und werd dann sehen, wie ich weiter vorgehe...
WauCoder
01.02.2008, 21:18
Jetzt hab ich mit den Leuten von CREATIVE gesprochen und die meinten, daß sie keine Hardwareinformationen über ihre Soundkarten herausgeben, ich mich lediglich an Directsound, Opensound oder ASIO halten müsse, um deren Soundkarten anzusprechen.
Ätzend :mauer:
Es gibt vereinzelte "alternative" PCI Sound Treiber/Code ... insbesondere für SB Live 24 ... IMHO alles aus Linux "gerippt" ... aber auch ich war aus dem Linux code nicht schlau :mauer: ... die "Referenz" sind halt die Windoof-Treiber, mehrere 100 KB bis mehrere MB gross ... aber letztlich müssen die Linux Treiber von dort "gestohlen" worden sein :confused:
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.