Вы находитесь на странице: 1из 10

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
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

Workqueues Workqueues Les Wait Queues


Mcanisme gnral pour repousser un calcul
Permet dordonnancer des des tches dans une kthread
Permet dattendre de manire passive un vnement.
Exemple dutilisation des Workqueues : flush des caches des
disques, dfragmentation en arrire-plan, etc... Peut-tre utilis dans le contexte dune tche ou dans une
Il est possible dutiliser dautre workqueue (= dautres kthreads) kthread.
INIT_WORK(work, func) permet de dclarer une nouvelle que celle de schedule_work
structure work excutant func Cela permet de faire passer la tche associe de ltat run
int queue_work(struct workqueue_struct *wq, ltat wait
int schedule_work(struct work_struct *work)
struct work_struct *work) permet de demander
permet de demander lexcution de work Fonctionne de manire similaire des pthread_cond ou des
lexcution de work en spcifiant la workqueue.
int schedule_work_on(int cpu, struct rt_event sous Xenomai ou les OSFlags sous C/OS-II
work_struct *work) spcifie un CPU particulier sur lequel le Il est aussi possible de crer ses propres workqueues avec
Pour dclarer :
work doit sexcuter alloc_workqueue(name, flags, max_active)
DECLARE_WAIT_QUEUE_HEAD(my_queue) : initialisation
int schedule_delayed_work(struct delayed_work * Rfrence : linux/workqueue.h lors de la dclaration
work, unsigned long delay) dmarre work aprs un wait_queue_head_t my_queue;
certain dlais. Permet de faire des tches priodiques. init_waitqueue_head(&my_queue) : Dclaration et
bool cancel_delayed_work(struct delayed_work * initialisation spars
work) Annule une tche
dlaye
Sysmic - J. Pouiller Formation au Noyau Linux 136 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 137 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 138 / 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 Wait Queues Les Wait Queues Coherent mapping


Pour attendre un vnement : Gre un mapping cohrent accessible depuis le priphrique et
Attend un vnement sur la queue ET que la condition soit le CPU
vrifie void *dma_alloc_coherent(
void wait_event(queue, condition); Pour rveiller les tches en attentes struct device *dev, /* Device sur lequel est
mapp le DMA. Fourni par le framework */
Idem mais retourne une erreur si excut dans un appel systme Rveil tous les processus en attente sur la queue
size_t size, /* Taille du mapping */
et le processus est tu avec SIGKILL dma_addr_t *handle, /* Adresse physique
wait_up(queue);
int wait_event_killable(queue, condition); fournir au device */
Idem mais, seulement les interruptibles gfp_t gfp) /* Flags habituels */
Idem mais retourne une erreur si excut dans un appel systme
et le processus recoit un signal wait_up_interruptible(queue); dma_alloc_coherent retourne une adresse virtuelle pour
int wait_event_interruptible(queue, condition); accder au mapping par le CPU.
La libration du buffer se fait par :
Idem wait_event mais avec un timeout
void dma_free_coherent(struct device *dev,
void wait_event_timeout(queue, condition); size_t size, void *cpuaddr, dma_handle_t
bus_addr);
wait_event_timeout + wait_event_interruptible :
void wait_event_tinterruptible_timeout(queue,
Sysmic - J. Pouiller Formation au Noyau Linux 139 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 140 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 141 / 182
condition);

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

Streaming mapping Les listes Les listes


