You are on page 1of 10

Les BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs

p/nfs Options de dmarrage Fabrication dun


Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun BSP

Option de gestion de la mmoire Configuration du boot et du FPE Configuration rseau

Boot options :
EABI, OABI, etc... : Diffrentes format dappel des fonctions. Flattened Device Tree : Utilise OpenFirmware, le nouveau format Networking :
Spcifique ARM (mais trs important) de description matriel appel aussi Flatten Device Tree Possibilit dactiver les innombrables protocoles rseaux de
Memory Model : Permet de grer les futurs systmes mmoire Default kernel command string : Permet de passer des niveaux 1, 2 et 3
asymtriques entre les CPU paramtres par dfaut au noyau (nous verrons cela un peu plus Network options : Beaucoup de fonctionnalit rseau : client
COMPACTION : Permet de compresser les page de mmoire loin) dhcp, bootp, rarp, ipv6, ipsec, les protocole de routage, gestion
plutt que les mettre en swap. Particulirement utile dans les boot loader address : Permettent de dmarrer le noyau partir de QoS, support des VLAN, du multicast,
systmes sans swap ! dune ROM, dune MMC, etc... Unix domain sockets : Les sockets UNIX (cf. sortie de netstat)
KSM : Permet de fusionner les page mmoire identiques. Kernel Execute-In-Place from ROM : Permet dexcuter un TCP/IP networking : Les sockets bien connue TCP/IP
Uniquement utile avec des machines virtuelles ou des chroot. noyau non compress partir dune ROM
Sinon, les noyau sait que le fichier est dj en mmoire et ne Netfilter : Le firewall de Linux. Dinnombrable options. Permet
duplique pas la page Floating point emulation : Si une instruction sur des nombres lutilisation diptables si loption IPTABLES est active.
virgule flottante est rencontre et ne peut pas tre excute, le noyau
peut alors muler linstruction (voir aussi -msoft-float)

Sysmic - J. Pouiller Formation au Noyau Linux 46 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 47 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 48 / 182

Les BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun BSP

Configuration des systmes de fichiers Configuration des systmes de fichiers Configuration des Drivers

File systems :
Second extended, Ext3 journalling file, The Extended 4 Miscellaneous filesystems Contient des systmes de fichiers Device Drivers Des centaines de drivers. Notons :
filesystem : Le file system standard de Linux spcifiques
FUSE : Permet de dvelopper des systmes de fichiers en eCrypt filesystem layer : Gestion transparent dun file system cod path to uevent helper : Le programme apell lorsquun nouveau
espace utilisateur Journalling Flash File System v2 : Spcialis pour les Flash avec priphrique est dtect (cf. /proc/sys/kernel/hotplug et
gestion de lcriture uniforme, des bad blocks et des erase blocks. /sys/kernel/uevent_helper)
Pseudo filesystems Systmes de fichiers sans supports Compressed ROM file system : Spcialis pour ROM sans accs
physiques Maintain a devtmpfs filesystem to mount at /dev : Un tmpfs
en criture.
TMPFS : File system volatile en RAM. Trs utilis avec des Squashed file system : Idem cramfs mais fortement compress
spcifique pour les devices automatiquement mont sur /dev.
systme en flash vu que laccs la Flash est coteux en temps et Les fichiers devices sont alors automatiquement crs sans
Network File Systems
destructeur pour la flash laide dun programme extrieur.
SYSFS et PROC_FS : Permettent au noyau dexporter un certain NFS client support : File system sur ethernet. Trs utilis dans
lembarqu durant les phases de dveloppement Memory Technology Device : Les flashs
nombre de donne interne vers le userland. Beaucoup doutils
systme tirent lors informations de ces systmes de fichiers. Ils Root file system on NFS : Permet de dmarrer le noyau sur une Staging drivers : Des drivers en cours de bta
doivent tre monts dans /sys et /proc. /proc est plutt partition NFS
orient processus alors que /sys est orient modules et
paramtrage du noyau.

Sysmic - J. Pouiller Formation au Noyau Linux 49 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 50 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 51 / 182

Les BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun BSP

Configuration du noyau Boot par tftp/nfs Notre cas


Dans notre cas, nous utilisons U-Boot (standard)

Pour le dveloppement du noyau, il est commun dutiliser les Compilation


Mais aussi : technologies : host% apt-get install uboot-mkimage
Kernel Hacking : Options concernant le dbugging du noyau. tftp : Il sagit dun protocole de transfert de fichier trs simple.
host$ make O=build ARCH=arm usb-a9260_defconfig
Security Options : Plusieurs framework permettant de grer des host$ make O=build ARCH=arm CROSS_COMPILE=arm-
Beaucoup de bootloaders limplmentent. Il permet un
droits plus fin sur les programmes excuts et/ou de garantir linux- -j3 uImage
dmarrage rapide dun nouveau noyau lors du dveloppement.
lintgrit des donne laide de TPM. On pourra aussi trouver des protocole sur RS232 ou sur USB
permettant la mme fonctionnalit. Comme pour un dmarrage Partage de limage par TFTP
Cryptographic API : Fonctions de cryptographies slectionnes
automatiquement par dautres modules (particulirement les normal, on indique au bootloader quelle adresse le noyau doit host% cp build/arch/arm/boot/uImage /srv/tftp/
protocoles rseaux) tre charg et on jump cette adresse uImage-2.6.33.7
Library routines : Idem Cryptographic API mais avec nfsroot : On demande au noyau de monter une partition rseau. host% ln -s uImage-2.6.33.7 /srv/tftp/uImage
principalement des calculs de checksum. On dispose ainsi dun espace de stockage illimit et il est simple
et rapide de mettre jour le rootfs. Au redmarrage, le bootloader passe par un registre lidentifiant
de la carte. Cet identifiant (spcifique larchitecture ARM) est
erron. A ce stade, il est plus facile de corriger ce problme dans
le noyau dans le fichier arch/arm/tools/mach-types.
Sysmic - J. Pouiller Formation au Noyau Linux 52 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 53 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 54 / 182
Les BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun BSP

Passage doptions au noyau Le rootfs La configuration rseau


