summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Traut <manut@linutronix.de>2018-07-04 21:57:06 +0200
committerManuel Traut <manut@linutronix.de>2018-07-04 21:57:06 +0200
commit900c12d856bffc4769384f2fea0d33183a84917e (patch)
tree3ac3066106ce70a00da73f319516007539eb7f4f
parent7f0f89470dfd319b48fd6523a8daa15468130203 (diff)
added pruefung 2018
Signed-off-by: Manuel Traut <manut@linutronix.de>
-rw-r--r--2018-pruefung.tex458
1 files changed, 458 insertions, 0 deletions
diff --git a/2018-pruefung.tex b/2018-pruefung.tex
new file mode 100644
index 0000000..bd06f5c
--- /dev/null
+++ b/2018-pruefung.tex
@@ -0,0 +1,458 @@
+\documentclass[addpoints,12pt]{exam}
+
+\usepackage{ngerman}
+\usepackage{listings,color}
+\usepackage{graphicx}
+\usepackage[T1]{fontenc}
+
+\firstpageheadrule
+\runningheadrule
+\lhead{Manuel Traut\\Sommersemester 2018}
+\chead{Hochschule Ravensburg-Weingarten\\Linux-Kernelprogrammierung}
+\rhead{MatrNr:\\Datum:}
+
+\firstpagefootrule
+\runningfootrule
+\firstpagefooter{Page \thepage\ of \numpages}
+{}
+{Punkte: \makebox[.5in]{\hrulefill}\\
+von \pointsonpage{\thepage} Punkten}
+
+\runningfooter{Page \thepage\ of \numpages}
+{}
+{}
+
+\pagestyle{headandfoot}
+
+\pointsinrightmargin
+\pointpoints{Punkt}{Punkte}
+
+\begin{document}
+
+
+\begin{coverpages}
+\begin{titlepage}
+\title{Pr\"ufung Linux-Kernelprogrammierung}
+\author{Dozent: Manuel Traut}
+\date{10. Juli 2018 10:30 Uhr}
+\maketitle
+\begin{center}
+Hochschule Ravensburg-Weingarten
+\vspace{1cm}
+
+Raum: H142
+
+Dauer: 60 Minuten, erlaubte Hilfsmittel: alle
+\end{center}
+
+\vspace{2cm}
+Name:\enspace\hrulefill
+\vspace{2cm}
+MatrNr:\enspace\hrulefill
+\begin{center}
+\begin{lstlisting}
+ a8888b.
+ d888888b.
+ 8P"YP"Y88 (((((((())))))))))
+ 8|o||o|88 ||VIEL ERFOLG !!||
+ 8' .88 ((((((((((((()))))
+ 8`._.' Y8.
+ d/ `8b.
+ .dP . Y8b.
+ d8:' " `::88b.
+ d8" `Y88b
+ :8P ' :888
+ 8a. : _a88P
+ ._/"Yaa_ : .| 88P|
+ \ YP" `| 8P `.
+ / \._____.d| .'
+ `--..__)888888P`._.'
+\end{lstlisting}
+\end{center}
+\end{titlepage}
+\end{coverpages}
+
+\lstset{ %
+ basicstyle=\scriptsize, % the size of the fonts that are used for the code
+ breaklines=true, % sets automatic line breaking
+ frame=single, % adds a frame around the code
+ language=C, % the language of the code
+ numbers=left, % where to put the line-numbers;
+ numbersep=5pt, % how far the line-numbers are from the code
+ numberstyle=\tiny, % the style that is used for the line-numbers
+ tabsize=8, % sets default tabsize to 2 spaces
+}
+
+
+\begin{questions}
+
+\question Sie haben einen IoT Toaster entwickelt. Um die Sensoren (Temperatur,
+ Luftfeuchtigkeit, Strommesser, Spannungsmesser, Lagemesser, sowie zwei
+ Wegsensoren) und Aktoren (je eine PWM für Heizspirale und die zwei Motoren)
+ des Toasters vom User-space zugreifbar zu machen haben Sie den Linuxkernel
+ um entsprechende Treiber erweitert. Die Toasterapplikation im Userspace
+ liest die Sensordaten aus und übermittelt Sie über ein Netzwerkinterface
+ und WLAN Kerneltreiber in eine Cloudapplikation. Ausserdem ermöglicht die
+ Toasterapplikation, dass in der Cloud definierte Toastprogramme (z.B.
+ auftauen, bräunen, Holzkohle) die PWMs via Userspaceinterface programmieren.
+ Die Toasterapplikation ist in JAVA geschrieben und verwendet ausschliesslich
+ JAVA Module welche unter MIT oder LGPL Lizenz stehen.
+
+\begin{parts}
+
+\part[4] Argumentieren Sie weshalb es f\"ur zuk\"unftige Entwicklungen am
+ Toaster f\"ur Ihre Firma von Vorteil ist, die neu entwickelten Kerneltreiber
+ in den 'mainline Kernel' zu integrieren.
+
+\part[6] Sie wollen Ihre Treiber welche Sie gegen Kernelversion 4.5 entwickelt
+ haben in Mainline Linux integriert haben. Wie gehen Sie vor?
+
+\part[2] Welche Aufgaben haben die Kernel Maintainer in diesem Zusammenhang?
+
+\part[12] Für die Temperatursensoren können Sie die Funktionen des 'thermal
+ Subsystems' nutzen. Für den Luftfeuchtigkeitssensor gibt es kein passendes
+ Subsystem. Der Sensor befindet sich auf einer PCI Karte, der Sensorwert
+ (uint\_8) kann ohne Umrechnung von Memoryoffset 0x100 von PCI Bar 2 im Kernel
+ gelesen werden.
+
+ Verwenden Sie zur Beantwortung der folgenden Punkte Pseudocode oder
+ beschreiben Sie textuell:
+
+ \begin{enumerate}
+ \item Was tut Ihre init Funktion?
+ \item Was implementieren Sie in der probe Funktion?
+ \item Wie ermöglichen Sie den Zugriff auf den Messwert vom Userspace aus?
+ \item Beschreiben Sie wie Sie den Wert in der Toasterapplikation auslesen.
+ \end{enumerate}
+
+
+\part[1] M\"ussen Sie die K\"aufer des Toasters informieren, dass Sie Linux
+ einsetzen?
+
+\part[1] M\"ussen Sie auf Anfrage eines Käufers die verwendeten Kernelsourcen
+ zur Verf\"ugung stellen?
+
+\part[1] Wem m\"ussen Sie auf Anfrage den Quellcode der Toasterapplikation zur
+ Verf\"ugung stellen?
+\end{parts}
+
+\question [6] Beschreiben Sie stichwortartig den Releasezyklus des Linuxkernels.
+Erkl\"aren Sie in diesem Zusammenhang auch die Begriffe 'Release Candidate',
+'Release', 'stable Kernel' und 'staging'.
+
+\question [6] Ein von Ihnen entwickelter Kerneltreiber funktioniert nicht wie
+erwartet. Welche Debugingm\"oglichkeiten haben Sie?
+
+Nennen Sie zwei Möglichkeiten und beschreiben Sie Vor- und Nachteile
+
+\newpage
+
+\question Im Linux Source gibt es einen Ordner 'staging'.
+\begin{parts}
+\part[1] Was findet man in diesem Ordner?
+\part[2] Wann wird der Code aus diesem Ordner gel\"oscht / verschoben?
+\end{parts}
+
+\question
+
+\question
+Die folgenden Fragen beziehen sich auf den Quellcode 1 im Anhang.
+\begin{parts}
+\part[2] Der Treiber wird in einem System geladen, welches 2 PCI Devices mit
+ Vendor ID 0x186c und Device ID 0x0624 besitzt. Wie oft wird mf624\_pci\_probe
+ und mf624\_init aufgerufen?
+\part[4] Egal auf welches Device Sie zugreifen, Sie interagieren immer nur mit
+ einer der zwei PCI Karten. Wie m\"usssen Sie den Treiber modifizieren, damit
+ beide Karten funktionieren?
+\part[6] Suchen Sie sich drei Codezeilen aus, erkl\"aren Sie jeweils in welchem
+ Zusammenhang die Codezeile ausgeführt wird und was diese bewirkt.
+\end{parts}
+
+\question
+Die folgenden Frage bezieht sich auf den Quellcode 2 im Anhang.
+\begin{parts}
+\part[10] Mit den Funktionen 'set\_latch\_green und get\_latch\_green' (welche
+in asm/mach-rc32434/gpio.h definiert sind) kann analog zu den bereits verwendeten
+Funktionen 'set\_latch\_u5 / get\_latch\_u5' eine gr\"une LED angesteuert
+werden. Erweitern Sie den Treiber so, dass die gr\"une LED z.B. mit
+ 'echo 1 > /sys/class/leds/huhu/brightness'
+eingeschaltet werden kann.
+\end{parts}
+
+\end{questions}
+
+\vspace{1cm}
+Punkte: \_\_\_\_ von \numpoints
+\hspace{1cm}
+Note:
+
+\newpage
+
+\begin{appendix}
+
+Quellcode 1:
+
+\begin{lstlisting}
+/*
+ * UIO driver fo Humusoft MF624 DAQ card.
+ * Copyright (C) 2011 Rostislav Lisovy <lisovy@gmail.com>,
+ * Czech Technical University in Prague
+ *
+ * Copyright (C) 2016 Manuel Traut <manut@mecka.net>,
+ * modified for usage in kernel exams
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/uio_driver.h>
+
+#define PCI_VENDOR_ID_HUMUSOFT 0x186c
+#define PCI_DEVICE_ID_MF624 0x0624
+
+/* BAR0 Interrupt control/status register */
+#define INTCSR 0x4C
+#define INTCSR_ADINT_ENABLE (1 << 0)
+#define INTCSR_CTR4INT_ENABLE (1 << 3)
+#define INTCSR_PCIINT_ENABLE (1 << 6)
+#define INTCSR_ADINT_STATUS (1 << 2)
+#define INTCSR_CTR4INT_STATUS (1 << 5)
+
+enum mf624_interrupt_source {ADC, CTR4, ALL};
+
+static void mf624_disable_interrupt(enum mf624_interrupt_source source,
+ struct uio_info *info)
+{
+ void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
+
+ switch (source) {
+ case ADC:
+ iowrite32(ioread32(INTCSR_reg)
+ & ~(INTCSR_ADINT_ENABLE | INTCSR_PCIINT_ENABLE),
+ INTCSR_reg);
+ break;
+ case CTR4:
+ default:
+ iowrite32(ioread32(INTCSR_reg)
+ & ~(INTCSR_CTR4INT_ENABLE | INTCSR_PCIINT_ENABLE),
+ INTCSR_reg);
+ break;
+ }
+}
+
+static irqreturn_t mf624_irq_handler(int irq, struct uio_info *info)
+{
+ void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
+
+ if ((ioread32(INTCSR_reg) & INTCSR_ADINT_ENABLE)
+ && (ioread32(INTCSR_reg) & INTCSR_ADINT_STATUS)) {
+ mf624_disable_interrupt(ADC, info);
+ return IRQ_HANDLED;
+ }
+
+ if ((ioread32(INTCSR_reg) & INTCSR_CTR4INT_ENABLE)
+ && (ioread32(INTCSR_reg) & INTCSR_CTR4INT_STATUS)) {
+ mf624_disable_interrupt(CTR4, info);
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
+static struct uio_info mf624_info = {
+ .name = "mf624";
+ .version = "0.0.1";
+};
+
+static int mf624_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ struct uio_info *info = &mf624_info;
+
+ if (pci_enable_device(dev))
+ return -1;
+
+ if (pci_request_regions(dev, "mf624"))
+ goto out_disable;
+
+ /* BAR0 */
+ info->mem[0].name = "PCI chipset, interrupts, status "
+ "bits, special functions";
+ info->mem[0].addr = pci_resource_start(dev, 0);
+ if (!info->mem[0].addr)
+ goto out_release;
+ info->mem[0].size = pci_resource_len(dev, 0);
+ info->mem[0].memtype = UIO_MEM_PHYS;
+ info->mem[0].internal_addr = pci_ioremap_bar(dev, 0);
+ if (!info->mem[0].internal_addr)
+ goto out_release;
+
+ /* BAR2 */
+ info->mem[1].name = "ADC, DAC, DIO";
+ info->mem[1].addr = pci_resource_start(dev, 2);
+ if (!info->mem[1].addr)
+ goto out_unmap0;
+ info->mem[1].size = pci_resource_len(dev, 2);
+ info->mem[1].memtype = UIO_MEM_PHYS;
+ info->mem[1].internal_addr = pci_ioremap_bar(dev, 2);
+ if (!info->mem[1].internal_addr)
+ goto out_unmap0;
+
+ info->irq = dev->irq;
+ info->irq_flags = IRQF_SHARED;
+ info->handler = mf624_irq_handler;
+
+ if (uio_register_device(&dev->dev, info))
+ goto out_unmap1;
+
+ pci_set_drvdata(dev, info);
+ return 0;
+
+out_unmap1:
+ iounmap(info->mem[1].internal_addr);
+out_unmap0:
+ iounmap(info->mem[0].internal_addr);
+
+out_release:
+ pci_release_regions(dev);
+
+out_disable:
+ pci_disable_device(dev);
+
+ return -ENODEV;
+}
+
+static void mf624_pci_remove(struct pci_dev *dev)
+{
+ struct uio_info *info = pci_get_drvdata(dev);
+
+ mf624_disable_interrupt(ALL, info);
+
+ uio_unregister_device(info);
+ pci_release_regions(dev);
+ pci_disable_device(dev);
+
+ iounmap(info->mem[0].internal_addr);
+ iounmap(info->mem[1].internal_addr);
+
+ kfree(info);
+}
+
+static const struct pci_device_id mf624_pci_id[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_HUMUSOFT, PCI_DEVICE_ID_MF624) },
+ { 0, }
+};
+
+static struct pci_driver mf624_pci_driver = {
+ .name = "mf624",
+ .id_table = mf624_pci_id,
+ .probe = mf624_pci_probe,
+ .remove = mf624_pci_remove,
+};
+MODULE_DEVICE_TABLE(pci, mf624_pci_id);
+
+int mf624_init(void)
+{
+ return pci_driver_register(&mf624_pci_driver);
+}
+
+void mf624_exit(void)
+{
+ pci_driver_unregister(&mf624_pci_driver);
+}
+
+module_init(mf624_init);
+module_exit(mf624_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Rostislav Lisovy <lisovy@gmail.com>");
+\end{lstlisting}
+
+\newpage
+
+Quellcode 2:
+
+\begin{lstlisting}
+/*
+ * LEDs driver for the "User LED" on Routerboard532
+ *
+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
+ *
+ * Based on leds-cobalt-qube.c by Florian Fainelly and
+ * rb-diag.c (my own standalone driver for both LED and
+ * button of Routerboard532).
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+static void rb532_led_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ if (brightness)
+ set_latch_u5(LO_ULED, 0);
+
+ else
+ set_latch_u5(0, LO_ULED);
+}
+
+static enum led_brightness rb532_led_get(struct led_classdev *cdev)
+{
+ return (get_latch_u5() & LO_ULED) ? LED_FULL : LED_OFF;
+}
+
+static struct led_classdev rb532_uled = {
+ .name = "uled",
+ .brightness_set = rb532_led_set,
+ .brightness_get = rb532_led_get,
+ .default_trigger = "nand-disk",
+};
+
+static int rb532_led_probe(struct platform_device *pdev)
+{
+ return led_classdev_register(&pdev->dev, &rb532_uled);
+}
+
+static int rb532_led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&rb532_uled);
+ return 0;
+}
+
+static struct platform_driver rb532_led_driver = {
+ .probe = rb532_led_probe,
+ .remove = rb532_led_remove,
+ .driver = {
+ .name = "rb532-led",
+ },
+};
+
+module_platform_driver(rb532_led_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("User LED support for Routerboard532");
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
+MODULE_ALIAS("platform:rb532-led");
+\end{lstlisting}
+\end{appendix}
+\end{document}