\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}