Dans ce mode, le driver doit allouer lui-mme la mmoire Implmentation assez singulire de listes gnriques en C. Exemple :
(utilisation de GFP_DMA). utilisation de la macro container_of qui permet de retourner
Il faut configurer le cache du CPU que la zone mmoire puisse un pointeur sur lobjet contenant en connaissant ladresse dun #include <linux/list.h>
tre utilis pour un DMA : attribut et et le type : stuct my_node_t {
struct list_head node;
dma_addr_t dma_map_single(struct device *dev, #define container_of(ptr, type, member) ({ \ /* other attributes */
void *buffer, size_t size, enum const typeof( ((type *)0)->member ) *__mptr = }
dma_data_direction direction); (ptr); \ void f() {
(type *)( (char *)__mptr - offsetof(type, LIST_HEAD(my_list);
direction peut tre DMA_TO_DEVICE, DMA_FROM_DEVICE, member) );})
DMA_BIDIRECTIONAL, DMA_NONE struct my_node_t new_node;
Le cache nest pas cohrent. Pour accder au buffer, il faut Pour dclarer une liste : struct my_node_t *i;
apeller : Dclarer un type pour les noeuds de sa liste 10 printf("%d\n", list_empty(my_list));
Ajouter un attribut de type struct list_head son type list_add(&new_node->node, &my_list);
void dma_unmap_single(struct device *dev, Une liste vide est alors compos dune simple printf("%d\n", list_size(my_list));
dma_addr_t bus_addr, size_t size, enum struct list_head dclarer avec LIST_HEAD(my_var) list_for_each_entry(i, &my_list, node) {
dma_data_direction direction) Pour les fonction dajout, suppression, etc... tout est gr avec }
Cet appel doit tre fait aprs que le priphrique ait termin ces les list_head }
accs au buffer Pour accder au donnes lies un list_head, il faut utiliser la
Le streaming mapping
Sysmic -permet
J. Pouiller des optimisations
Formation au Noyau Linux que cohrent 142 / 182 macro list_entry (qui
Sysmic est en Formation
- J. Pouiller fait laaumme
Noyau Linuxchose que 143 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 144 / 182

mapping ne permet pas container_of)


Rfrence : linux/list.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

Les arbres Les fifo kfifo


Il existe deux implmentations principales darbre dans le noyau
Les rbtree (arbres rouges-noirs) Dclarer et initialiser une kfifo :
Fonctionnent aussi base de container_of mais ncessite Apell aussi Buffer Circulaire
une plus grande part de personnalisation que les listes. DEFINE_KFIFO(fifo, type, size)
Lune des structure les plus utilise dans le noyau
En particulier, ncessite limplmentation des fonction de
Permet la communication avec les interruptions (pas de pause fifo : Nom de la fifo
recherche et dajout.
lors des accs) et entre les processus type : Type des objets contenir
Cette architecture permet de dfinir sa propre fonction de
Pendant longtemps, chaque driver avait son implmentation de size ; Taille de la fifo
comparaison sans impacte sur les performance et en maintenant
fifo
une certaine gnricit Pour pousser, tirer et lire des lments :
Il existait un dbut dinterface commune dans
Rfrences : Documentation/rbtree.txt et int kfifo_put(fifo, val)
linux/circ_buf.h
linux/rbtree.h int kfifo_get(fifo, val)
Il existe maintenant une implmentation de rfrence : kfifo
Les radix priority search tree (arbres prfixes ou prio_tree) int kfifo_peek(fifo, val)
Uniquement utilis pour rfrencer les structures vma
Rfrences : Documentation/prio_tree.txt et
linux/prio_tree.h
Sysmic - J. Pouiller Formation au Noyau Linux 145 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 146 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 147 / 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

kfifo Mutex Mutex


Mthodes assez classiques des mutex :
Dclarer et initialiser un mutex :
Pleins dautres fonctions utiles :
DEFINE_MUTEX(name);
kfifo_recsize(fifo) void mutex_init(struct *mutex);
kfifo_reset(fifo) Prcautions classiques lutilisation des sections critiques :
kfifo_size(fifo)
Acqurir le mutex le plus tard possible, Relcher le plus tt Acqurir le mutex. Attention, si appel depuis un processus,
kfifo_len(fifo)
Etudier la granularit ncessaires aux sections critiques celui-ci ne peut plus tre tu
kfifo_is_full(fifo)
kfifo_is_empty(fifo) Attention aux bug classiques : latences, dead locks, mutex_lock(struct mutex *lock);
inversements de priorits
Il est possible de coupler une kfifo avec wait_queue Idem, mais le processus peut-tre tu
Il est possible de dclarer une kfifo avec un espace mmoire mutex_lock_killable(struct mutex *lock);
dport de la structure et ainsi utiliser des espace mmoire
spciaux. Idem, mais le processus peut tre interrompu avec un signal
mutex_lock_interruptible(struct mutex *lock);

Sysmic - J. Pouiller Formation au Noyau Linux 148 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 149 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 150 / 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

Mutex Autre mcanismes Dsactivation des interruption et de la premption