Il est possible de passer des options au dmarrage du noyau
Cest normalement le bootloader qui se charge de passer la
ligne de commande au noyau
Il est possible dinitialiser le rseau avant de montage du rootfs
Le bootloader utilise un protocole prdfini (lorsquil donne la root= indique le disque monter sur /
main au noyau, un des registre contient un pointeur sur la ligne Indispensable pour le dmarrage par NFS
Srement loption la plus utilise Syntaxe : ip=<client-ip>:<server-ip>:<gw-ip>:<
de commande)
Il est possible de surcharger la ligne de commande lors de la Il est possible de spcifier le nom dune partition. Par exemple netmask>:<hostname>:<device>:<autoconf>
compilation avec loption CMDLINE root=/dev/sda1 (PC) ou root=/dev/mtd0 (partition flash) Exemple : ip=192.168.1.72:::::eth0:
Les diverses options acceptes sont dcrites dans root=/dev/nfs demande au noyau de dmarrer sur NFS Pour le dmarrage par nfs, il est aussi ncessaire de spcifier le
Documentation/kernel-parameters.txt Remarque : la partition / ntant pas encore monte, ces nom rpertoire partag par le serveur :
Il est possible daccder la ligne de commande aprs le de partition ne correspondent pas des fichiers existants dans nfsroot=192.168.1.10:/srv/nfs
dmarrage dans /proc/cmdline /dev. Le kernel utilise simplement la mme syntaxe. Il aussi possible de dmarrer en utilisant un DHCP (ou un autre
Il existe des paramtres globaux au kernel et des paramtres protocole dauto-ngociation) : ip=on
spcifiques un module. Lorsque le module est compil dans en
statique, il est possible de lui passer des paramtres avec la
syntaxe <MODULE_NAME>.<PARAM>=<VALUE>
Beaucoup doptions sont modifiable posteriori par /sys
Sysmic - J. Pouiller Formation au Noyau Linux 55 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 56 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 57 / 182

Les BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun BSP

La configuration rseau Dmarrage du noyau La console

A la fin du dmarrage du noyau, celui donne la main


Il est alors possible de spcifier le nfsroot dans la
lexcutable dclar avec init=. Par dfaut, il sagit de
configuration du serveur DHCP :
/sbin/init
host target { init ne se termine jamais Srement la deuxime option la plus utilise
option root-path "192.168.1.10:/srv/nfs";
Les arguments non-utiliss par le noyau sont pass init console= permet de demander au noyau dafficher la sortie de
next-server 192.168.1.10; printk sur un priphrique spcifique.
hardware ethernet 00:26:24:3a:14:5c; On peut estimer que notre systme dmarre partir du moment
ou nous obtenons un shell (cest en tous cas la que la plupart Sur PC, souvent limit console=ttyS0,115200n8.
fixed-address 192.168.1.72;
} des intgrateur Linux embarqu sarrteront) Sur un systme embarqu, il existe beaucoup de driver de ports
Du moins complexe au plus complexe dmarrer : sries diffrents. console peut alors prendre des valeurs
exotiques. A voir au cas par cas pour chaque driver.
Lors du dmarrage NFS, attention aux modifications de la init=/hello-arm-static
configuration rseau postrieure au montage du rootfs init=/hello-arm
init=/bin/sh
Rfrence : init=/sbin/init
Documentation/filesystems/nfs/nfsroot.txt
Effectuons ces tests avec le Rootfs original et un Rootfs vierge.

Sysmic - J. Pouiller Formation au Noyau Linux 58 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 59 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 60 / 182

Les BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun
Les
BSP
BSP Obtenir le noyau Organisation des sources Compiler le noyau Options principales Les drivers Le boot tftp/nfs Options de dmarrage Fabrication dun BSP

Panic La mmoire Etape de fabriquation dun BSP


Commencez par compiler une toolchain si celle-ci nest pas
Il est parfois ncessaire de donner des instructions au kernel sur fournie.
lutilisation quil peut faire des espaces mmoires Si le bootloader est fourni, travaillez avec celui-ci. Il arrive
mem=nn Force la taille de la mmoire que le noyau peut utiliser. souvent que les bootloader initialisent certains paramtres du
Sur beaucoup de plateformes, le noyau nest pas capable de CPU sans lesquels le noyau ne peut dmarrer
Un kernel panic est une erreur dtecte mais irrcuprable dtecter la capacit de la mmoire. Si vous navez pas de bootloader, vous devrez commencez par
paramtrer une sonde JTAG
panic=X permet demande au noyau de redmarrer aprs X memmap=nn@ss et memmap=nn$ss Force le noyau nutiliser
Sinon, vous pouvez dvelopper le noyau et le bootloader en
secondes en cas de kernel panic que la mmoire entre ss et ss+nn
parallle. Sans bootloader, vous devrez utiliser une sonde JTAG
Par dfaut, le noyau ne redmarre pas en cas de kernel panic memmap=nn@ss et memmap=nn$ss Force le noyau ne pas pour dmarrer votre cible
utiliser la mmoire entre ss et ss+nn Configurer le noyau jusqu pouvoir dmarrer lespace utilisateur
Il est possible dutiliser plusieurs fois ces options Compiler un busybox pour lespace utilisateur
Utiles pour rapidement rservs des espace dadresse dE/S pas Faites fonctionner les diffrents priphriques
encore dfini dans la configuration ou se rserver des blocs de Intgrer votre toolchain, votre bootloader, les fichiers de
mmoire particuliers pour la communication avec dautres configuration de votre noyau et de votre busybox, vos outils et
priphriques drivers spcifique dans un outil tel que BuildRoot
Zipper lensemble
Compilez lensemble et zipper le rsultat
Sysmic - J. Pouiller Formation au Noyau Linux 61 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 62 / 182 Intgrez vos modification dans lupstream
Sysmic - J. Pouiller Formation au Noyau Linux 63 / 182
Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

12 Macros de base
13 Licenses des modules Les modules noyau
my_module
14 Dveloppement des modules
15 Ecriture des Makefile
A lextrieur du noyau
Un template de module :
Troisime partie III A lintrieur du noyau
// Declare special functions
16 Charger des modules
module_init(m_init);
17 Utiliser des paramtres
module_exit(m_exit);
Le Coding Style
Les modules La documentation // These uppercase macro will be added to
Rgles de documentation informative section of module (.modinfo)
MODULE_AUTHOR("Jrme Pouiller");
O trouver la documentation
MODULE_DESCRIPTION("A pedagogic Hello World");
Trouver de laide MODULE_LICENSE("Proprietary");
18 LAPI MODULE_VERSION("1.1");
19 Gestion des erreurs
20 Communiquer avec le noyau
Les appels systmes
Sysmic - J. Pouiller Formation au Noyau Linux 64 / 182
Les fichiers devices
Sysmic - J. Pouiller Formation au Noyau Linux 65 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 66 / 182

Read et write
Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Les ioctls
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Quelques macros de base Quelques macros de base Parlons des licenses


