\documentclass[addpoints,12pt]{exam} \usepackage{ngerman} \usepackage{listings,color} \usepackage{graphicx} \usepackage[T1]{fontenc} \firstpageheadrule \runningheadrule \lhead{Manuel Traut\\Sommersemester 2020} \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{20. Juli 2020 16:00 Uhr} \maketitle \begin{center} Hochschule Ravensburg-Weingarten \vspace{1cm} Raum: H062 Sektor 1 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[3] Was ist eine Linuxdistribution, was der Linuxkernel? Wie stehen Sie in Relation? \question[3] Was versteht man unter dem Begriff 'Kernelpatch'? Wie wird ein Patch erstellt und angewendet? \question[4] Erkl\"aren Sie an einem Beispiel die Aufgaben eines Linux Kernel Maintainers. \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 \begin{parts} \part[1] Welches Tool ist auf folgendem Bild zu sehen? \part[1] \"Uber welche Datei wird der Inhalt / Struktur des Tools gesteuert? \part[2] Warum ist es notwendig, dass der Kernel konfigurierbar ist? \part[4] Welche Einstellungen k\"onnen mit Hilfe dieses Tools konfiguriert werden? (beschreiben Sie 4 Kategorien) \end{parts} \includegraphics[height=0.3\textwidth]{./images/kconfig.png} \question Linux beinhaltet das Tracingsystem 'ftrace'. \begin{parts} \part[4] Beschreiben/Skizzieren Sie die Architektur und die wichtigsten Funktionen des Systems. \part[4] Beschreiben Sie am Beispiel sched::sched\_switch Event wie Sie das Tracing konfigurieren, starten, auslesen. \end{parts} \question[4] Nennen Sie 4 Gr\"unde die f\"ur oder gegen die Integration eines von Ihnen entwickelten Treibers in Mainline Linux sprechen. \question[4] Kernel- und Userspace arbeiten in unterschiedlichen Addressr\"aumen. Nennen Sie eine M\"oglichkeit, wie Daten zwischen den Bereichen ausgetauscht werden k\"onnen. Nennen Sie typische Verwendung, gegebenenfalls Einschr\"ankungen. \newpage \question Die folgenden Frage bezieht sich auf den Quellcode 1 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} \question Die folgenden Fragen beziehen sich auf den Quellcode 2 im Anhang. \begin{parts} \part[4] 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[8] 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? \end{parts} \end{questions} \vspace{1cm} Punkte: \_\_\_\_ von \numpoints \hspace{1cm} Note: \newpage \begin{appendix} Quellcode 1: \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} \newpage Quellcode 2: \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} \end{appendix} \end{document}