\input{confighandout} \subsection{Kernel-Grundlagen} Der Linux-Kernel ist moderner Betriebssystemkern, der sich unter anderem durch folgende Eigenschaften auszeichnet: \begin{itemize} \item Freie Software (GPL Version 2) \item Auf vielen Plattformen lauffähig \item Hohe Skalierbarkeit vom Handy bis zum Supercomputer \item Große Anzahl integrierter Treiber \item Einfache Entwicklung eigener Treiber \item Codequalität auf hohem Niveau \item Qualitätssicherung durch Code-Review unabhängiger Personen \item ca. 10 Millionen Codezeilen (ca. 80\% davon Treiber) \item hohes Entwicklungstempo \item hervorragende Netzwerk-Fähigkeiten \item Echtzeit-Fähigkeit leicht und sauber erreichbar \end{itemize} Diese Eigenschaften haben dazu geführt, dass im Embedded-Bereich heute die große Mehrzahl der neu begonnenen Projekte mit Linux realisiert werden. Aber auch in vielen anderen Bereichen wie dem Cluster-Computing (Google, Rendern von Spielfilm-Effekten in Hollywood) werden die Aufgaben heute fast ausschließlich mit Linux gelöst. \subsubsection{Aufbau des Kernels} Der Sourcecode des Kernels ist recht übersichtlich in Subsysteme gegliedert. Die Grenzen der einzelnen Subsysteme sind keinesfalls scharf definiert, aber trotz einzelner Überlappungen und gegenseitigen Abhängigkeiten ist doch ein hohes Mass an Unabhängigkeit erreicht worden. Dies trägt entscheidend zur Qualität bei, da Änderungen in einem Bereich andere Subsysteme meist nur wenig beeinflussen. \begin{figure}[h] \centering \includegraphics[width=0.8\textwidth]{images/Subsystems.png} \caption{Kernel-Aufbau aus Subsystemen} \label{img:subsystems} \end{figure} Abbildung \ref{img:subsystems} zeigt schematisch diesen Aufbau. Man unterscheidet zunächst zwischen Subsystemen des \emph{Kernel-Core} und Treiber-Subsystemen. Zum Kernel-Core rechnet man Subsysteme wie den für die Prozessumschaltung verantwortlichen Scheduler, Memory-Management, Timer und ähnliche Einheiten, die zur grundsätzlichen Funktionalität des Kernel gehören und auf allen Plattformen vorhanden sein müssen. Der weitaus größte Teil des Kernels besteht aus Treibern. Hier kann man wiederum unterscheiden zwischen Treibern für Hostcontroller von Schnittstellen wie PCI, USB oder I2C und den Treibern für Geräte, die diese Schnittstellen benutzen. Abbildung \ref{img:subsystems} deutet an, dass es zwischen diesen Treibern durchaus Querverbindungen geben kann. Eine PCI-Karte kann ja durchaus einen USB- oder I2C-Hostcontroller enthalten, und ein bestimmter Sound-Chip könnte wahlweise per USB oder per PCI angeschlossen sein. Unabhängig von der Art der Schnittstellen gibt es ein Repertoire an Funktionen, die alle Treiber benötigen. Dazu gehört etwa die Funktionalität, Treiber und Geräte einander zuzuordnen. Auch die Darstellung des Treiber-Baums im \cmd{sysfs} kommt automatisch allen Treibern zugute. Diese übergeordneten Treiberfunktionen werden als \emph{Driver Core} bezeichnet. \subsubsection{Kernel Maintainer} Jedes Subsystem wird normalerweise von einem, manchmal auch mehreren Programmierern betreut. Diese Betreuer bezeichnet man als \emph{Maintainer}. Ihre Aufgabe besteht darin, den Code selbst weiter zu entwickeln, und vor allem die Erweiterungsvorschläge anderer Entwickler zu prüfen. Sie haben als Spezialisten für ein bestimmtes Sachgebiet eine wichtige Aufgabe bei der Weiterentwicklung und Qualitätssicherung des Kernels. Da der Kernel von einer freien Entwicklergemeinde entwickelt wird, haben Maintainer natürlich keine Weisungsbefugnisse gegenüber anderen Programmierern. Dennoch ist es kaum möglich, eine Änderung, die der zuständige Maintainer ablehnt, in den offiziellen Kernel zu bringen. Die Programmierer, die sich vor allem mit der Integration der vielen Änderungsvorschläge befassen (an der Spitze Linus Torvalds), respektieren üblicherweise die Entscheidung der zuständigen Maintainer. Die Kernel-Maintainer sind in der Datei \cmd{MAINTAINERS} im Hauptverzeichnis der Kernelquellen aufgelistet. Dort findet man auch die für das jeweilige Thema zuständige Mailingliste. Fragen oder Änderungsvorschläge sollte man \emph{immer} an die Mailingliste senden und nicht persönlich an den Maintainer! \subsubsection{Entwicklungsprozess} Änderungen am Linux-Kernel erfolgen ausschließlich durch \emph{Patche}. Ein Patch ist eine durch das Programm \cmd{diff} Textdatei, die die Änderungen durch Angabe der entfernten beziehungsweise hinzugefügten Zeilen beschreibt. Das verwendete Textformat ist sehr gut lesbar und ermöglicht ein schnelles Erkennen der vorgenommenen Änderungen. Wer eine Änderung in den offiziellen Kernel bringen möchte, generiert zunächst einen solchen Patch. Dann sendet er den Patch in einer Mail an die zuständige Mailingliste und nimmt dabei den oder die zuständigen Maintainer in Cc:, zusätzlich eventuell weitere Autoren von betroffenem Quellcode. Meist erhält er dann innerhalb kurzer Zeit Antworten mit Reviews seines Patch. Je nachdem, wie diese ausfallen, wird er seine Änderungen noch einmal überarbeiten und erneut einsenden. Für Änderungen am Kernel-Code gelten sehr strenge Richtlinien für den \emph{Coding Style}, das Erzeugen und Versenden des Patch sowie das Verhalten auf Mailinglisten. Grundsätzlich sollte der Anbieter eines Patch in der Lage sein, mit rein technischen Argumenten zu erläutern, warum es eine Verbesserung darstellt, den Patch aufzunehmen. Informationen dazu findet man in den Kernelquellen unter \cmd{Documentation/CodingStyle} \cmd{Documentation/SubmittingPatches} \subsubsection{Kernel-Konfiguration} Der Kernel ist durch eine Vielzahl an Optionen (mehrere 1000) in weiten Bereichen konfigurierbar. Die Konfiguration wird im Hauptverzeichnis der Kernelquellen in der versteckten Datei \cmd{.config} gespeichert. Diese Datei wird normalerweise nicht von Hand editiert, sondern menügesteuert mit Hilfe eines integrierten Konfigurationstools, das man mit \cmd{make menuconfig} aufruft. Diese Tool bezieht seine Informationen aus Dateien mit dem Namen \cmd{Kconfig}, die sich in jedem Unterverzeichnis des Quellcodebaums befinden. Diese Dateien enthalten die Bezeichnung der Option und die zugehörigen Abhängigkeiten und Hilfetexte. Das Kernel-Buildsystem stellt ein eigenes Subsystem dar und hat einen eigenen Maintainer. Es handhabt den kompletten Build-Prozess des Kernels und unterstützt dabei auch explizit Cross-Compiling. \input{tailhandout}