Description du modules
Ces macros permettent de placer des informations sur des symboles
particulier dans module ; MODULE_DESCRIPTION Le noyau est dvelopp sous licence GPLv2
La GPL indique que tout travail driv dun projet sous GPL doit
Dclare la fonction appeler lors du chargement du module Version du module
tre GPL.
(traditionnellement module_init) MODULE_VERSION Ainsi, un module propritaire ne doit pas compiler en statique
module_init Rendre un symbole visible par les autres modules. Il sera alors avec le noyau (le rsultat est alors considr comme un travail
pris en compte dans le calcul des dpendances de symboles. driv du noyau). Il doit rester sous la forme dun module.
Dclare la fonction appeler lors du dchargement du module Pour le lutilisation dynamique des symboles, le dbat nest pas
(traditionnellement module_exit) EXPORT_SYMBOL(symbol)
tranch. Le noyau laisse la possibilit lauteur dexporter ses
Idem EXPORT_SYMBOL mais ne permet sont utilisation que pour modules avec EXPORT_SYMBOL ou avec EXPORT_SYMBOL_GPL.
module_exit
les modules GPL Si vous dveloppez un module Propritaire, vous naurez pas
Dclare un auteur du fichier. Peut apparatre plusieurs fois. EXPORT_SYMBOL_GPL(symbol) accs toute lAPI du noyau (environ 90% seulement).
Il est nanmoins possible de contourner le problme en utilisant
MODULE_AUTHOR License. Indispensable un module intermdiaire comme proxy logiciel.
MODULE_LICENSE

Sysmic - J. Pouiller Formation au Noyau Linux 67 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 68 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 69 / 182

Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Les licences Headers Les modules noyau


my_module

En remplissant correctement la macro MODULE_LICENCE, le


systme de compilation du noyau empchera les compilations #include <linux/kernel.h>
illgales. MODULE_LICENCE peut prendre plusieurs valeurs : GPL, #include <linux/module.h>
GPL v2, GPL and additionnal rights, Dual MIT/GPL, Dual BSD/GPL, #include <linux/init.h>
Dual MPL/GPL. Toutes les autres valeurs sont considres comme Il nest pas possible pour le noyau de compiler avec des bibliothques
propritaire. extrieur. En particulier avec la libc. Tous les headers habituels static int __init m_init(void)
/proc/sys/kernel/tainted (ou uname -a) indique si des sont donc inaccessible dans le noyau. {
modules propritaires sont charg. Les headers publiques sont dans include/. On retiendra en pr_info("my_module init\n");
particulier : linux/module.h, linux/init.h, linux/kernel.h return 0;
Quels consquences ? }
indispensables pour compiler un module.
Pas de support de la part de la communaut 10
static void __exit m_exit(void)
Pas de garantie de la qualit du modules
{
Mauvaise image auprs de la communaut et des clients pr_info("my_module exit\n");
Par exprience, les modules propritaires que lon croise dans }
lembarqu peuvent cacher tout et nimporte quoi.

Sysmic - J. Pouiller Formation au Noyau Linux 70 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 71 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 72 / 182
Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Les modules noyau Les modules noyau Compilation avec Kbuild


my_module my_module
Fichier Makefile lintrieur de larborescence noyau :
Pour amliorer le processus, on ajoute ces lignes dans le Makefile :
obj-$(MY_COMPILE_OPTION) := my_module.o
KDIR ?= /lib/modules/$(shell uname -r)/build
$(MY_COMPILE_OPTION) sera remplac par :
Fichier Makefile lextrieur du noyau : default: modules
: Non compil
obj-m := my_module.o m : compil en module
modules:
y : compil en statique
Puis, on appelle : $(MAKE) -C $(KDIR) M=$(shell pwd) modules
Fichier Kconfig :
host$ KDIR=/lib/modules/$(uname -r)/build modules_install: config MY_CONFIG_OPTION
host$ make -C $KDIR ARCH=arm M=$(pwd) modules $(MAKE) -C $(KDIR) M=$(shell pwd) tristate "my_module: A small Hello World
modules_install sample"
Il aussi est possible dappeler les cibles help et modules_install help
et on appelle Pedagogic purpose only.
1 host$ make ARCH=arm KDIR=../linux-2.6/usb-a9260
To compile it as a module, choose M here.
If unsure, say N.
Rfrence : Documentation/kbuild/modules.txt
Sysmic - J. Pouiller Formation au Noyau Linux 73 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 74 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 75 / 182

Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Utilisation de Kconfig Utilisation de Kconfig Grer les modules

Chaque entre config prend comme attribut :


Avoir des informations sur le module
Son type et sa description en une ligne :
tristate, le plus classique pouvant prendre les valeurs , m et y host$ modinfo my_module.ko
bool pouvant prendre seulement les valeurs n et y Il est aussi possible :
int prennant un nombre Dinclure dautres fichiers avec source Charger un module
string prennant une chane
De dclarer un sous menu avec menu target% insmod my_module.ko
default Sa valeur par dfaut
De demander un choix parmis un nombre fini doptions avec
depends on Loption napparait si lexpression suivante est Dcharger un module
choice
vraie. Il est possible de spcifier des conditions complexes avec
les oprateurs &&, ||, = et != Rfrence : Documentation/kbuild/makefiles.txt, target% rmmod my_module
select Active automatiquement les options en argument si Documentation/kbuild/kconfig-language.txt
loption est active Afficher le buffer de log du kernel (Diagnostic MESsaGes)
help Description dtaille de loption. Si votre description ne target$ dmesg
tient pas en moins de 20 lignes, pensez crire une
documentation dans Documentation et y faire rfrence

Sysmic - J. Pouiller Formation au Noyau Linux 76 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 77 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 78 / 182

Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Grer les modules Paramtres Paramtres


Nous devons dclarer le paramtre laide de la macro
Charger/dcharger un module correctement install/index dans module_param(name, type, perm);
modules.dep
name : Nom de la variable utilise comme paramtre
target% modprobe my_module
Il est possible de passer des paramtres aux modules : type : Type du paramtre (bool, charp, byte, short,
target% modprobe -r my_module
ushort, int, uint, long, ulong) (remarquez que ca ne
target$ modinfo my_module.ko correspond pas tout fait aux types C. Particulirement pour
Mettre jour le fichier de dpendances target% insmod my_module.ko param=2 bool et charp)
target% depmod perm : Permissions du fichier
host$ depmod -b ~/rootfs Il est possible de passer le paramtre au boot avec /sys/module/<module>/parameters/<param>. (utiliser les
my_module.param=2 macros de linux/stat.h). Si 0, le fichier napparat pas.
Notons que les modules sont des binaires elf standards qui La paramtre doit videment tre allou :
peuvent tre analyss avec les outils standard :
static int param = 0;
host$ arm-linux-objdump -t my_module.ko
Il est fortement recommand de documenter le paramtre
MODULE_PARM_DESC(param, "Useless parameter");
Sysmic - J. Pouiller Formation au Noyau Linux 79 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 80 / 182
Rfrence : linux/moduleparam.h
Sysmic - J. Pouiller Formation au Noyau Linux 81 / 182
Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