Idem, mais retourne immdiatement si le mutex est dj lock Dans la mme branche, le noyau propose aussi :
mutex_trylock(struct mutex *lock); Des smaphores (rfrence : linux/semaphore.h) Lors de certains accs, les mcanismes de protections de
Des Read-Write Lock (rfrence : linux/rw_semaphore.h) ressources inter-tches ne sont plus suffisants.
Retourne 1 si le mutex est lock Cela peut concerner des accs concurrent avec des
Mutex avec protocole dhritage de priorits et dtection de dead
mutex_is_locked(struct mutex *lock); lock (aka rt_mutex) (rfrence : interruptions.
Documentation/rt-mutex-design.txt, Il est alors ncessaire de dsactiver temporairement les
Unlock le mutex linux/rtmutex.h) interruptions afin de garantir que lon ne sera pas interrompu.
Les rt_mutex peuvent tre utilis par la libpthread Ces fonctions sont utiliser avec parcimonie
mutex_unlock(struct mutex *lock);
rfrence : Documentation/pi-futex.txt
Documentation/rt-mutex.txt
Rfrence : linux/mutex.h

Sysmic - J. Pouiller Formation au Noyau Linux 151 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 152 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 153 / 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

Dsactivation des interruption et de la premption Dsactivation des interruption et de la premption Spin Lock

Dans certains cas, une tche peut avoir besoin dun accs exclusif
Sauve/restaure ltat des interruptions dans/de flags et dsactive une ressource potentiellement utilise dans une interruption. Dans ce
les interruptions : cas, il est ncessaire de dsactiver les interruptions lors de laccs
local_irq_save(unsigned long flags); Dsactive/Ractive les SoftIrq (bottom halves) : la ressource. Nanmoins, linterruption peut se produire sur un autre
local_irq_restore(unsigned long flags); local_bh_disable(); CPU. Il est alors ncessaire de se protger contre cette ventualit
local_bh_enable(); Il sagit dune attente active sur une section critique
Dsactive/Active les interruptions ( priori, toujours utiliser les
versions _save et _restore) Ne traite pas les problmes de concurrence mais de paralllisme
Dsactive/Ractive la premption uniquement. Par consquent, uniquement en environnement
local_irq_disable(); preempt_disable(); SMP
local_irq_enable(); preempt_enable(); Principalement utilis lors de en complment de la dsactivation
des interruption
Retourne vrai si les interruption du CPU local sont dsactives :
La premption est aussi dsactiv durant un spin lock
local_irq_disabled(); Le noyau propose aussi des read/write spin locks : rwlock_t
Rfrence linux/rwlock.h

Sysmic - J. Pouiller Formation au Noyau Linux 154 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 155 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 156 / 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

Spin Lock Spin Lock Read-Copy-Update (RCU)

