You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

416 lines
15 KiB

% Copyright (C) 2018 TANSORIER.
% Permission is granted to copy, distribute and/or modify this document
% under the terms of the GNU Free Documentation License, Version 1.3
% or any later version published by the Free Software Foundation;
% with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
% A copy of the license is included in the section entitled "GNU
% Free Documentation License".
% https://www.gnu.org/licenses/fdl-1.3.html
% compress option to have horyzontal circle
\documentclass[compress,aspectratio=169]{beamer}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Thèmes suppélmentaires
\useoutertheme[]{miniframes} % barre menu du haut
\setbeamertemplate{frametitle}[default] % replace le titre à la bonne place
\useinnertheme[shadow=true]{rounded} % arrondi les angles
\usecolortheme{orchid}
\usecolortheme{whale}
%\usepackage{xcolor}
%\definecolor{smileOrange}{RGB}{254,128,86}
\setbeamertemplate{footline}[text line]{
\textcolor{gray}{%
\parbox{\linewidth}{\vspace*{-8pt}Smile\hfill\insertshortauthor\hfill\insertpagenumber/\inserttotalframenumber}}
}
\beamertemplatenavigationsymbolsempty
% Language
\usepackage[french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc}
% Display Table Of Content spécific for smilebeamer
% Force to get empty
\AtBeginSection[]{}
\AtBeginSubsection[]{}
%{
% \begin{frame}<beamer>
% \frametitle{Plan}
% \tableofcontents[currentsection]
% \end{frame}
%}
% Change color of definiton block
\AtBeginEnvironment{definition}{%
\setbeamercolor{block title}{use=example text,fg=example text.fg,bg=example text.fg!20!bg}
\setbeamercolor{block body}{parent=normal text,use=block title,bg=block title.bg!50!bg}
}
% code coloration
\usepackage{listings}
% L'option "[fragile]" doit être rajouté au frame pour pouvoir utiliser correctement
% la police verbatim
\usepackage{color}
\lstset{
breaklines=true,
tabsize=4,
backgroundcolor=\color[RGB]{49,54,59},
basicstyle=\footnotesize\ttfamily\color{white},
commentstyle=\itshape\color[RGB]{0,136,136},
morecomment=[l]{\#},
morekeywords={*,\$,\{,\}},
stringstyle=\itshape\color[RGB]{218,116,0},
showstringspaces=false,
frame=LTBR,
}
\lstdefinestyle{shell}{
language=bash,
keywords={\$},
keywordstyle=\bfseries\color[RGB]{66,198,66}
}
\lstdefinelanguage{diff}{
morecomment=[f][\color{blue}]{@@}, % group identifier
morecomment=[f][\color{red}]-, % deleted lines
morecomment=[f][\color{green}]+, % added lines
morecomment=[f][\color{magenta}]{---}, % Diff header lines (must appear after +,-)
morecomment=[f][\color{magenta}]{+++},
}
% Pour utiliser des colonnes
\usepackage{multicol}
% Pour integrer un pdf
\usepackage[final]{pdfpages}
% Pour les hyperliens
\usepackage{hyperref}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\title[U-Boot]{UDEV \\ \textbf{Gérerer les device node}}
\author[Mickaël Tansorier]{Mickaël Tansorier}
\date[Août 2018]{Présentation du fonctionnement d'UDEV.}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
%\tableofcontents[subsectionstyle=hide]
% *******************************
% **** PAGE DE GARDE ****
% *******************************
\begin{frame}
\titlepage
\end{frame}
% *******************************
% **** INTRODUCTION ****
% *******************************
\begin{frame}{Plan}
\tableofcontents[hideallsubsections]
\end{frame}
\section{Introduction}
\subsection{device-node}
\begin{frame}
\texttt{UDEV} est un démon chargé de gérer les device-nodes.
\begin{block}{Principe d'unix}
Tout est fichier
\end{block}
Donc les périphériques matériels sont des pseudo-fichier.\newline
Ils peuvent être manipulés par: cat, grep, open(), read(), write() etc…\newline
\newline
Ils sont stockés dans: \texttt{/dev} \newline
On les appelle device-nodes.
\end{frame}
\begin{frame}
\begin{list}{-}{Les device nodes sont:}
\item des points d'entrée vers le noyau
\item de type bloc ou char
\item identifiés par un majeur et un mineur
\end{list}
$ $\newline
Le majeur permet au noyau de savoir quel driver doit gérer le périphérique.\newline
Le mineur permet au driver de savoir quel périphérique parmi ceux quil gère est utilisé.
\end{frame}
\subsection{Historique}
\begin{frame}{}
\begin{itemize}
\item Le script \texttt{MAKEDEV}
\begin{itemize}
\item[-] Les majeur et mineur était codés en dur dans un script appelé par la commande mknode.
\item[-] Pour créer les périphériques dans \texttt{/dev}.
\item[-] Tout ceux possible existaient sur le système (\texttt{\~} 18 000)
\item[-] Ne gère pas le hotplug
\end{itemize}
\item Le \texttt{devfs}
\begin{itemize}
\item[-] Les noeuds ne sont plus crées par le système mais par les drivers eux-mêmes à la détection d'un périphérique.
\item[-] Mais les majeurs mineurs étaient toujours codé en dur
\item[-] devfs est difficile à paramétrer
\end{itemize}
\item Le \texttt{udev}
\begin{itemize}
\item[-] udev est un programme purement user-space
\item[-] udev évolue en s'appuyant sur les évolutions du noyau
\item[-] Il sappuie sur les informations laissées dans \texttt{/sys} (majeur et mineur)
\item[-] Le noyau fournit un lien netlink qui permet à udev d'être prévenu lors d'un changement.
\end{itemize}
\end{itemize}
\end{frame}
% *******************************
% **** PRÉSENTATION ****
% *******************************
\section{Les événements noyau}
\subsection{monitor}
\begin{frame}[fragile]
\texttt{udev} réagit donc à des événements envoyés par le noyau via \texttt{inotify}.
\begin{lstlisting}[style=shell]
udevadm monitor -k
\end{lstlisting}
Lorsque l'on branche un USB:
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
KERNEL[805.692293] add /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1 (usb)
KERNEL[805.694999] add /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0 (usb)
KERNEL[806.006810] add /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0/net/eth1 (net)
KERNEL[806.006948] add /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0/net/eth1/queues/rx-0 (queues)
KERNEL[806.007010] add /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0/net/eth1/queues/tx-0 (queues)
\end{lstlisting}
Et si l'on retire:
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
KERNEL[800.026043] remove /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0/net/eth1/queues/rx-0 (queues)
KERNEL[800.026228] remove /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0/net/eth1/queues/tx-0 (queues)
KERNEL[800.026366] remove /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0/net/eth1 (net)
KERNEL[800.050534] remove /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0 (usb)
KERNEL[800.080535] remove /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1 (usb)
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
On peut demander à \texttt{udev} de nous fournir les propriétés du périphérique:
\begin{lstlisting}[basicstyle=\tiny\ttfamily\color{white}]
udevadm monitor -k -p
\end{lstlisting}
Pour une seule sortie:
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
KERNEL[5763.052898] add /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1 (usb)
ACTION=add
BUSNUM=001
DEVNAME=/dev/bus/usb/001/003
DEVNUM=003
DEVPATH=/devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1
DEVTYPE=usb_device
MAJOR=189
MINOR=2
PRODUCT=bda/8153/3000
SEQNUM=1544
SUBSYSTEM=usb
TYPE=0/0/0
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
Les propriétés dépendent du type exact de périphérique mais certaines propriétés sont toujours présentes:
\begin{itemize}
\item \texttt{ACTION} : Le type dévénement à traiter,
\item \texttt{MAJOR}, \texttt{MINOR} : Les numéro majeur et mineur du périphérique concerné,
\item \texttt{SEQNUM} : un numéro croissant pour ordonner les événements,
\item \texttt{SUBSYSTEM} : Le sous-système noyau ayant causé lévénement,
\item \texttt{DEVPATH} : Le fichier dans \texttt{/sys} correspondant au périphérique.
\end{itemize}
\end{frame}
% *******************************
% **** PRÉSENTATION ****
% *******************************
\section{Les règles udev}
\begin{frame}[fragile]{Lécriture de règles}
Les règles udev peuvent venir de plusieurs endroits différents:
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
/etc/udev/rules.d/ # regles locales ajoutees par l'administrateur
/run/udev/rules.d/ # regles volatiles, generalement creees par d'autres regles
/usr/lib/udev/rules.d/ # regles fourni par la distribution
/lib/udev/rules.d/ # regles fourni par la distribution
\end{lstlisting}
Les fichiers sont préfixé par un numéro (comme init), et postfixé par \texttt{.rules}.\newline
Exemple: \texttt{/usr/lib/udev/rules.d/82-net-usb-up.rules}
\begin{lstlisting}[style=shell]
ACTION=="add", RUN+="/bin/sh -c '/bin/echo %k : %p >> /root/events'"
\end{lstlisting}
\end{frame}
\subsection{Les règles de filtrage}
\begin{frame}[fragile]
Pour filtrer les évènements on utilise la syntaxe: \texttt{PROPRIETE==valeur} \newline
"\texttt{==}", "\texttt{!=}", "\texttt{=}", "\texttt{+=}", "\texttt{-=}", "\texttt{:=}"
\newline
\newline
Le champs \texttt{PROPRIETE} peut prendre les valeurs suivantes:
\begin{itemize}
\item \texttt{ATTR\{fichier\}} — permet de filtrer sur le contenu dun fichier dans le répertoire sysfs correspondant à lévénement en cours.
\item \texttt{ATTRS\{fichier\}} — idem + également sur ceux des périphériques parents (bus, plateforme etc…).
\item \texttt{ENV\{clé\}} — permet de filtrer sur une propriété ajoutée par une autre règle udev.
\item \texttt{PROGRAM} — permet de filtrer sur la valeur de retour dun programme.
\end{itemize}
\end{frame}
\subsection{Les actions possibles}
\begin{frame}[fragile]
Lorsque l'on a le filtrage que l'on souhaite, on peut effectuer des actions avec les options suivantes:
\begin{itemize}
\item \texttt{SYMLINK} — crée un lien symbolique vers le fichier \texttt{/dev} du pérphérique. Le noyau fournit un premier fichier \texttt{/dev} dont le nom ne peut pas être changé.
\item \texttt{OWNER}, \texttt{GROUP}, \texttt{MODE}, \texttt{SECLABEL\{module\}} — permet de préciser les droits daccès et les propriétés SELinux du périphérique.
\item \texttt{ATTR\{fichier\}} — permet décrire une valeur dans un fichier du répertoire sysfs correspondant au périphérique.
\item \texttt{ENV\{clé\}} — permet de positionner un attribut interne à udev pour le périphérique en cours,
\item \texttt{RUN} — permet dexécuter un programme
\end{itemize}
\end{frame}
\begin{frame}[fragile]
Certain mots clés peuvent être utilisés pour ces actions, comme:
\begin{itemize}
\item \texttt{\$kernel}, \texttt{\%k} — The kernel name for this device.
\item \texttt{\$devpath}, \texttt{\%p} — The devpath of the device.
\end{itemize}
Exemple:
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
ACTION=="add", SUBSYSTEM=="net", RUN+="/bin/sh -c '/bin/echo %k : %p >> /root/events'"
\end{lstlisting}
Donne
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
$ cat /tmp/event
usb0 : /devices/soc0/soc/2100000.aips-bus/2184000.usb/ci_hdrc.0/gadget/net/usb0
eth0 : /devices/soc0/soc/2100000.aips-bus/2188000.ethernet/net/eth0
eth1 : /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1:1.0/net/eth1
sit0 : /devices/virtual/net/sit0
lo : /devices/virtual/net/lo
\end{lstlisting}
\end{frame}
% *******************************
% **** PRÉSENTATION ****
% *******************************
\section{Analyse d'évènements}
\subsection{Trouver les propriétés d'un périphérique}
\begin{frame}[fragile]
retrouver le répertoire sysfs d'un device:
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
$ udevadm info -x -q path -n /dev/hidraw0
/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.3/1-1.3:1.0/0003:046D:C01A.0015/hidraw/hidraw0
\end{lstlisting}
Obtenir des info sur le device:
\begin{lstlisting}[style=shell,basicstyle=\tiny\ttfamily\color{white}]
$ udevadm info /sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.3/1-1.3:1.0/0003:046D:C01A.0015/hidraw/hidraw0
P: //devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.3/1-1.3:1.0/0003:046D:C01A.0015/hidraw/hidraw0
N: hidraw0
E: DEVNAME=/dev/hidraw0
E: DEVPATH=//devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.3/1-1.3:1.0/0003:046D:C01A.0015/hidraw/hidraw0
E: MAJOR=247
E: MINOR=0
E: SUBSYSTEM=hidraw
\end{lstlisting}
\begin{itemize}
\item E: une propriété purement udev. elles sont accessibles grâce à \texttt{ENV\{\}}
\item N: le nom du périphérique suggéré par le noyau
\item S: les liens symboliques créés vers le périphérique
\item P: le chemin vers lentrée dans \texttt{sysfs}
\end{itemize}
\end{frame}
\subsection{Surveiller les évènements}
\begin{frame}[fragile]
Monitorer les actions en direct:
\begin{lstlisting}[style=shell]
$ udevadm monitor -p
\end{lstlisting}
L'option \texttt{-p} permet d'avoir les propriétés des évènements.
\end{frame}
\subsection{Tester des évènements}
\begin{frame}[fragile]
Tester un évènement:
\begin{lstlisting}[style=shell]
$ udevadm test -a add /sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.3/1-1.3:1.0/0003:046D:C01A.0018/hidraw/hidraw0
\end{lstlisting}
\end{frame}
% *******************************
% **** PRÉSENTATION ****
% *******************************
\section{Divers}
\subsection{La règle réseau}
\begin{frame}[fragile]
\begin{lstlisting}[style=shell]
$ cat board/eolane/modx6/rootfs_pendant/usr/lib/udev/rules.d/82-net-usb-up.rules
# do not edit this file, it will be overwritten on update
ACTION!="add", GOTO="net_usb_up_end"
SUBSYSTEM!="net", GOTO="net_usb_up_end"
ENV{ID_BUS}=="usb", RUN+="/bin/sh -c 'ifup %k'"
LABEL="net_usb_up_end"
\end{lstlisting}
\end{frame}
\subsection{mdev}
\begin{frame}[fragile]
\texttt{mdev} est un utilitaire similaire à \texttt{udev} présent dans \texttt{busybox}. Très utilisé dans l'embarqué.\newline
\newline
Mais \texttt{udev} est déjà très léger (le binaire fait 520K).
\end{frame}
% *******************************
% **** PRÉSENTATION ****
% *******************************
\section*{Conclusion}
\begin{frame}
\begin{center}
\begin{huge}
Question ?
\end{huge}
\end{center}
\begin{center}
\textcolor{gray}{\tiny{Enfin je vais essayer de répondre...}}
\end{center}
$ $\newline
\newline
Document basé sur:\newline
\url{http://www.linuxembedded.fr/2015/05/une-introduction-a-udev/}
\end{frame}
\end{document}