/sys Le Coding Style Le Coding Style


On ne doit pas avoir besoin dutiliser lascenseur (vertical ou
horizontal) pour lire une fonction (bref : 80 colonnes et pas trop
Quelques remarques sur la programmation lintrieur du noyau : de lignes par fonction)
Indentation la tabulation
Il nest pas possible daccder aux fonctions de la libc (ni des ... et une tabulation fait 8 espaces
Etudions /sys autres bibliothques) lintrieur du noyau
Si lindentation vous empche dcrire votre fonction, cest que
/sys/module/my_module/parameters : Les paramtres. Pas de C++ dans le noyau. Cest techniquement fesable mais celle-ci possde trop de niveaux dimbrication
Modifiables si dclars modifiables dconseill et sera refus par lupstream Mettre au propre les tabulations et vrifier la taille des lignes :
/sys/module/my_module/sections : Des infos sur la zone Il ny a pas de garde fou pour la mmoire du noyau. Un accs
de chargement mmoire invalide pourra potentiellement est rattrap par un host$ scripts/cleanfile my_module.c
Oops, mais ca nest pas garanti.
Incolade sur la mme ligne que les blocs
Attention la portabilit. Votre code ne doit pas tre dpendant ... sauf pour les fonctions
de lendianess ou de taille des integer.
Pour indenter correctement votre code
host$ apt-get indent
host$ scripts/Lindent my_module.c

Sysmic - J. Pouiller Formation au Noyau Linux 82 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 83 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 84 / 182

Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

CodingStyle La documentation Trouver de la documentation


Le noyau nest pas un modle de documentation
En revanche, le systme de dveloppement facilite normment Dans Documentation (en utilisant grep)
la recherche dinformations
Le noyau utilise un script perl appel kernel-doc. Ce script La cible htmldocs permet de compiler les documentation au
Les noms des variables locales doivent tre courts format Docbook (Documentation/DocBook)
parcours le code la recherche de syntaxe du mme type que
Si vous avez besoin de nom plus explicites, cest que vous avez doxygen. (Rfrence : Documentation/kernel-docs.txt) ... en particulier Linux Device Drivers et Linux Device Drivers.
trop de variables locales Un commentaire ne doit pas ce substituer un code pas illisible. Toutefois, ces compilations sont loin dtre exhaustives
Pas de CamelCase Prfrez rcrire le code plutt quajouter un commentaire. La cible mandocs permet dextraire les diffrente API invoque
Il faut prserver la propret de lespace de nommage en Une fonction exporte doit tre prfixe par un commentaire la dans les DocBook sous forme de pages de man.
prfixant par statique tout ce qui ne doit pas tre export dcrivant. Ce commentaire ne doit surtout explique comment la http://kernel.org/doc regroupe les diverses
(fonctions, variables) fonction marche. Le commentaire indique le quoi, mais surtout le documentations en ligne
pourquoi cette fonction existe.
Rfrence : Documentation/CodingStyle Dans les commentaires du noyau (fichiers .c ou .h)
Ces commentaires sont place avant la dfinition des fonctions.
Les fonction du noyau sont souvent dfinie dans les headers. Du http://lxr.linux.no offre une interface permettant de
coup, les commentaires sont parfois dans le fichier .c et parfois rapidement chercher des symboles et naviguer dans le code du
dans le fichier .h noyau.
Les commentaires expliquant le fonctionnement gnral dun
framework doivent tre crit sous la forme dune documentation
Sysmic - J. Pouiller Formation au Noyau Linux 85 / 182 darchitecture et place
Sysmic - J.dans
Pouiller Documentation/
Formation au Noyau Linux 86 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 87 / 182

Rfrence : Documentation/CodingStyle
Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Les livres de rfrence Trouver de laide LAPI non-stable


Les rfrences :

Demander de laide la communaut LAPI non-stable ne facilite pas la maintenance des


documentations
Le fichier MAINTAINERS contient la liste des mainteneur de De mme, la maintenance des modules hors du noyau demande
chaque sous-systme beaucoup defforts
Les entres commencant par L: indique des mailing lists Cest encore pire de maintenir un module pour plusieurs versions
Notons <linux-newbie@vger.kernel.org> (driver nvidia par exemple)
MAINTAINERS liste aussi les sites officiel, les fichiers de En revanche, lAPI non stable permet des dveloppement plus
documentation, etc... pour les diffrents sous-projets du noyau agiles. En fait, le noyau serait intenable si il essayait de maintenir
LWN : http://lvn.net une API stable.
git blame permet de savoir qui a modifier la fonctions ou les
Embedded Linux Wiki : http://elinux.org
lignes qui nous intresse. Cela permet de sorienter vers le bon Lors quun dveloppeur modifie une API, il doit patcher
Les rfrences de nos amis de la communaut francaise : groupe lensemble des driver utilisant lancienne API.
Gilles Blanc : Linux embarqu - Comprendre, dvelopper, russir Rfrence : http://kernel.org/doc On prfre souvent laisser lancienne et la nouvelle API cohabiter
Jrme Pouiller : http://sysmic.org en demandant au maintainers de migrer vers la nouvelle
Thomas Petazzoni et Michael Opdenacker :
http://free-electrons.com/docs/
Sysmic - J. Pouiller Formation au Noyau Linux 88 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 89 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 90 / 182
Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

LAPI non-stable Gestion des erreurs Gestion des erreurs

Il ny a pas de raisons de maintenir un driver lextrieur du


noyau, sauf les problmes de licences
La plupart des fonctions retournant des int retournent une Vous devez systmatiquement grer les erreur retourner par les
Il peut tre coteux en temps dintgrer un module dans le valeur ngative en cas derreur sous-fonctions mme si il vous semble impossible quelle se
mainstream. Les mainteneurs vous demanderons srement de
Les valeurs retourne correspondent aux inverses des erreurs produise.
corriger beaucoup de chose.
Posix dfinis dans errno.h (ie : -EAGAIN). Certaines pannes matrielles peuvent amener des
Il faut compter 2 4 fois le temps de dveloppement initial pour
Rfrence : errno(3), asm/errno-base.h et asm/errno.h comportements qui paraissent impossibles. Facilit le travaille
intgrer un module dans le mainstream
Les fonctions renvoyant des pointeurs peuvent retourner NULL des debugueurs en dtectant ce type derreur le plus tt possible
Une fois que votre module est intgr dans le mainstream et a
ou des valeurs spciale en cas derreur Lorsque vous grez une erreur, vous devez dfaire tout ce qui
pass la phase de staging, il sera thoriquement maintenu et
Utiliser les macro PTR_ERR, ERR_PTR et IS_ERR dj t fait
support pour toujours.
Rappel : le segfault nexiste pas dans le noyau. Une manire connue de grer les erreur dinitialisation dans le
Paradoxalement, lAPI non-stable permet que la dure de
noyau est dutiliser goto
maintenance dun driver dans le noyau sera longue (en thorie Rfrence linux/err.h
infinie)
Rfrence Documentation/stable_api_nonsense.txt

Sysmic - J. Pouiller Formation au Noyau Linux 91 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 92 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 93 / 182

Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Grer les erreurs Communiquer avec le noyau Communiquer avec le noyau


char_dev char_dev

ptr = kmalloc(sizeof(device_t)); Le seul moya de communiquer depuis le userspace vers le


if (!ptr) { noyau passe par les appel systmes. Il existe dans la norme Unix des fichier spciaux, appels fichiers
ret = -ENOMEM Il sagit de placer les paramtres sur la piler et de dclencher devices, dont les appels systmes ne sont pas mapps sur des
goto err_alloc; une interruption logicielle particulire (sur x86, il sagit de fichiers rels mais sur des fonctions du noyau.
} linterruption 0x80, ou sysenter/sysexit). Ainsi, le noyau Un fichier device est associ deux nombre, le major et le minor.
dev = init(&ptr); reprend la main et effectue une action en fonction des On spcifie ces deux nombres lors de lors de la cration du
if (dev) { paramtres stocks que la pile. fichier avec la commande mknod :
ret = -EIO Le premier paramtre correspond au numro de lappel systme
goto err_init; (cf. syscalls(2), asm/unistd.h). target% mknod my_device c 253 0
10 } Il y a environ 300 appels systmes dans le noyau. Il est rare target% ls -l my_device
return 0; dajouter de nouveau appels systme et exceptionnel den
modifier ou den supprimer. Il est possible de communiquer avec les fichiers device en
err_init: Le modle Unix consiste limiter le nombre des appels utilisant les outils standard
free(ptr); systmes et de tout grer par lintermdiaire de fichiers. target% cat my_device
err_alloc: Parmi les appels systmes associs aux fichiers, nous trouvons target% echo foo > my_device
return ret; open, read, write, mmap, ioctl (pour modifier la
configuration du priphrique), etc...
Sysmic - J. Pouiller Formation au Noyau Linux 94 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 95 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 96 / 182

Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Communiquer avec le noyau Communiquer avec le noyau Mmoire userspace


char_dev char_dev

Cot noyau, un driver peut allouer une(des) entre(s) dans la


table des devices et associer des fonctions au appels systme Il existe historiquement deux types de fichiers devices :
associ cette entre (cf. register_chrdev, block : Pour les priphriques de tailles fixes accs alatoire.
struct file_operations dans linux/fs.h) Principalement des priphriques de stockage. Les fonction de la struct file_operations recoivent en
character : Pour les priphriques avec des donnes sous forme
En standard, tous les fichiers devices sont regroups dans /dev. paramtre des adresses provenant de lespace dadressage du
de flux comme des ports sries.
Autrefois, les numro de devices taient normaliss (cf processus appelant. En raison de la sparation des espaces
Cette diffrence est aujourdhui de moins en moins vidente mmoire (nous y reviendrons lorsque nous parlerons plus en dtail
Documentation/devices.txt) et les fichiers de /dev tait
crs statiquement Les cartes rseaux sont une exception notable de se modle. Il du fonctionnement de la MMU), ces adresses ne peuvent pas tre
nexiste pas de fichiers devices pour les cartes rseau. Il est utilise directement dans le noyau. Il est est ncessaire dutiliser les
Avec laugmentation du nombre de priphriques existants et ncessaire dutiliser des appels systmes spcifiques. fonctions copy_from_user et copy_to_user pour y accder.
larrive des bus hotplugs tels que lUSB, ce modle ntait plus
tenable. Il existe donc des systme dallocation dynamique de Notons aussi que de nos jours, de nombreuses fonctionnalits
numro de devices (cf. /proc/device et sont accessibles par les file systems virtuels (procfs, sysfs,
/sys/dev/{char,block}) et des systmes crant debugfs, etc...). Ils permettent les mme fonctionnalit que les
automatiquement les fichiers ncessaires (hotplug, udev, mdev, fichier devices, mais sans leur complexit.
devtmpfs, etc...)

Sysmic - J. Pouiller Formation au Noyau Linux 97 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 98 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 99 / 182
Macros de base Licenses des modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs
Macros de
Communiquer
base Licenses
avec des
le noyau
modules Dveloppement des modules Ecriture des Makefile Charger des modules Utiliser des paramtres LAPI Gestion des erreurs Communiq

Communiquer avec le noyau Communiquer avec le noyau Les ioctl


char_dev char_dev
Les appels systmes read et write permettent de communiquer
correctement avec les priphriques. Nanmoins, les priphriques
Nous allons faire un driver permettant de faire un pipe avec un buffer : possdent trs souvent des options de paramtrages. On utilise alors
lappel systme ioctl.
target% insmod my_chardev.ko
Vrifions le comportement : Celui-ci prend en paramtre un numro didentifiant et un
target% echo toto > my_dhardev
nombre variable darguments :
target% cat my_chardev target% insmod my_chrdev.ko
toto target% mknod my_chrdev c 251 0 ret = ioctl(fd, FIFO_GET_LEN, &arg);
target$ for i in {1..64}; echo "$i " > my_chrdev
Nous utiliserons : Il est existe une normalisation pour le format du numro dioctl
target$ cat my_chrdev
(FIFO_GET_LEN). Les macro _IO, _IOR, _IOW et _IOWR
target% rmmod my_chrdev
copy_to_user, copy_from_user permettent de gnrer des numro dioctl corrects :
kcalloc, kfree #define FIFO_GET_LEN _IOR(f, 0x01, int)
register_chrdev, unregister_chrdev_region
memmove On Rfrence :
Documentation/ioctl/ioctl-decoding.txt
Les ioctl existants sont lists dans
Documentation/ioctl/ioctl-number.txt
Sysmic - J. Pouiller Formation au Noyau Linux 100 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 101 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 102 / 182

Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

21 Les frameworks
22 Les fonctions inspirs de la libc Les frameworks
23 Accder au E/S
24 Allouer de la memoire
Le noyau est divis en frameworks.
25 La MMU
Pour bien utiliser un framework, il est ncessaire de comprendre
Quatrime partie IV 26 Les interruptions
Allouer des interruptions
le fonctionnement du noyau et de la technologie dcrite par le
framework.
Les Softirq Un framework est gnralement dcrit dans son fichier .h
27 Les Wait Queues (exemple : linux/usb.h).
LAPI 28 Les DMA Un framework contient gnralement une paire de fonctions
29 Les structures de donnes register/unregister permettant au driver de se dclarer
Les listes auprs du framework (Exemple : usb_register_driver)
30 Mecanismes de synchronisation La fonction register prend souvent en paramtre une
Les fifos structure contenant des pointeurs sur des callbacks appeles
lors des divers vnements pouvant se produire (exemple : la
Les mutex
structure usb_driver)
Dsactivation des interruptions
Parmi les callbacks, il y a souvent une fonction probe
Spin Lock
Les RCU
Sysmic - J. Pouiller Formation au Noyau Linux 103 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 104 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 105 / 182
Les barrires mmoires

Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Les frameworks Fonctions standards de string.h Fonctions standards de string.h

Les extensions de gcc sont utilises pour initialiser ces Convertions de nombres et de boolens : strtobool,
structures avec les attributs nomms Taille de chainesstrlen, strnlen kstrto{int,uint,l,ul}
Un framework fourni aussi dautres fonctions permettant de kstrto{s64,u64,s32,u32,s16,u16,s8,u8}
Comparaisons : strcmp, strncmp, strcasecmp,
lancer des actions (exemple : usb_submit_urb) kstrto{s64,u64,s32,u32,s16,u16,s8,u8}_from_user
strncasecmp, strnicmp, memcmp, strstarts
(existe aussi prfix avec simple_, mais destin mourrir)
Un framework peut raffiner un framwork plus gnrique (en le Recherches : strchr, strnchr, memchr, memscan, strrchr,
proxifiant) (exemple : les framework usb_serial et le framework Duplication avec allocation : kmemdup, kstrdup, kstrndup,
memchr_inv, strspn, strcpsn, strstr, strnstr, strpbrk
usb) memdup_user, strndup_user (nous verrons largument gfp
Copies : strcpy, strncpy, memcpy, strcat, strncat, un peu plus loin)
Une driver peu appartenir plusieurs frameworks. Par exemple, strsep
un driver de carte rseau peut utiliser le framework pci, le Formatage : sprintf, snprintf, sscanf
strlcpy et strlcat (De meilleures implmentations de
framework, network_device, sysfs, debugfs, etc... Utilitaire sur les nombres : max, max3, min, min3, clamp, swap
strncat et strncpy). Toujours utiliser ces fonctions.
Il existe un framework pour les modules (linux/modules.h) Notez que beaucoup de ces fonctions possdent des
skip_spaces, strim, strstrip : Supprime les blanc en
accessible avec THIS_MODULE implmentations gnriques mais peuvent tre surcharges par
dbut et fin de chane
Un exemple de framework simple enrobant les char devices : architecture
include/linux/cdev.h Rfrence : linux/string.h linux/kernel.h

Sysmic - J. Pouiller Formation au Noyau Linux 106 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 107 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 108 / 182
Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Au sujet des accs aux E/S Fonctionnement en PIO Fonctionnement en MMIO


La mthode daccs aux E/S dpend de larchitecture : On doit dabord informer le noyau que lon utilise une plage de
Il existe des fonctions identique pour les MMIO.
ports avec
Memory Mapped Input Output (MMIO) : Registres mapps en
struct ressource *request_region(unsigned long struct ressource *request_mem_region(unsigned
mmoire. Il suffit de lire et crire une adresse particulire pour
start, unsigned long len, char *name); long start, unsigned long len, char *name)
crire dans les registres du priphrique. La mthode la plus
void release_region(unsigned long start, void release_mem_region(unsigned long start,
rpandue
unsigned long len); unsigned long len)
Port Input Output (PIO) : Registres accessible par un bus ddi.
Instructions assembleurs spcifiques (in, out). Cas notable de Rfrence : linux/ioport.h Il est possible de voir le mapping actuel dans le fichier
larchitecture x86. Permet dviter que deux drivers essayent de rfrencer la /proc/iomem
mme plage de ports. Il est ensuite ncessaire de faire appel au MMU pour mapper les
On dclare rarement les adresses des priphriques en absolu. On
Il est possible davoir des information sur les ports actuellement IO dans lespace dadressage du noyau
prfrera dfinir les offsets partir dune base :
utiliss en lisant le fichiers /proc/ioports
outb(base_device + REGISTER, 1); Une fois rserv, il est possible de lire/crire sur les ports avec : void *ioremap(unsigned long phys_add, unsigned
long size)
u\{8,16,32\} in\{b,w,l\}(int port);
ou void iounmap(unsigned long phys_addr)
void out\{b,w,l\}(u\{8,16,32\} value, int port)
writeb(base_device->register, 1); ;
Ces fonctions soccupent de la cohrence avec le cache.
Ces fonctions soccupent de convertir les donnes dans le bon
Sysmic - J. Pouiller Formation au Noyau Linux 109 / 182 endian Sysmic - J. Pouiller Formation au Noyau Linux 110 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 111 / 182

Rfrence : asm/io.h
Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Fonctionnement en MMIO Accder aux IO en userspace Quelques notions


Sur les architectures simples, il possible de directement
drfrencer le rsultat de ioremap. Il existe nanmoins des
fonctions apportant une couche dabstraction (barrires Adresses physiques : Adresses physiques de la mmoire
/dev/mem est un fichier fichier device permettant daccder aux
mmoire, etc...). Adresses virtuelles : Adresses converties par le MMU
adresses physiques.
Adresses logiques : Adresses dans lespace du noyau mappe
u{8,16,32,64} read{b,w,l,q}(void *addr) Il est possible dutiliser mmap sur ce fichier et dcrire aux linairement sur les adresses physiques
void write{b,w,l,q}(u{8,16,32,64}, void *addr) adresses occupes par des priphriques Elles peuvent tre converties en adresses physiques en appliquant
Sur les architectures utilisant PIO, il est possible de demander au un simple masque de bits
Vous devez utilisez ces fonctions :
noyau de laisser un processus utilisateur utiliser les instruction Les adresses logiques sont des adresses virtuelles
les adresses ne sont pas volatiles assembleurs out* et in* pour quils puissent accder aux Sur les architectures 32bits, les adresses logiques sont places
write et read soccupent de placer des barrires et ou davoir entre 0xC0000000 (3Go) et 0xFFFFFFFF
priphrique avec ioperm et iopl.
des accs volatiles Il est toutefois possible de modifier ce parametrage
il peut y avoir des problmes de SMP ou de premption grs par Cest ainsi que fonctionne les serveurs graphiques XFree86 ou Il est possible de convertir une adresse logique en adresse
write et read xorg physique avec la macro __pa
certaines architectures ne supportent pas laccs direct la ... et faire linverse avec la macro __va
mmoire
il est plus facile pour sparse de dtecter des erreur
Cas notable des accs PCI (little endian obligatoire)

Sysmic - J. Pouiller Formation au Noyau Linux 112 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 113 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 114 / 182

Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Quelques notions Les pages Les pages


Il est possible dallouer et de dsallouer des pages avec :
struct page *alloc_pages(unsigned int flags,
Les pages sont lunit de gestion du MMU.
unsigned int order);
Mmoire basse (Low Memory) : Partie de ladressage virtuel PAGE_SIZE indique la taille des page sur larchitecture courante struct page *alloc_page(unsigned int flags);
contenant les adresses logiques. (voir /proc/kallsyms en Une page fait 4 8Ko. void __free_page(struct page *page);
root) void __free_pages(struct page *page, unsigned
Page Frame Number (PFN) Le numro de la page. Ce sont en int order);
Mmoire haute (High Memory) : Le reste de ladressage virtuel fait les bits de poids fort des adresses.
Out Of Memory (OOM) killer : Mcanisme dclench lorsque le Il est facile de convertir les pages en pfn et inversement avec Les flags sont dcrit un peu plus loin
systme ne peut plus fournir de mmoire. Dans ce cas, un page_to_pfn et pfn_to_page (correspond page - CST et order indique le nombre de pages allouer. Le noyau alloue
processus est dsigne pour tre kill. Il sagit dun algorithme pfn + CST) 2order pages
heuristique int get_order(unsigned long size) retourne order
Il est possible dobtenir ladresse virtuelle dune page avec la
ncessaire pour avoir size octets de mmoire
macro page_address (si elle est mappe dans lespace
Il existe des raccourcis pour allouer une nouvelle page et obtenir
dadressage du noyau)
son adresse :
unsigned long get_zeroed_page(int flags);
unsigned long __get_free_page(int flags);
unsigned long __get_free_pages(int flags,
Sysmic - J. Pouiller Formation au Noyau Linux 115 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 116 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 117 / 182
unsigned long order);
void free_page(unsigned long addr);
Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Le Slab Cration de pool dans le Slab Options dallocation


Le Slab est lallocateur de mmoire du noyau. Cest lquivalent Si vous avez de grande quantit dobjets identiques grer, ou si
de lallocateur de la libc. Elles permettent de spcifier des contraintes sur lallocateur. Les plus
vous avez des besoins spcifiques, vous pouvez crer un pool
Il existe des alternatives telles que le Slub ou le Slob courantes sont :
spcialement pour vos besoins.
Il gre des pool despace mmoire. GFP_KERNEL : Standard
Il est possible dobtenir des informations sur ltat du Slab en Le cas chant, il est mme possible dutiliser vos propres fonctions
GFP_USER : De la mmoire destine tre donne un
lisant le fichier /proc/slabinfo dallocation :
processus utilisateur. Elle est alors bien spare des pages
Il est possible dallouer et de dsallouer des espaces de
mempool_t *mempool_create(int min_nr, alloues pour le noyau.
mmoire avec le Slab en utilisant :
mempool_alloc_t *alloc_fn, mempool_free_t * GFP_HIGHUSER : Indique en plus que lallocation doit tre faite
void *kmalloc(size_t size, gfp_t flags); free_fn, void *data); dans la mmoire haute
void kzalloc(size_t size, gfp_t flags); void mempool_destroy(mempool_t *pool);
void kzfree(const void *p); GFP_ATOMIC : Lallocateur ne peux pas bloquer durant
void *kcalloc(size_t n, size_t size, gfp_t lallocation. Permet dtre utilis dans des interruptions. Utilise le
Vous pouvez garder la politique dallocation par dfaut en utilisant : pool dallocation durgence. Ne pas en abuser.
flags);
void kfree(const void *objp); void *mempool_alloc(mempool_t *pool, int gfp_mask); GFP_DMA : Retourne un bloc contenu dans lespace physique
void mempool_free(void *element, mempool_t *pool); utilisable par les DMA
On retrouve aussi lquivalent de realloc :
Rfrence : linux/gfp.h
void *krealloc(const void *p, size_t new_size, Rfrence : linux/mempool.h, /proc/slabinfo
gfp_t flags);
Sysmic - J. Pouiller Formation au Noyau Linux 118 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 119 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 120 / 182

Sauf mention contraire, le Slab retourne des adresse logiques


Les frameworks
Dans tous les cas, le Slab retourne de la mmoire physiquement
Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis
contigu
Rfrence : linux/slab.h
vmalloc Conversions La mmoire des processus

Il est possible dallouer de la mmoire non-contigu avec Copier des donnes depuis/vers lespace dadressage du
vmalloc : processus courant :
void *vmalloc(unsigned long size); Il est possible de faire des conversions en utilisant : int copy_from_user(kern_buf, user_buf, size);
void *vzalloc(unsigned long size); phys_to_virt et virt_to_phys (qui appellent __pa et __va int copy_to_user(user_buf, kern_buf, size);
void vfree(void *addr); si possible)
Retourne le nombre doctets non copis
page_to_virt, virt_to_page, phys_to_page et
Alloue dans la mmoire haute Lire/affecter une variable simple (jusqu 8 octets) de lespace
page_to_phys (qui appellent page_address)
... ainsi la mmoire alloue peut tre non contigu dans la dadressage du processus courant :
pfn_to_page et page_to_pfn
mmoire physique
get_user(var, user_ptr);
Il est ainsi possible dallouer dimportante quantit de mmoire. put_user(var, user_ptr);
Rfrence : linux/vmalloc.h, mm/vmalloc.c,
/proc/vmallocinfo La taille de var est automatiquement calcule

Sysmic - J. Pouiller Formation au Noyau Linux 121 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 122 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 123 / 182

Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

La mmoire des processus Mapper des adresse physiques Sparse