Lock et dsactive/ractive les interruptions sur le processeur Type dalgorithme non bloquant :
API :
courant. Les flags contiennent ltat du masque dinterruption :
La lecture nest pas bloquante
Dclarer et initialiser un spin lock :
spin_lock_irqsave(spinlock_t *lock, unsigned On note le nombre de lecteurs
DEFINE_SPINLOCK(lock); long flags);
Les modification seffectuent sur une copie de lobjet
spin_lock_init(spinlock_t *lock); spin_unlock_irqrestore(spinlock_t *lock,
unsigned long flags); Les lecture suivante se font sur la nouvelle version de lobjet
Idem que les fonctions mutex_* : Lorsque le dernier lecteur a termin, lobjet dorigine est dtruit.
Spinlock et dsactive/ractive les SoftIrq : Seul subsiste la nouvelle version.
spin_lock(spinlock_t *lock);
spin_lock_bh(spinlock_t *lock); Les RCU sont un design darchitecture. Les RCU ne possdent
spin_trylock(spinlock_t *lock);
spin_unlock_bh(spinlock_t *lock); que peu dAPI pouvant tre rutilis.
spin_unlock(spinlock_t *lock);
Rfrence Documentation/RCU/whatisRCU.txt
Documentation/RCU/*
Rfrence : linux/spinlock.h

Sysmic - J. Pouiller Formation au Noyau Linux 157 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 158 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 159 / 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

Exemple : Manipulation de listes les barrires mmoire les barrires mmoire


Le compilateur et le CPU peuvent optimiser du code en
rordonnancant les instructions. Utilisation de barrires :
typedef struct {
mmiowb() Empche le rordonnancement des accs en criture
struct a_t a; Le compilateur et le CPU ne rordonnance que les instructions la mmoire mappe sur IO
int count_usage = 0;
bool obsolete = false; indpendantes (donc, a priori, sans danger) rmb() Barrire en lecture. Toutes les lecture demandes avant la
} rcu_t;
rcu_t *a = malloc(sizeof(rcu_t)); Ce comportement peut nanmoins introduire des erreurs sur les barrire sont termine avant rmb() et aucun lecture demandes
systme SMP ou lors daccs certains priphriques. aprs la barrire nest commence avant rmb()
Il est assez complexe de savoir ou doivent se placer les wmb() Barrire en criture
mb() Lecture et criture
barrires. Elle interviennent nanmoins dans un certains nombre
void read_a() { void write_a() { smp_wmb(), smp_rmb() et smp_mb() ont un comportement
// lock: struct rcu_t *a3 = a; de structures de donnes ou dalgorithme identique, mais ne sont prsentent que si le systme est compil
rcu_t *ptr = a; struct rcu_t *a2 = malloc(
ptr->count_usage++; sizeof(rcu_t)); Les barrire sont implmentes en utilisant des instructions en SMP
// do something with ptr;
// unlock:
memcpy(a2, a);
// modify a2;
assembleur particulires Il existe dautre types de barrires trs spcifiques
ptr->count_usage--; a = a2; barrier() est un barrire pour le compilateur. Toutes les Tous les mcanismes de protections de ressources partag
if (ptr->obsolete && !ptr-> a3->obsolete = true;
count_usage) if (!a3->count_usage) instruction avant la barrire seront places avant les instructions contiennent dj des barrires correctement places (ca tombe
free(ptr); free(ptr); aps la barrire bien, cest la que cest le plus complexe)
} }
Toutes les barrires CPU impliquent une barrire compiler. Du Rfrence : Documentation/memory-barriers.txt
coup barrier() est peu utilis.
Sysmic - J. Pouiller Formation au Noyau Linux 160 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 161 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 162 / 182
Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents

printk
31 Afficher des informations
Dynamic printk printk affiche les information sur la console et les copie dans
un buffer. Il est possible dafficher ce buffer avec dmesg
Il est possible dutiliser directemenr printk en specifiant le
Cinquime partie V 32 kgdb
degr dimportance de linformation :

33 Tracker la mmoire printk(KERN_ALERT "Aie\n");

Debuguer 34 Outils base de Kprobe et apparents


Notez labsence de virgule entre KERN_ALERT et la chane
Nanmoins, il est maintenant conseill dutiliser les macros
kprobe pr_cont, pr_develpr_debug, pr_info, pr_notice,
Tracepoint pr_warning, pr_err, pr_crit, pr_alert, pr_emerg
Ftrace Existe aussi suffix de _once pour ntre affich que la premire
fois.
Oprofile
print_hex_dump_bytes et print_hex_dump affichent un
Perf dump en hexadcimal dun buffer. La seconde est la forme
gnrale qui permet de faire peu prs la mme chose que la
commande hexdump
Sysmic - J. Pouiller Formation au Noyau Linux 163 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 164 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 165 / 182

Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents

printk debugfs Debuguer le noyau


printk est compatible avec la norme C99 et ajoute des Activation d kgdb permettant dembarquer gdbserver dans le
extensions pour pretty-printer certains pointeurs (%p). En noyau :
particulier : Un certain nom doutils de debug sont command par debugfs
%pF pour rsoudre le nom dune fonction du segment de text Il sagit dun type de partition virtuel Compilation
%pUB et %pUL pour afficher les UUID ou les GUID Activ avec host$ cp -a build build-dbg
%pM pour afficher des adresses MAC
%pI4 pour affichier des adresses IPv4 host$ make O=build-dbg ARCH=arm CROSS_COMPILE=
mount -t debugfs none /sys/kernel/debug
%pI6 et %pI6c pour afficher des adresses IPv6 arm-linux- menuconfig
Les formats dIP peuvent tre suivit de h, n, l ou b pour demander ... Compile the kernel with debug info ...
Il est possible dobtenir le statut de dprintk avec
des conversions dendian avant dafficher ... KGDB: kernel debugging with remote gdb ...
%m pour errno cat /sys/kernel/debug/dynamic_debug/control host$ make -j3 O=build-dbg ARCH=arm
Rfrence linux/printk.h, CROSS_COMPILE=arm-linux- uImage
Documentation/printk-formats.txt ... et dactiver de nouvelles traces avec
Il est aussi possible de provoquer des dump de la pile avec les Limage ELF est beaucoup plus grosse
macro BUG(), BUG_ON(condition) et BUG_ON_NULL(ptr) echo file hello.c +plf > /sys/kernel/debug/
Les pr_debug ne sont compil que si lune des option dynamic_debug/control host$ ls -l build-dbg/vmlinux build/vmlinux
CONFIG_DEBUG ou CONFIG_DYNAMIC_DEBUG est active host$ cp build-dbg/uImage /srv/tftp/uImage
Dans le cas de DYNAMIC_DEBUG, il est possible dactiver les -2.6.33.7-dbg
messages atomiquement en passant par debugfs
Rfrence : Documentation/dynamic-debug-howto.txt
Sysmic - J. Pouiller Formation au Noyau Linux 166 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 167 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 168 / 182

Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents

Debuguer le noyau Commandes gdb utiles Commandes gdb utiles


Gestion de lexcution Obtenir des informations
Point darrt ladresse 0x9876 Voir la pile dappel
Passage des arguments kgdboc indiquant quel interface kgdb gdb> b *0x9876 gdb> bt
doit utilis et kgdbwait indiquant que kgdb doit attendre notre
connexion avant de continuer le boot b hello.c:30 Point darrt la ligne 30 du fichier hello.c Afficher les variable locales la fonction
uboot> set bootargs ${bootargs} kgdboc=ttyS0 gdb> b hello.c:30 gdb> i locales
kgdbwait
uboot> tftp Point darrt sur la fonction main Afficher les arguments de la fonction
<Ctrl-a q> gdb> b main gdb> i args
host$ arm-linux-gdb vmlinux
gdb> target remote /dev/ttyUSB1 Continuer un programme arrt Afficher la valeur de a
gdb> c gdb> p a
Rfrence : htmldocs/kgdb.html
Dmarrer le programme avec arg comme argument Afficher la valeur de abs(2 * (a - 4))
gdb> r arg gdb> p abs(2 * (a - 4))

Sysmic - J. Pouiller Formation au Noyau Linux 169 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 170 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 171 / 182
Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents

Commandes utiles Commandes utiles Kgdb et les modules


Et plus... Les modules sont charg dynamiquement. Ils ne sont pas
Afficher la valeur de i chaque fois que lon passe sur le point contenu dans le fichier vmlinux
darrt 1 Il est ncessaire dindiquer gdb de charger le module que lon
Debuguer chaud souhaite dbuguer
gdb> command 1
> silent Nanmoins, gdb ne peut pas savoir quel addresse t
Attacher gdb un processus existant charg le module
> p i
gdb> attach 1234 > c Ces informations peuvent tre rcupres dans
> end /sys/modules/*/sections
Arrter le debug sans arrter le processus On peut alors les donner gdb avec add-symbol-file :
Arrter le programme lorsque la variable i est modifie ou lue
gdb> detach target% cat /sys/modules/my_modules/sections
gdb> watch i host$ gdb vmlinux
gdb> awatch i > target remote 192.168.1.55:2345
> add-symbol-file my_modules.ko 0xd0832000 \
Passer dune thread une autre -s .bss 0xd0837100 -s .data 0xd0836be0
gdb> thread 2
gdb> thread 1 Il existe des scripts effectuant la procdure automatiquement. A
adapter suivant vos besoins.
Sysmic - J. Pouiller Formation au Noyau Linux 172 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 173 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 174 / 182

Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents

