diff options
| author | Manuel Traut <manut@linutronix.de> | 2009-06-22 15:47:30 +0200 |
|---|---|---|
| committer | Manuel Traut <manut@linutronix.de> | 2009-06-22 15:47:30 +0200 |
| commit | 9cbb0a699f398daffa8c1808d02bf447ebf0c1f0 (patch) | |
| tree | ea3f4d4081b0648e1da7b1e1d8d3dabe12705a0a /kernel-devel | |
| parent | 9e0bab8ec70646ed9c51d5c7d272da4b51698c6c (diff) | |
| parent | 719085c3dc98ab3df272476e16e983e4a16fe14b (diff) | |
Merge branch 'master' of ssh://tglx.de/home/linutronix/git/schulung
Diffstat (limited to 'kernel-devel')
16 files changed, 788 insertions, 36 deletions
diff --git a/kernel-devel/Makefile b/kernel-devel/Makefile new file mode 100644 index 0000000..f325edd --- /dev/null +++ b/kernel-devel/Makefile @@ -0,0 +1,6 @@ +SUBDIRS = char-device driver-basics kernel-basics kernel-best-practices kernel-build uio-driver + +all clean: + for dir in $(SUBDIRS) ; do \ + (cd $$dir && make $@); \ + done diff --git a/kernel-devel/kernel-basics/Makefile b/kernel-devel/kernel-basics/Makefile new file mode 100644 index 0000000..aad5bb5 --- /dev/null +++ b/kernel-devel/kernel-basics/Makefile @@ -0,0 +1,9 @@ +all: + pdflatex pres_kernel-basics_de.tex + pdflatex hints_kernel-basics_de.tex + pdflatex handout_kernel-basics_de.tex + pdflatex handout_kernel-basics_de.tex + +clean: + rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out + diff --git a/kernel-devel/kernel-basics/handout_kernel-basics_de.tex b/kernel-devel/kernel-basics/handout_kernel-basics_de.tex index 4c391b2..057f4bc 100644 --- a/kernel-devel/kernel-basics/handout_kernel-basics_de.tex +++ b/kernel-devel/kernel-basics/handout_kernel-basics_de.tex @@ -1,17 +1,142 @@ -\documentclass{article} +\documentclass{lxarticle} \usepackage{german} \usepackage[utf8]{inputenc} +\usepackage{lxheaders} +\usepackage{lxextras} \begin{document} -\section*{Titel} +\section*{Kernel-Grundlagen} -\subsection*{Abschnitt1} +Der Linux-Kernel ist moderner Betriebssystemkern, der sich unter anderem +durch folgende Eigenschaften auszeichnet: -Text +\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} -\subsection*{Abschnitt2} +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. -Text +\subsection*{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. + +\subsection*{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! + +\subsection*{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} + +\subsection*{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. \end{document} diff --git a/kernel-devel/kernel-basics/pres_kernel-basics_de.tex b/kernel-devel/kernel-basics/pres_kernel-basics_de.tex index 07db328..8b6161e 100644 --- a/kernel-devel/kernel-basics/pres_kernel-basics_de.tex +++ b/kernel-devel/kernel-basics/pres_kernel-basics_de.tex @@ -1,24 +1,103 @@ -\documentclass{article} +\documentclass{beamer} +\usetheme{linutronix} \usepackage{german} \usepackage[utf8]{inputenc} +\usepackage{pgf} +\usepackage{graphicx} +\usepackage{lxextras} + +\title{Kernel-Grundlagen} +\institute{Linutronix GmbH} \begin{document} -\section*{Block \lq Was ist Linux?\rq} +\maketitle + -\subsection*{Lernziele} +% ----- Slide ------------------ +\begin{frame} +\frametitle{Kernel-Eigenschaften} \begin{itemize} -\item Lernziel 1 -\item Lernziel 2 -\item Lernziel 3 +\item Freie Software (GPL Version 2) +\pause +\item Auf vielen Plattformen lauffähig +\pause +\item Hohe Skalierbarkeit vom Handy bis zum Supercomputer +\pause +\item Große Anzahl integrierter Treiber +\pause +\item Einfache Entwicklung eigener Treiber +\pause +\item Codequalität auf hohem Niveau +\pause +\item Qualitätssicherung durch Code-Review unabhängiger Personen +\pause +\item ca. 10 Millionen Codezeilen (ca. 80\% davon Treiber) +\pause +\item hohes Entwicklungstempo +\pause +\item hervorragende Netzwerk-Fähigkeiten +\pause +\item Echtzeit-Fähigkeit leicht und sauber erreichbar \end{itemize} +\end{frame} -\subsection*{Unterrichts-Ablauf} +% ----- Slide ------------------ +\begin{frame} +\frametitle{Aufbau des Kernels} +\centering +\includegraphics[width=0.8\textwidth]{images/Subsystems.png} +\end{frame} -Hinweise zur Präsentation, Zeitplanung, etc. +% ----- Slide ------------------ +\begin{frame} +\frametitle{Kernel Maintainer} +\begin{itemize} +\item Betreuer eines Subsystems oder Treibers +\pause +\item Verantwortlich für Weiterentwicklung +\pause +\item Review von Änderungsvorschlägen +\pause +\item Annehmen/Ablehnen von Änderungsvorschlägen +\pause +\item Weitergabe/Verwaltung angenommener Änderungen +\end{itemize} +\end{frame} -\subsection*{Übungen bei vorhandener Hardware} +% ----- Slide ------------------ +\begin{frame} +\frametitle{Entwicklungsprozess} +\begin{itemize} +\item Änderungsvorschläge in Form von Patchen +\pause +\item Review und Diskussion auf Mailinglisten +\pause +\item strenge Richtlinien für Coding Style +\pause +\item strenge Richtlinien für Form und Weitergabe von Patchen +\pause +\item Nur technische Argumente zählen! +\end{itemize} +\end{frame} + +% ----- Slide ------------------ +\begin{frame} +\frametitle{Kernel-Konfiguration} +\begin{itemize} +\item Grosse Zahl von Konfigurations-Optionen +\pause +\item Speicherung in \cmd{.config} +\pause +\item Ändern der Konfiguration: \cmd{make menuconfig} +\pause +\item Informationen über Optionen in \cmd{Kconfig}-Dateien +\pause +\item Kernel-Buildsystem: Eigenes Subsystem mit eigenem Maintainer +\pause +\item Unterstützt explizit auch Cross-Compiling +\end{itemize} +\end{frame} -Hinweise zu Übungen, Zeitlimit dazu. \end{document} diff --git a/kernel-devel/kernel-build/Makefile b/kernel-devel/kernel-build/Makefile new file mode 100644 index 0000000..d221473 --- /dev/null +++ b/kernel-devel/kernel-build/Makefile @@ -0,0 +1,9 @@ +all: + pdflatex pres_kernel-build_de.tex + pdflatex hints_kernel-build_de.tex + pdflatex handout_kernel-build_de.tex + pdflatex handout_kernel-build_de.tex + +clean: + rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out + diff --git a/kernel-devel/kernel-build/handout_kernel-build_de.tex b/kernel-devel/kernel-build/handout_kernel-build_de.tex index 4c391b2..f0e5fae 100644 --- a/kernel-devel/kernel-build/handout_kernel-build_de.tex +++ b/kernel-devel/kernel-build/handout_kernel-build_de.tex @@ -1,17 +1,230 @@ -\documentclass{article} +\documentclass{lxarticle} \usepackage{german} \usepackage[utf8]{inputenc} +\usepackage{lxheaders} +\usepackage{lxextras} \begin{document} -\section*{Titel} +\section*{Kernel konfigurieren und kompilieren} -\subsection*{Abschnitt1} +\subsection*{Vorarbeiten} -Text +Bevor man einen Kernel konfigurieren kann, sollte man wissen, was man will. +Das hört sich zunächst nach einer trivialen Binsenweisheit an, kann aber +manchmal tatsächlich nicht ganz einfach sein. -\subsection*{Abschnitt2} +Zunächst sollte man möglichst viele Informationen über die fragliche Hardware +sammeln. Dazu gehört die genaue Prozessorversion sowie Typen und Versionen +der angeschlossenen Chips. Insbesondere die Chips, die bereits beim Booten +benötigt werden, sollten klar sein. Dazu gehören auf üblichen PCs der, +Chipsatz mit ATA/SATA-Controller oder, je nach gewünschter Bootquelle auch +der USB- oder Netzwerk-Chip. + +Bei Embedded Devices kommen oft noch NAND-Controller hinzu. In diesem Fall +sollte man auch über die genauen Daten der angeschlossenen NAND-Chips +informiert sein. + +Weiterhin muss man sich überlegen, von welchen Dateisystemen man booten +möchte. Gängige Varianten sind ext2, ext3, NFS, oder NAND-Dateisysteme wie +jffs2 oder ubifs. FAT eignet sich nicht für ein Linux-Rootfilesystem, da es +beispielsweise keine Gerätedateien unterstützt. Will man Linux von einem +USB-Stick booten, so wird man diesen dazu beispielsweise mit einem +ext2-Dateisystem versehen. + + \subsection*{Kernel-Konfiguration} + +Mit diesen Informationen versehen, kann man jetzt die Konfiguration beginnen. +Dies erfolgt durch Eingabe von + +\cmd{make menuconfig} + +Abbildung \ref{img:menuconfig} zeigt die oberste Ebene des Menüs, das dann erscheint. + + +\begin{figure}[h] +\centering +\includegraphics[width=0.8\textwidth]{images/menu_rt_001.png} +\caption{Menü zur Kernel-Konfiguration} +\label{img:menuconfig} +\end{figure} + +Am oberen Rand gibt das Menü eine stichwortartige Erklärung zur Bedienung. +Man sollte bei der Konfiguration zuerst grundlegende Dinge wie den +Prozessortyp angeben, da untergeordnete Eigenschaften oder Treiber davon +abhängig sein können. + +\subsection*{Module, ja oder nein?} +Bei üblichen Kerneln für Desktop-Systeme wird man immer einen Großteil der +Treiber als Module kompilieren. Solche Rechner besitzen viele Schnittstellen, +über die man später die Hardware erweitern kann, und kann den Kernel bereits +mit den möglicherweise vorkommenden Treiber-Modulen ausstatten. Diese werden +dann nur bei Bedarf nachgeladen. + +Bei Embedded Systems ist die Situation anders. Hier ist die Hardware meist +fest vorgegeben, so dass man schon beim Kompilieren genau weiss, welche Treiber +benötigt werden. Ausserdem ist der im Rootfs zur Verfügung stehende Platz oft +beschränkt, man wird hier ungern Speicher für unnötige Treiber-Module +verschwenden. + +Andererseits ist es manchmal praktisch, einen Treiber als Modul vorliegen +zu haben. Speziell während der Entwicklung eines eigenen Treibers ist es +vorteilhaft, dass man einfach durch Austausch des Moduls eine neue Version +ausprobieren kann. Unter Linux muss man dabei nicht einmal neu booten, +sondern kann einen Treiber mit + +\cmd{modprobe mein\_modul} installieren und mit + +\cmd{rmmod mein\_modul} wieder deinstallieren. + +Die Entscheidung, ob man einen Kernel ganz ohne Module baut, hängt vom +Einzelfall ab. Bei Embedded Systems kommt dies aber durchaus öfter vor. + +Aus verständlichen Gründen dürfen Treiber, die zum Booten und Mounten des +Rootfs benötigt werden, niemals als Module gebaut werden! + +\subsection*{initrd} + +Die Kernel von Distributionen haben das Problem, dass sie auf möglichst vielen +unterschiedlichen Rechnern booten müssen. Würde man die Treiber für alle +denkbaren Kombinationen fest in den Kernel einkompilieren, so hätte man einen +riesigen Kernel, von dem der Großteil des Codes niemals benutzt würde. + +Die statt dessen verwendete Lösung besteht in einem Verfahren, bei dem der +Kernel beim Booten eine RAM-Disk anlegt und diese mit einem vorbereiteten +Image füllt. Das Image enthält sämtliche in Frage kommenden Treiber als Module. +Nach dem Booten und dem Mounten des Root-Filesystems kann die RAM-Disk wieder +aus dem Speicher entfernt werden. Dieses Verfahren nennt man \emph{initrd} +(von \emph{Initial RAM Disk}). + +Wenn man einen Kernel für ein bestimmtes Board selbst kompiliert, braucht man +nie eine initrd, da man ja genau die richtigen Treiber fest einkompilieren kann. + +\subsection*{initramfs} + +Ein anderes Verfahren, bei dem der Kernel zunächst eine RAM-Disk anlegt, ist +\emph{initramfs}. Im Unterschied zu initrd wird diese aber nicht aus einem +externen Image geladen, sondern das Image wird bereits beim Kompilieren zum +Kernel dazugelinkt. Auch hier wird der von der RAM-Disk belegte Speicher am +Ende wieder freigegeben. + +Das initramfs wird vom Kernel wie ein normales Root-Filesystem gemountet. +Üblicherweise verwendet man ein minimales System, etwa basierend auf uclibc +und einer busybox. Man kann in den Startskripten dieses Minimalsystems jetzt +Aktionen ausführen, bevor das eigentliche Rootfs gemountet wird. + +Eine Anwendung dieses Verfahrens ist ein kleiner Bootkernel, der von einem +IPL gestartet wird. In seinem initramfs befinden sich Startskripte, die den +eigentlichen Produktiv-Kernel aus einer beliebigen Quelle nachladen und dann +per \cmd{kexec} starten. Der Vorteil bei diesem Verfahren ist, dass der +Bootkernel bereits jeden beliebigen Treiber (beispielsweise einen kompletten +USB-Stack) enthalten kann, während Bootloader meist nur unvollständig mit +den gängigsten Treibern versehen sind. + +Eine weitere Anwendung sind Firmware-Updates. So könnten die Startskripte +des initramfs beispielsweise auf einem Server nachschauen, ob Updates +vorhanden sind, und diese dann anwenden. + +\subsection*{Kernel kompilieren} + +Nach abgeschlossener Kernel-Konfiguration kompiliert man den Kernel einfach +durch Eingabe von + +\begin{lstlisting} +make +\end{lstlisting} + +Falls der zum Kompilieren verwendete Rechner mehrere CPUs besitzt, kann man +den Vorgang beschleunigen, indem man \cmd{make} anweist, mehrere Jobs +gleichzeitig zu starten. Für die Zahl der Jobs ist eine häufig genannte +Empfehlung die doppelte Anzahl der CPUs plus eins. Auf einem Dual-Core würde +man also folgenden Befehl verwenden: + +\begin{lstlisting} +make -j3 +\end{lstlisting} + +Will man den Kernel für eine andere Architektur als die des Compile-Rechners +crosskompilieren, so muss man \cmd{make} mitteilen, mit welcher Toolchain und +für welche Architektur gebaut werden soll. Damit man die doch etwas länglichen +Optionen nicht immer wieder von Hand eintippen muss, schreibt man sie am Besten +in ein kleines Skript, das man dann anstelle von \cmd{make} aufruft. Ein Skript +für die ARM-Architektur unter Verwendung der Codesourcery-Toolchain 2007q3 +könnte etwa so aussehen: + +\begin{lstlisting} +#!/bin/sh + +ARCH="arm" +CROSS="/opt/arm-2007q3/bin/arm-none-linux-gnueabi-" +export INSTALL_MOD_PATH="/rfs" + +make ARCH=$ARCH CROSS_COMPILE=$CROSS $@ +\end{lstlisting} + +Speichert man dies beispielsweise unter dem Namen \cmd{makearm} im +Hauptverzeichnis der Kernelquellen, so ergibt sich folgender Aufruf: +\begin{lstlisting} +./makearm -j3 +\end{lstlisting} + +\subsection*{Kernel installieren} + +Einen Kernel für den lokalen Rechner (also den, auf dem man auch kompiliert +hat) installiert man einfach durch Eingabe von + +\begin{lstlisting} +make install +\end{lstlisting} + +Dies führt folgende Aktionen durch (Beispiel für einen Kernel 2.6.30): +\begin{itemize} +\item Falls es im Verzeichnis \cmd{/boot} bereits ein \cmd{vmlinuz-2.6.30} + gibt, wird es in \cmd{vmlinuz-2.6.30.old} umbenannt +\item Kopieren von \cmd{arch/<Architektur-Name>/boot/zImage} nach + \cmd{/boot/vmlinuz-2.6.30} +\item Anlegen eines symbolischen Link \cmd{vmlinuz -> vmlinuz-2.6.30} in + \cmd{/boot} +\end{itemize} + +Anschliessend darf man nicht vergessen, auch die Module des neuen Kernels +zu installieren: + +\begin{lstlisting} +make modules_install +\end{lstlisting} + +Dabei werden alle Module (Dateien mit der Endung \cmd{*.ko} in Verzeichnisse +unter \cmd{/lib/modules/2.6.30/...} kopiert. Ausserdem werden dort +Zusatzinformationen zu den Modulen und ihren Abhängigkeiten generiert. + +\emph{VORSICHT!} Wenn man einen Kernel für eine andere Architektur +crosskompiliert hat, darf man \emph{NIEMALS} leichtfertig +\cmd{make modules\_install} aufrufen, da dies ohne weitere Warnung die +eigenen Module mit den natürlich nicht verwendbaren Modulen der fremden +Architektur überschreiben würde! + +Das oben aufgeführte Skript zeigt die korrekte Vorgehensweise. In der Variablen +\cmd{INSTALL\_MOD\_PATH} kann man ein anderes Root-Filesystem angeben, in das +die Module installiert werden sollen. Im Beispiel oben würde der Befehl + +\begin{lstlisting} +./makearm modules_install +\end{lstlisting} + +die Module nach \cmd{/rfs/lib/modules/2.6.30/...} installieren. Hat man sein +Root-Filesystem per NFS aus diesem Verzeichnis gemountet, so stehen die Module +sofort und ohne Reboot zur Verfügung. Diese Vorgehensweise hat sich bei der +Entwicklung von Treibern für Embedded Systems sehr bewährt. + +\subsection*{Kontrollfragen} + +\begin{enumerate} +\item Beschreiben Sie Unterschiede zwischen initrd und initramfs. +\item Warum braucht man bei selbst kompilierten Kerneln in der Regel keine + initrd? +\item Nennen Sie eine Anwendung von initramfs. +\end{enumerate} -Text \end{document} diff --git a/kernel-devel/kernel-build/images/menu_rt_001.png b/kernel-devel/kernel-build/images/menu_rt_001.png Binary files differnew file mode 100644 index 0000000..27f26cd --- /dev/null +++ b/kernel-devel/kernel-build/images/menu_rt_001.png diff --git a/kernel-devel/kernel-build/pres_kernel-build_de.tex b/kernel-devel/kernel-build/pres_kernel-build_de.tex index 07db328..1489f12 100644 --- a/kernel-devel/kernel-build/pres_kernel-build_de.tex +++ b/kernel-devel/kernel-build/pres_kernel-build_de.tex @@ -1,24 +1,23 @@ -\documentclass{article} +\documentclass{beamer} +\usetheme{linutronix} \usepackage{german} \usepackage[utf8]{inputenc} +\usepackage{pgf} +\usepackage{graphicx} +\usepackage{lxextras} -\begin{document} - -\section*{Block \lq Was ist Linux?\rq} +\title{Linux-Kernel konfigurieren und kompilieren} +\institute{Linutronix GmbH} -\subsection*{Lernziele} -\begin{itemize} -\item Lernziel 1 -\item Lernziel 2 -\item Lernziel 3 -\end{itemize} +\begin{document} -\subsection*{Unterrichts-Ablauf} +\maketitle -Hinweise zur Präsentation, Zeitplanung, etc. -\subsection*{Übungen bei vorhandener Hardware} +% ----- Slide ------------------ +\begin{frame} +\frametitle{Hallo} +\end{frame} -Hinweise zu Übungen, Zeitlimit dazu. \end{document} diff --git a/kernel-devel/uio-driver/Makefile b/kernel-devel/uio-driver/Makefile new file mode 100644 index 0000000..d212291 --- /dev/null +++ b/kernel-devel/uio-driver/Makefile @@ -0,0 +1,10 @@ +all: + pdflatex pres_uio-driver_de.tex + pdflatex pres_uio-driver_en.tex + pdflatex hints_uio-driver_de.tex + pdflatex handout_uio-driver_de.tex + pdflatex handout_uio-driver_de.tex + +clean: + rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out + diff --git a/kernel-devel/uio-driver/images/greg-all-hardware.jpg b/kernel-devel/uio-driver/images/greg-all-hardware.jpg Binary files differnew file mode 100644 index 0000000..f7ab989 --- /dev/null +++ b/kernel-devel/uio-driver/images/greg-all-hardware.jpg diff --git a/kernel-devel/uio-driver/images/greg-kernel-org.jpg b/kernel-devel/uio-driver/images/greg-kernel-org.jpg Binary files differnew file mode 100644 index 0000000..dbfb915 --- /dev/null +++ b/kernel-devel/uio-driver/images/greg-kernel-org.jpg diff --git a/kernel-devel/uio-driver/images/hjk-desperate.jpg b/kernel-devel/uio-driver/images/hjk-desperate.jpg Binary files differnew file mode 100644 index 0000000..740f574 --- /dev/null +++ b/kernel-devel/uio-driver/images/hjk-desperate.jpg diff --git a/kernel-devel/uio-driver/images/ioctl-vs-uio.png b/kernel-devel/uio-driver/images/ioctl-vs-uio.png Binary files differnew file mode 100644 index 0000000..8536934 --- /dev/null +++ b/kernel-devel/uio-driver/images/ioctl-vs-uio.png diff --git a/kernel-devel/uio-driver/images/konventioneller-treiber.png b/kernel-devel/uio-driver/images/konventioneller-treiber.png Binary files differnew file mode 100644 index 0000000..bea54da --- /dev/null +++ b/kernel-devel/uio-driver/images/konventioneller-treiber.png diff --git a/kernel-devel/uio-driver/images/uio-treiber.png b/kernel-devel/uio-driver/images/uio-treiber.png Binary files differnew file mode 100644 index 0000000..caa2152 --- /dev/null +++ b/kernel-devel/uio-driver/images/uio-treiber.png diff --git a/kernel-devel/uio-driver/pres_uio-driver_en.tex b/kernel-devel/uio-driver/pres_uio-driver_en.tex new file mode 100644 index 0000000..8468894 --- /dev/null +++ b/kernel-devel/uio-driver/pres_uio-driver_en.tex @@ -0,0 +1,302 @@ +\documentclass{beamer} +\usetheme{linutronix} +\usepackage{german} +\usepackage[utf8]{inputenc} +\usepackage{pgf} +\usepackage{graphicx} + +\title{The Userspace I/O Framework (UIO)} +\author{Hans-Jürgen Koch} +\institute{Linutronix GmbH} + +\begin{document} + +\maketitle + +% ----- Slide "Desperate programmer" ------------------ +\begin{frame} +\includegraphics[width=11cm]{images/hjk-desperate.jpg} +\end{frame} + +% ----- Slide "Linux device drivers" ------------------ +\begin{frame} +\frametitle{Linux device drivers} +\pause +\begin{itemize} +\item Standard devices +\pause +\item Non-standard devices +\end{itemize} +\end{frame} + +% ----- Slide "Standard devices" ----------------------- +\begin{frame} +\frametitle{Standard devices} +\pause +\begin{itemize} +\item Handled by a kernel subsystem (USB, networking...) +\pause +\item Hardware specific part relatively small +\pause +\item Examples of similar drivers available +\pause +\item Can probably be included in mainline kernel +\pause +\begin{block}{Standard devices should not be handled by UIO !} +\end{block} +\end{itemize} +\end{frame} + +% ----- Slide "Problematic devices" ------------------- +\begin{frame} +\frametitle{Problematic devices} +\pause +\begin{itemize} +\item Doesn't fit into a standard kernel subsystem +\pause +\item Almost everything is hardware specific +\pause +\item Driver becomes large, no similar example drivers +\pause +\item Driver often invents its own ioctl based API +\pause +\item Will probably not be included in mainline kernel +\pause +\begin{block}{Drivers for such devices are often buggy and hard to maintain !} +\end{block} +\end{itemize} +\end{frame} + +% ----- Slide "In-kernel driver" ------------------ +\begin{frame} +\includegraphics[width=11cm]{images/konventioneller-treiber.png} +\end{frame} + +% ----- Slide "UIO driver" ------------------ +\begin{frame} +\includegraphics[width=11cm]{images/uio-treiber.png} +\end{frame} + +% ----- Slide "How UIO works" -------------------------- +\begin{frame} +\frametitle{How UIO works} +\pause +\begin{itemize} +\item Device memory can be mapped to userspace +\pause +\item All data exchange is done through this memory +\pause +\item All device control is done through this memory +\pause +\item Interrupts are acknowledged in the kernel... +\pause +\item ...and then handled in userspace +\pause +\begin{block}{A small kernel module is still needed} +\end{block} +\end{itemize} +\end{frame} + +% ----- Slide "Kernel: interrupt handler" -------------------------- +\begin{frame}[fragile] +\frametitle{Kernel: interrupt handler} +\begin{verbatim} +irqreturn_t my_handler(int irq, struct uio_info *dev_info) +{ + if (IRQ is not caused by my hardware) + return IRQ_NONE; + + /* Disable interrupt */ + (Perform some register access to silence the IRQ line) + + return IRQ_HANDLED; +} +\end{verbatim} +\end{frame} + +% ----- Slide "Kernel: probe() function" -------------------------- +\begin{frame}[fragile] +\frametitle{Kernel: probe() function} +\begin{verbatim} +int pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + ... + allocate and fill struct uio_info + ... + call uio_register_device() +} +\end{verbatim} +\end{frame} + +% ----- Slide "Kernel: struct uio_info" -------------------------- +\begin{frame}[fragile] +\frametitle{Kernel: struct uio\_info} +\begin{verbatim} +struct uio_info { + struct uio_device *uio_dev; + char *name; + char *version; + struct uio_mem mem[MAX_UIO_MAPS]; + long irq; + unsigned long irq_flags; + void *priv; + irqreturn_t (*handler)(int irq, struct uio_info *dev_info); + int (*mmap)(struct uio_info *info, struct vm_area_struct *vma); + int (*open)(struct uio_info *info, struct inode *inode); + int (*release)(struct uio_info *info, struct inode *inode); +}; +\end{verbatim} +\end{frame} + +% ----- Slide "Kernel: struct uio_mem" -------------------------- +\begin{frame}[fragile] +\frametitle{Kernel: struct uio\_mem} +\begin{verbatim} +struct uio_mem { + unsigned long addr; + unsigned long size; + int memtype; + void __iomem *internal_addr; + struct uio_map *map; +}; +\end{verbatim} +\end{frame} + +% ----- Slide "Userspace part of driver" -------------- +\begin{frame} +\frametitle{Userspace: Overview} +\pause +\begin{itemize} +\item Find device in sysfs (/sys/class/uio/...) +\pause +\item Get device information from sysfs +\pause +\item Open /dev/uioX +\pause +\item Use mmap() to get a pointer to the devices's memory +\pause +\item Initialize device, enable interrupt generation +\pause +\item Perform a blocking read() to wait for interrupts +\end{itemize} +\end{frame} + +% ----- Slide "Hello UIO world" -------------- +\begin{frame}[fragile] +\frametitle{Hello UIO world} +\pause +\begin{verbatim} +int32_t irq_cnt; +int fd = open("/dev/uio0", O_RDWR); +u16 *mem = mmap(..., n*getpagesize()); +mem[...] = ... +while (read(fd, &irq_cnt, 4)) { + printf("irq count = %d\n", irq_cnt); +} +\end{verbatim} +\end{frame} + +% ----- Slide "Performance considerations" -------------- +\begin{frame} +\frametitle{Performance considerations} +\pause +\begin{itemize} +\item Interrupt latency +\pause +\item Memory/register access +\end{itemize} +\end{frame} + +% ----- Slide "ioctl vs. UIO" ------------------ +\begin{frame} +\includegraphics[width=10cm]{images/ioctl-vs-uio.png} +\end{frame} + +% ----- Slide "Publish your driver!" -------------- +\begin{frame} +\frametitle{Publish your driver!} +\pause +\begin{itemize} +\item Get rid of maintenance work! +\pause +\item Send your patch to the UIO maintainers +\pause +\item Cc: linux-kernel@vger.kernel.org +\pause +\item Publish your userspace code, if possible +\pause +\item Make it LGPL, if possible +\pause +\item An open driver helps selling your hardware! +\end{itemize} +\end{frame} + +% ----- Slide "Greg: Support all hardware on earth" --- +\begin{frame} +\includegraphics[width=11cm]{images/greg-all-hardware.jpg} +\end{frame} + +% ----- Slide "Greg: All drivers in kernel.org tree" -- +\begin{frame} +\includegraphics[width=11cm]{images/greg-kernel-org.jpg} +\end{frame} + +% ----- Slide "Legal issues" -------------------------- +\begin{frame} +\frametitle{Legal issues} +\pause +\begin{itemize} +\item Userspace code can be under any licence +\pause +\item Kernel module MUST be GPL +\pause +\item Avoid trickery and gray areas +\end{itemize} +\end{frame} + +% ----- Slide "Tools" -------------------------- +\begin{frame} +\frametitle{Tools} +\pause +\begin{itemize} +\item lsuio +\pause +\item TODO: libuio (nearly ready) +\end{itemize} +\end{frame} + +% ----- Slide "OSADL" -------------------------- +\begin{frame} +\frametitle{OSADL} +\pause +\begin{itemize} +\item Open Source Automation Development Lab +\pause +\item http://www.osadl.org +\pause +\item Hosts some UIO code +\end{itemize} +\end{frame} + +% ----- Slide "Future" -------------------------- +\begin{frame} +\frametitle{Future} +\pause +\begin{itemize} +\item DMA support +\pause +\item get UIO tools and libuio into Linux Distributions +\end{itemize} +\end{frame} + +% ----- Slide "Thanks for listening!" ---------- +\begin{frame} +\frametitle{Thanks for listening!} +\pause +\begin{itemize} +\item Questions ? +\end{itemize} +\end{frame} + +\end{document} |