La variable current pointe sur le processus courant Parmi les fonctions les plus utiles, remap_pfn_range permet de
mapper des adresses physiques dans un espace utilisateur. Elle est
Chaque processus possde une table de mapping mmoire particulirement utile pour implmenter lappel mmap : Sparse est un outils spcifique au noyau
Le mapping du processus courant se trouve dans current->mm Sparse parse le code et interprte certains attributs non dfinis
int remap_pfn_range(
lors de la compilation avec gcc
current->mm->rb_tree contient des virtual memory area struct vm_area_struct *vma,
unsigned long addr, bitwise indique que deux types ne peuvent pas tre casts
(vma) sous la forme dun arbre rouge-noir
Il est possible dutiliser la fonction find_vma(mm, addr) pour unsigned long pfn, (exemple : phys_addr_t et long unsigned)
retrouver une VMA unsigned long size, address_space(NUM) prcise le domaine dun pointeur et
allouer de la mmoire consiste allouer une structure pgprot_t flags); empche les pointeurs de diffrent domaines dtre affect entre
vm_area_struct et lajouter dans larbre rouge-noir eux :
Le noyau parle ensuite to pin une page en mmoire lorsque celle-ci vma Espace dadressage virtuel dans lequel le mapping doit address_space(0) Kernel
doit tre rellement alloue seffectuer. Dans le cadre de mmap, fournie par le kernel. address_space(1) User
Il est possible dobtenir les mapping dun processus en lisant les addr Ladresse lintrieur de vma (=offset) address_space(2) MMIO
fichier /proc/<PID>/map, /proc/<PID>/smap, pfn La page physique mapper Lancer vos compilation avec loption C=1 pour activer Sparse
/proc/<PID>/pagemap size Taille de lintervalle mapper Rfrence : linux/compiler.h, sparse(1)
Rfrence : Documentation/vm/pagemap.txt, flags Flags ventuels (reprendre vma->vm_page_prot)
Documentation/filesystems/proc.txt, linux/mm.h Il est aussi possible de surcharger lattribut
Sysmic - J. Pouiller Formation au Noyau Linux 124 / 182
vm_operations_struct Sysmic - J.*
vm_ops
Pouiller
de la vm_area_struct afin
Formation au Noyau Linux 125 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 126 / 182
de grer soit mme les diffrentes exceptions. Peut-tre utile pour le
dveloppement de certains drivers (good luck)
Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Interruptions Interruptions Le PIC


Pour demander la gestion dune interruption :
int request_irq(
unsigned int irq, Une fois alloue, il est possible de demander au systme (au
irq_handler_t handler, Il est possible dobtenir la liste des interruptions enregistres
Programmable Interrupts Controller (PIC) en fait) dactiver ou non
unsigned long flags, dans /proc/interrupts
linterruption avec :
const char *devname,
On libre linterruption avec : void enable_irq(unsigned int irq)
void *dev_id)
void free_irq(unsigned int irq, void *dev_id) void disable_irq(unsigned int irq)
irq : Le numro de lIRQ
handler La fonction apeller. Note : Les PIC sont des priphriques comme les autres. Nous
irq : Numro dirq nexpliquons pas spcifiquement ici comment dvelopper un driver
flags Principalement :
IRQF_SHARED : Linterruption peut tre partag dev_id : Instance supprimer. dev_id doit donc tre unique pour un PIC.
devname : Un descriptif pour /proc/interrupts pour chaque IRQ
Rfrence : linux/interrupts.h
dev_id : Pointeur qui sera pass en paramtre de handler.
On utilise gnralement un pointeur sur une structure dcrivant
linstance du device. Ce pointeur aussi son importance lors de
la libration de linterruption.
Sysmic - J. Pouiller Formation au Noyau Linux 127 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 128 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 129 / 182

Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Les handlers dinterruption Softirq Tasklets


Les softirqs sont excuts dans lenvironnement des
Les gestionnaires (handlers) dinterruption :
interruptions mais alors que les interruptions sont actives
Il est de type irqreturn_t (*)(int irq, void *dev_id) Elles nempchent pas le dclenchement des interruptions mais Excuts par les SoftIrq Hi et Tasklet
Il doit retourner (irqreturn_t) ne sont pas ordonnances avec les tches
Par consquent, quasiment les mmes rgles que les Hi est excut avec la priorit la plus haute parmi les SoftIrq,
IRQ_HANDLED si linterruption a bien t gre alors que les Tasklets ont quasiment la priorit la plus basse
IRQ_NONE dans le cas inverse. Linterruption est alors passe au interruptions sappliquent
handler enregistr suivant si linterruption est partage Les Softirq sont rservs aux tche demandant une frquence Pour initialiser et ds-enregistrer un tasklet :
de traitement importante. Les dveloppeurs du kernel gardent le
Il doit acquitter linterruption sur le priphrique DECLARE_TASKLET(name, void (*func)(unsigned
nombre de Softirq en quantit limite :
Il ne doit pas tre bloquant : long), unsigned long data);
pas de wait_event HI_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, void tasklet_init(struct tasklet_struct *t,
pas de sleep TIMER_SOFTIRQ, TASKLET_SOFTIRQ, void (*func)(unsigned long), unsigned long
allocation de mmoire avec GFP_ATOMIC NET_TX_SOFTIRQ, SCHED_SOFTIRQ, data);
attention aux sous-fonctions, vrifier quelles sont bien interrupt NET_RX_SOFTIRQ, HRTIMER_SOFTIRQ, void tasklet_kill(struct tasklet_struct *t);
compliant BLOCK_SOFTIRQ, RCU_SOFTIRQ,
Le maximum de traitement doit tre report dans le Bottom Half Les SoftIrq Hi et Tasklet sont des multiplexeurs permettant
(bh) dexcuter dautres tches
Rfrence : linux/interrupts.h
Sysmic - J. Pouiller Formation au Noyau Linux 130 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 131 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 132 / 182

Les frameworks Les fonctions inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes
Les frameworks
Mecanismes
Les fonctions
de synchronisation
inspirs de la libc Accder au E/S Allouer de la memoire La MMU Les interruptions Les Wait Queues Les DMA Les structures de donnes Mecanis

Tasklets Les kthreads Les kthreads


Equivalent des threads en espace utilisateur
Crer une kthreads : Affecter une kthread un CPU
Pour demander lexcution dun Tasklet (dans le SoftIRQ Tasklet
struct task_struct *kthread_create(int (* void kthread_bind(struct task_struct *k,
et dans le SoftIRQ Hi)
threadfn)(void *data), void *data, const unsigned int cpu)
void tasklet_schedule(struct tasklet_struct *t) char namefmt[], ...)
void tasklet_hi_schedule(struct tasklet_struct Tuer une kthread :
*t) Marquer la tche comme devant tre tre ordonnance
(Fonctionne avec toute les tches, pas spcifique aux kthreads) int kthread_stop(struct task_struct *k)
Si la tasklet tait dj prvue pour tre excute, elle ne sera wake_up_process(struct task_struct *k)
excute quune fois. Ne pas trop abuser des kthreads. Les calculs seffectuent
normalement dans les SoftIRQ et surtout dans les appel
Si la tasklet est dj en cours dexcution, elle sera r-excute Il est possible de faire kthread_create et wake_up en un seul
systme des processus. Le cas chant, prfrez lutilisation des
(mais pas simultanment, mme sur un SMP). appel :
Workqueue gnriques. Enfin, posez-vous la question si laction
Rfrence : linux/interrupts.h struct task_struct *kthread_run(int (*threadfn) doit tre effectue dans le noyau ou dans lespace utilisateur
(void *data), void *data, const char namefmt Rfrence : linux/kthread.h
[], ...)

Sysmic - J. Pouiller Formation au Noyau Linux 133 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 134 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 135 / 182

You might also like