kmemleak kmemcheck Kprobe


Dun point de vue gnrique, Les Kprobes permettent de deffectuer
une action lors du passage de lexcution dune case mmoire
Active un algorithme proche dun garbage collector. Mais au lieu particulire (Rfrence : Documentation/kprobes.txt)
de librer la mmoire, enregistre simplement les blocs perdus.
Modifie la MMU de manire ce quune exception soit dclenche Dans la partie userspace, il existe une api davoir des informations
Le rsultat se trouve dans /sys/kernel/debug/kmemleak
chaque accs la mmoire. Lors quun accs en lecture est effectu, statistique sur le passage sur une ligne. Il suffit dindiquer une
La procdure classique : adresse (ou un symbole) prober :
kmemcheck vrifie si loctet dj t crit auparavent. Si ca nest
target% echo clear > /sys/kernel/debug/kmemleak pas le cas, une erreur du mme type quun Oops est gnre echo p do_fork > /sys/kernel/debug/tracing/
target% modprobe my_module kprobe_events
... (Pas disponible sur ARM)
target% modprobe -r my_module ... et de lactiver
target% echo scan > /sys/kernel/debug/kmemleak Rfrence : Documentation/kmemcheck.txt
echo 1 > /sys/kernel/debug/tracing/events/kprobes/
target% cat /sys/kernel/debug/kmemleak p_do_fork_0/enable
Rfrence : Documentation/kmemleak.txt On peut maintenant lire les rsultats dans :
cat /sys/kernel/debug/tracing/trace

