Open Source im professionellen Einsatz

Kernel- und Treiberprogrammierung mit dem Kernel 2.6 - Folge 52

Kern-Technik

,

Simulierende Module ermöglichen es, auf Hardware zuzugreifen, die gar nicht im Rechner eingebaut ist. Dreh- und Angelpunkt dafür ist ein modifizierter Gerätetreiber.

Virtualisierung macht eine typischerweise nur einmal vorhandene Hardware mehreren Komponenten scheinbar exklusiv zugänglich. Es geht aber noch mehr: Per Simulation greifen Linux-Anwender auf Hardware zu, die in ihren Rechnern überhaupt nicht existiert.

Das ist nützlich, wenn diese sich beispielsweise noch in der Entwicklung befindet, ihre Entwickler aber bereits notwendige Treiber und erste Applikationen programmieren und testen wollen - oder wenn eine Hardware schlichtweg zu teuer ist. Dann sammeln die Entwickler bereits erste Erfahrung mit der nicht vorhandenen Hardware, selbst wenn Zeitverhalten und eventuell auch der Funktionsumfang nicht vollständig dem Original entsprechen.

Hardwarezugriffe umbiegen

Was Linux-Interessierte dafür benötigen: ein Simulationsprogramm und ein Treiber (siehe Abbildung 1). Bei ihm darf es sich auch um ein bereits existierendes Exemplar handeln, das für die Simulation nur ein wenig zu modifizieren ist. In jedem Fall aber ist der Treiber der Dreh- und Angelpunkt des Ganzen, denn er leitet die Anfragen der Applikation entweder an die real existierende Hardware oder eben an die alternativ oder ausschließlich eingesetzte Simulation weiter.

Abbildung 1: Ein modifizierter Treiber in Kombination mit einem Simulationsprogramm ermöglicht es, Hardware vorzutäuschen, ohne dass Entwickler ihre Applikationen dafür verändern müssen.

Abbildung 1: Ein modifizierter Treiber in Kombination mit einem Simulationsprogramm ermöglicht es, Hardware vorzutäuschen, ohne dass Entwickler ihre Applikationen dafür verändern müssen.

Ein gutes Softwaredesign vorausgesetzt muss der Entwickler einen Treiber nur minimal verändern, um eine Simulation möglich zu machen. Konkret heißt dies, die Zugriffe auf die reale Hardware (siehe Kasten "Memory-mapped versus IO-mapped"), die über die Maschinenbefehle »inX«, »outX« beziehungsweise über die Funktionen »readX()« sowie »writeX()« erfolgen, auf »simulation_inX()«, »simulation_outX()«, »simulation_readX()« und »simulation_writeX()« umzubiegen (siehe Abbildung 2). Die so modifizierten Funktionen reichen die übergebenen Daten dann bei Bedarf an das eigentliche Simulationsprogramm weiter.

Abbildung 2: Funktionspointer biegen im Treiber den Hardwarezugriff auf die Simulation um. Dargestellt ist hier nur das Schreiben auf die Hardware.

Abbildung 2: Funktionspointer biegen im Treiber den Hardwarezugriff auf die Simulation um. Dargestellt ist hier nur das Schreiben auf die Hardware.

Für den erfahrenen C-Programmierer ist das Umbiegen von Funktionen ein klarer Fall von Funktionspointern. Die könnten sie beispielsweise »mapper_inX«, »mapper_outX«, »mapper_readX« oder »mapper_writeX« nennen. Das Anhängsel »X« steht übrigens für den jeweils ersten Buchstaben von Byte, Word oder Long, je nachdem, ob ein 1-, 2- oder 4-Byte-Zugriff erfolgt. »mapper_readb« zeigt also auf eine Funktion, die genau ein einzelnes Byte einliest.

Das Simulationsprogramm selbst lässt sich bei hohen Anforderungen an das Zeitverhalten im Kernel realisieren. Attraktiver ist jedoch eine Applikation im Userland, die vor allem einfacher zu implementieren und zu konfigurieren ist. Sie erleichtert auch eine Visualisierung der simulierten Hardware.

Memory-mapped versus
IO-mapped

Peripherie, die ein Rechner wie Hauptspeicher über den normalen Adressbus in den Adressraum einer CPU einblendet, nennt man Memory-mapped. Einige Prozessorhersteller - allen voran Intel - haben zusätzlich zum normalen Adressbus einen zweiten, abgespeckten Adressbus eingebaut, der vor allem der Ankopplung von IO-Hardware dient (IO-mapped). Historisch betrachtet erweiterte das nicht nur den Adressraum, sondern sparte gleichzeitig den Hardware-Aufwand für die Dekodierung der Peripherie. Software-technisch muss die CPU natürlich erfahren, wenn sie eine Adressinformation an den neuen Adressbus, dem so genannten IO-Bus, anlegen soll. Die Assemblerbefehle, die den Standardbefehl »mov« für den Zugriff auf Speicher ergänzen, nennt Intel »in« und »out«.

Linux stellt dem Treiberprogrammierer Wrapperfunktionen für den direkten Hardwarezugriff zur Verfügung: Per »readX()« und »writeX()« greift er auf Memory-mapped-Hardware zu, mit den Makros »inX« und »outX« auf die Port-mapped-Hardware.

Simulator ankoppeln

Als Schnittstelle zwischen Simulationsprogramm und modifiziertem Treiber kommen vor allem das Proc-Filesystem [1], das Sys-Filesystem [2], das Netlink-Interface [3] oder die normale Treiberschnittstelle in Frage. Letztere ist mit den Systemcalls »open()«, »close()«, »read()« und »write()« gerade dem Applikationsprogrammierer gut bekannt. Das Simulationsprogramm erhält Informationen vom Treiber dadurch, dass es per »read()« auf eine zusätzliche Gerätedatei zugreift. Einen neuen Hardwarestatus übermittelt der Kernel dem modifizierten Treiber mit Hilfe von »write()«.

Diesen Artikel als PDF kaufen

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook