From ebb074d963c85e394f445793eea76423e88af3f6 Mon Sep 17 00:00:00 2001
From: Manuel Traut <manut@linutronix.de>
Date: Tue, 11 Jul 2017 19:10:03 +0200
Subject: add pruefung 2016

Signed-off-by: Manuel Traut <manut@linutronix.de>
---
 2016-pruefung.tex | 540 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 540 insertions(+)
 create mode 100644 2016-pruefung.tex

(limited to '2016-pruefung.tex')

diff --git a/2016-pruefung.tex b/2016-pruefung.tex
new file mode 100644
index 0000000..7e36f89
--- /dev/null
+++ b/2016-pruefung.tex
@@ -0,0 +1,540 @@
+\documentclass[addpoints,12pt]{exam}
+
+\usepackage{ngerman}
+\usepackage{listings,color}
+\usepackage{graphicx}
+
+\firstpageheadrule
+\runningheadrule
+\lhead{Manuel Traut\\Sommersemester 2016}
+\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{04. Juli 2016 10:30 Uhr}
+\maketitle
+\begin{center}
+Hochschule Ravensburg-Weingarten
+\vspace{1cm}
+
+Dauer: 60 Minuten, erlaubte Hilfsmittel: eigene Mitschriebe/Notizen
+\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 Roboter entwickelt. Zur Steuerung des Roboters wurde
+  ein ARM basiertes Linuxsystem integriert. Um die Sensoren und Aktoren des
+  Roboters vom User-space zugreifbar zu machen haben Sie den Linuxkernel
+  modifiziert. Die Steuerungsapplikation l\"auft im Userspace und wurde nur
+  gegen die unter LGPL stehende glibc gelinkt.
+
+\begin{parts}
+\part[2] Argumentieren Sie weshalb es f\"ur zuk\"unftige Entwicklungen am
+  Roboter f\"ur Ihre Firma von Vorteil ist, die \"Anderungen am Kernel
+  "Mainline" zu bekommen.
+
+\part[4] Sie wollen Ihre Modifikationen am Kernel in Mainline Linux
+  integriert haben. Was \"ubermitteln Sie auf welchem Weg wohin?
+
+\part[4] Welche Aufgaben haben die Kernel Maintainer in diesem Zusammenhang?
+
+\part[1] M\"ussen Sie die K\"aufer des Roboters informieren, dass Sie Linux
+  einsetzen?
+
+\part[1] Wem m\"ussen Sie auf Anfrage die Modifikationen am Kernel zur
+  Verf\"ugung stellen?
+
+\part[1] Wem m\"ussen Sie auf Anfrage den Quellcode Ihrer Applikation zur
+  Verf\"ugung stellen?
+\end{parts}
+
+\question F\"ur die Kernelentwicklungen im Rahmen des oben genannten
+	Roboterprojekts wird git als Versionskontrollsystem eingesetzt. Im Produkt
+	soll ein in einem branch (v4.4.y) des "linux-stable" Repository gepflegter
+	LTS (long-term support) Kernel zum Einsatz kommen. F\"ur das Mainlining
+	Ihrer Modifikationen m\"ussen diese gegen den aktuellsten Entwicklungskernel
+	(master branch des "linux" Repositories gebaut und getestet werden.
+\begin{parts}
+\part[2] Wozu dient 'git remote' und wie/wozu wird es hier zweckm\"assig
+	eingesetzt?
+\part[4] Sie arbeiten am Kameratreiber und haben einen Zwischenstand erreicht.
+	Kollege Max koordiniert alle Arbeiten am Kernel. Wie funktioniert die
+	Integration Ihres Treiberstands in das von Max gepflegte "linux-robo"
+	Repository? Skizzieren/Beschreiben Sie welche Repositories/Branches in dem
+	Prozess involviert sind und wem diese geh\"oren.
+\end{parts}
+
+\newpage
+
+\question
+\begin{parts}
+\part[1] Welches Kommando f\"uhrt zu den Ausgaben auf folgendem Bild?
+\part[1] \"Uber welche Dateien wird der Inhalt / Struktur des Tools gesteuert?
+\part[2] Der Kernel kann 'out of tree' gebaut werden. Nenne 2 Vorteile dieser
+	Methode.
+\end{parts}
+
+\includegraphics[height=0.3\textwidth]{./menuconfig.png}
+
+\question Sie haben einen Treiber entwickelt, welcher dem User-space
+	erm\"oglicht einen Ultraschallsensor via sysfs auszulesen. Die
+	Steuerungsapplikation des Roboters nutzt diese Funktion zyklisch (alle 2ms).
+	In einer Testapplikation kann dedektiert werden, dass in seltenen F\"allen
+	(bei einem Dauerlauf, ca. 2 mal t\"aglich) Ihr Treiber einen Wert liefert,
+	der im Rahmen des Testaufbaus v\"ollig unrealistisch ist. Sie vermuten, dass
+	es sich um eine Race-condition (Wert wird von Ihrem Treiber
+	geschrieben, w\"ahrend er vom User-space gelesen wird.) handelt.
+\begin{parts}
+	\part[10] Wie gehen Sie vor um zu pr\"ufen ob Ihre Vermutung wahr ist?
+		Welche Tools / Infrastruktur setzen Sie wie ein? M\"ussen Sie die User-space
+		Testapplikation modifizeren? Falls ja wie? M\"ussen Sie den Kernel
+		modifizieren? Falls ja wie?
+\end{parts}
+
+\question
+F\"ur Ihren Roboter ben\"otigen Sie ein Rootfilesystem welches einen Webserver
+sowie die user-space Tools zur WLAN Konfiguration enth\"alt.
+\begin{parts}
+	\part[2] Nennen Sie 2 Punkte die Sie beim Erstellen des Rootfilesystem mit
+		'Linux from scratch Ansatu' (also ohne Distribution) selber erledigen
+		m\"u\ss en, welche aber klassischerweise von einer bin\"aren
+		Linuxdistribution wie z.B. Debian gel\"ost w\"aren.
+\end{parts}
+
+\newpage
+
+\question
+Die folgenden Fragen beziehen sich auf den Quellcode 1 im Anhang.
+\begin{parts}
+\part[4] Welche Funktionalit\"at stellt der Code zur Verf\"ugung?
+\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[2] Sie wollen dass der Code nicht mehr angesprungen wird, welche Zeile(n)
+	m\"ussen Sie mindestens l\"oschen?
+\part[3] Die Interruptfunktion wird nicht mehr ben\"otigt, welche Zeilen
+	k\"onnen gel\"oscht werden?
+\end{parts}
+
+\question
+Die folgenden Fragen beziehen sich auf den Quellcode 2 im Anhang.
+\begin{parts}
+\part[10] Mittels 'set\_latch\_u7 / get\_latch\_u7' kann analog zu
+	'set\_latch\_u5 / get\_latch\_u5' eine gr\"une LED vom Kernel aus
+	geschalten werden. Erweitern Sie den Treiber so, dass die gr\"une LED
+	via 'echo 1 > /sys/class/leds/huhu/brightness' dauerhaft eingeschalten 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
+#define PCI_SUBVENDOR_ID_HUMUSOFT	0x186c
+#define PCI_SUBDEVICE_DEVICE		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:
+		iowrite32(ioread32(INTCSR_reg)
+			& ~(INTCSR_CTR4INT_ENABLE | INTCSR_PCIINT_ENABLE),
+			INTCSR_reg);
+		break;
+
+	case ALL:
+	default:
+		iowrite32(ioread32(INTCSR_reg)
+			& ~(INTCSR_ADINT_ENABLE | INTCSR_CTR4INT_ENABLE
+			    | INTCSR_PCIINT_ENABLE),
+			INTCSR_reg);
+		break;
+	}
+}
+
+static void mf624_enable_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:
+		iowrite32(ioread32(INTCSR_reg)
+			| INTCSR_CTR4INT_ENABLE | INTCSR_PCIINT_ENABLE,
+			INTCSR_reg);
+		break;
+
+	case ALL:
+	default:
+		iowrite32(ioread32(INTCSR_reg)
+			| INTCSR_ADINT_ENABLE | 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 int mf624_irqcontrol(struct uio_info *info, s32 irq_on)
+{
+	if (irq_on == 0)
+		mf624_disable_interrupt(ALL, info);
+	else if (irq_on == 1)
+		mf624_enable_interrupt(ALL, info);
+
+	return 0;
+}
+
+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;
+
+	/* Note: Datasheet says device uses BAR0, BAR1, BAR2 -- do not trust it */
+
+	/* 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;
+
+	/* BAR4 */
+	info->mem[2].name = "Counter/timer chip";
+	info->mem[2].addr = pci_resource_start(dev, 4);
+	if (!info->mem[2].addr)
+		goto out_unmap1;
+	info->mem[2].size = pci_resource_len(dev, 4);
+	info->mem[2].memtype = UIO_MEM_PHYS;
+	info->mem[2].internal_addr = pci_ioremap_bar(dev, 4);
+	if (!info->mem[2].internal_addr)
+		goto out_unmap1;
+
+	info->irq = dev->irq;
+	info->irq_flags = IRQF_SHARED;
+	info->handler = mf624_irq_handler;
+
+	info->irqcontrol = mf624_irqcontrol;
+
+	if (uio_register_device(&dev->dev, info))
+		goto out_unmap2;
+
+	pci_set_drvdata(dev, info);
+
+	return 0;
+
+out_unmap2:
+	iounmap(info->mem[2].internal_addr);
+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);
+	iounmap(info->mem[2].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}
-- 
cgit v1.2.3