Sysmic - J. Pouiller Formation au Noyau Linux 175 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 176 / 182
Rfrence : Documentation/trace/kprobetrace.txt
Sysmic - J. Pouiller Formation au Noyau Linux 177 / 182

Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents

Tracepoint ftrace oprofile


Les tracepoints sont des endroit spcifi dans le code du noyau qui
peuvent sembler intressant mesurer :
Pas de possibilit de les dclarer nimporte ou dans le code
Permet dobtenir plus dinformations que les kprobes Permet dinstrumenter certaines latence particulire. Il utilise loption
Les dveloppeur du noyau ont estim que lendroit tait pour y -pg de gcc. Cela ajoute un appel _mcount avant chaque appel de
mettre un tracepoint et ont configur le format adquate (cf. fonction. Contrairement kprobe, ftrace ne peut se placer quau Les CPU modernes possdent des registres de debugs et
/sys/kernel/debug/tracing/events/*/format) dbut dune fonction. breakpoints hardware capable de profiler le code. Oprofile permet de
Loverhead pour un tracepoint dsactiv est un poil plus paramtrer et de visualiser le contenu de ces registres. Oprofile nest
important que pour les kprobe vu quil ny a pas de patch la Nanmoins, ftrace est trs utilis dans le temps rel, la mesure des disponible que sur certaines architectures.
vole du code (mais du coup lusage est permit en XIP) temps de latence et ltude du scheduling.

Pour en obtenir la liste des tracepoints : Reference : Documentation/trace/ftrace.txt


find /sys/kernel/debug/tracing/events/ -type d Documentation/trace/ftrace-design.txt

Il est videment possible de de dfinir ses propres tracepoints (cf.


Documentaiton/trace/tracepoints.txt)

Rfrence : Documentation/trace/events.txt
Sysmic - J. Pouiller Formation au Noyau Linux 178 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 179 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 180 / 182
Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents Afficher des informations kgdb Tracker la mmoire Outils base de Kprobe et apparents

perf SystemTap

Permet daccder quasiment toutes les technologies prcdentes.


Compiler en natif, ce qui permet dtre trs rapide... Ncessite une
perf vous offre une interface pour accder : formation lui-seul.
aux tracepoint
Le principe :
aux kprobe
aux registres de debug hardware et au breakpoints hardware On crit du pseudo-code C
Il est converti en un modules C
Ainsi, perf offre une interface plus complte que oprofile (et
disponibles sur plus darchitecture) Il est compil, puis charg sur le noyau de la cible
Le rsultats est rcupr par un service appel relayfs
(perf ne compile pas sur notre carte de test car notre toolchain est un
peu trop vieille pour le noyau 3.3 (et jai la flemme de la recompiler)) Rfrence : systemtap-doc

Pour une vue globale est diffrents outils dinstrumentation :


Documentation/trace/tracepoint-analysis.txt

Sysmic - J. Pouiller Formation au Noyau Linux 181 / 182 Sysmic - J. Pouiller Formation au Noyau Linux 182 / 182

Вам также может понравиться