\documentclass[addpoints,12pt]{exam} \usepackage{ngerman} \usepackage{listings,color} \usepackage{graphicx} \firstpageheadrule \runningheadrule \lhead{Manuel Traut\\Sommersemester 2017} \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{12. Juli 2017 08:00 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 \begin{parts} \part[2] Welches Kommando f\"uhrt zu den Ausgaben auf folgendem Bild? \part[2] \"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[width=0.8\textwidth]{./menuconfig.png} \question \begin{parts} \part[6]Beschreiben Sie den Releasezyklus des Linuxkernels. Erkl\"aren Sie in diesem Zusammenhang auch die Begriffe 'Release Candidate', 'Release', 'stable Kernel' und 'staging'. \end{parts} \question \begin{parts} \part[6]Das Linuxtreibermodell kennt verschiedene Treiberarten. Worin unterscheidet sich der Code zur Registrierung eines 'usb\_device\_driver' von einem 'pci\_device\_driver'? \end{parts} \question \begin{parts} \part[6]Was wissen Sie über die Tracing Infrastruktur (ftrace) im Linux Kernel? (Nennen Sie 3 Punkte) \end{parts} \newpage \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[2] Sie wollen dass der Code nicht mehr angesprungen wird, welche Zeile(n) m\"ussen Sie mindestens l\"oschen? \end{parts} \question Die folgenden Fragen beziehen 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 , * Czech Technical University in Prague * * Copyright (C) 2016 Manuel Traut , * 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 #include #include #include #include #include #include #include #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 "); \end{lstlisting} \newpage Quellcode 2: \begin{lstlisting} /* * LEDs driver for the "User LED" on Routerboard532 * * Copyright (C) 2009 Phil Sutter * * 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 #include #include #include #include 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 "); MODULE_ALIAS("platform:rb532-led"); \end{lstlisting} \end{appendix} \end{document}