English/Français
Cette page est une traduction de la page en version anglaise. Il se peut qu'elle ne soit pas à jour. Au besoin, comparez les deux dates de dernières éditions et le ChangeLog
Memory Mapped I/O Trace
Mmiotrace est une boite à outils permettant de tracer les accès mémoire Input/Ouput dans le kernel. Elle peut être utilisée afin d'enregistrer comment un module driver utilise les lectures et écritures MMIO pour du reverse engineering et de debuggage.
x86 et x86_64 sont les deux architectures supportées, leur support semble assez stable. Si vous obtenez un crash, vérifiez s'il n'y a pas des informations dans vos log et contactez PekkaPaalanen par email ou sur le salon de discussion IRC #mmio-trace sur Freenode. Les anciennces notes de débuggage sont dans la page MmioTraceDebugging (en).
Fonctionnalités
- horodatage des évènements
- un mécanisme pour injecter des marqueurs dans les logs pendant la réalisation des traces
- aucun patch kernel nécessaire
- collecte les bloques de lecture/écritures dans in mmio-parse
- utilise une resgistre de noms (Rules-ng)
Le format moderne d'un log mmiotrace est décrit dans la page MmioTraceLogFormat (en)
1. Instructions specifiques suivant les versions du kernel Linux
Le dernier kernel (ou au minimum le 2.6.28) est le kernel, si vous pouvez choisir. L'instalation est les instructions d'utilisation dépendent de la version du kernel.
Ces notes suivants la version du kernel sont pour les personnes réalisant des dumps mmiotrace. Les personnes analysant ces dumps préfère utiliser la version "out-of-tree" car elle dispose plusieurs outils d'analyses très utiles.
1.1. 2.6.27 et plus ancien
Mmiotrace est dans le kernel, pas besoin de récupérer et de patcher quoique ce soit. Pensez à lire les instructions dans le fichier Documentation/tracers/mmiotrace.txt ou Documentation/trace/mmiotrace.txt dans les codes sources de votre kernel. Aucun programme spécifque n'est nécessaire pour enregistrer les sortie. Pour les règles de soumission, voir la section "Envoi des résultats" de la page MmioTraceHowto-fr (fr) (ou plus à jour la page en VO.
- 2.6.29
- Corrections suite à des crashes. Si vous aviez des soucis pour obtenir uen trace à cause d'un "gel" du système, ceci devrait être corrigé actuellement
- 2.6.28
- ajout du support de marqueur, Correction du bug sur l'écriture en 8 bit.
- 2.6.27
- The first kernel carrying mmiotrace. Aucun support de marqueur. Contient un bug lié à l'écriture sur 8 bits.
1.2. 2.6.25
Mmiotrace doit être patché dansle kernel, voirs MmioTrace2_6_25. Le kernel 2.6.26 n'est pas supporté, mais le même patch peut probablement être adapté.
1.3. 2.6.24
Le kernel 2.6.24 a besoin d'un patch, après quoi vous pouvez utiliser la version non officielle de mmiotrace. 0001-x86-Add-a-list-for-custom-page-fault-handlers.patch.txt. Activez CONFIG_PAGE_FAULT_HANDLERS. Puis suivre MmioTraceHowto-fr (en)
1.4. 2.6.19 to 2.6.23
Utilisez out-of-tree mmiotrace, voir MmioTraceHowto-fr.
Le hooks pour notifier les défauts de pages requis par le mmiotrace sans patch kernel a été introduit dans l'arbre du kernel de Linus dans la version 2.6.19-rc1, commit 474c256841074b913e76e392082373e12103a75d and 273819a2d982faace30e587b86a0683882251fe7.
2. Comment mmiotrace fonctionne
Les fonctions du noyau ioremap, ioremap_nocache et iounmap sont remplacées (pour le module uniquement) avec des ajouts pour enregistrer les zones MMIO. Dans ioremap les pages des zones MMIO sont marqués manquantes, ce qui implique qu'un accès à ces adresses provoque un défaut de page. Dans la gestion du défaut de page, les adresses MMIO tracées sont détectées et l'action tentée est enregistrée. La page est marquée présente et le code de défaut de page est réalisé d'un coup pour exécuter l'instruction qui réalise un MMIO. Ensuite, la page est à nouveau marquée absente.
L'enregistrement fonctionne par l'appel de pre et post fonctions dans mmio.ko avant et après l'exécution de l'instruction. mmio.ko utilise relayfs et debugfs pour relayer la donnée vers l'espace utilisateur.
Malheureusement la plage mémoire 0xa0000 - 0x100000 hérité de l'ISA ne peut être tracée de cette manière, car marquer ces pages comme absentes plante le noyau. Il peut également y avoir des instructions machines qui ne sont pas bien décodées, mais jusqu'ici elles ont été assez rare.
3. Une idée pour une alternative
En discutant sur l'émulation des instructions x86, Avi Kivity proposa ce qui suit (traduction de la citation) :
Quoiqu'il en soit, il y a une solution plus simple (pour vous) : exécuter le driver-a-être-reverse-engineered dans un invité kvm et modifier l'espace utilisateur kvm pour logguer les accès à des régions mmio. Ceci requiert le support 'passthrought PCI' qui n'a pas encore été fusionné. Vous pouvez faire de l'ingénierie inverse sur les drivers Windows de cette manière
Réference : http://lkml.org/lkml/2008/4/5/13
Qui souhaite prendre le projet ?
4. Out-of-tree mmiotrace et outils d'analyse
Les sources principales de mmio-trace, en dehors de l'arbre du kernel est l'arbre git de pq (PekkaPaalanen) : git://people.freedesktop.org/~pq/mmio-trace (browse)
Il y a deux branches : master et binformat. Utilisez la branche master si vous pouvez, et binformat seulement si vous le devez absolument. binformat est plutôt pour les gens qui souhaite analyser/parser les anciens logs binaires mmio. Une description plus approfondie des différentes branches suit plus loin
out-of-kernel-tree mmio-trace consiste en :
un module kernel pour analyser les accès MMIO, mmio.ko (obsolète)
un programme 'utilisateur' pour enregister les logs, mmio-trace (deprecatobsolèteed)
un programme 'utilisateur' pour interpréter les logs, mmio-parse
un programme 'utilisateur' pour re-executer les logs, mmio-replay
un programme 'utilisateur' pour convertir entre différents formats de logs, mmio-convert
un programme 'utilisateur' pour pour valider les sorties testmmiotrace.ko, test-check
module kernel pour tester mmiotrace, testmmiotrace.ko
En plus, le module du driver analysé doit avoir certains symboles qu'il appelle depuis le kernel , il y a un script pout réaliser ceci.
Les options CONFIG_DEBUG_FS et CONFIG_RELAY kernel doivent être activée dans votre kernel
Ancienne discussion RFC mmiotrace full patch, preview 1, RFC mmiotrace full patch, preview 2, RFC 1/3 mmiotrace full patch, preview 3 http://lkml.org/lkml/2008/3/22/70
4.1. Branche ''master'' de pq
Comparée aux plus vieilles versions, cette branche contient des format repensés pour les communications en espace noyau et utilisateur via relayfs et pour les logs sur le disque. Ceux-ci sont complètement incompatibles avec les anciennes versions.
Le format de log est basé sur du texte, il est donc lisible sans outil particulier, et annule certaines incompatibilités entre les architectures. Les bénéfices de la réécriture du format de données du noyau sont les messages de taille variable depuis l'espace noyau vers l'espace utilisateur, et l'enregistrement des vraies adresses physiques des opérations mémoire.
Fonctionnalités additionnelles :
- Enregistre l'adresse physique correcte des évènements.
Sauvegarde la sortie de lspci et l'informations contenue dans /proc/bus/pci/devices, cette dernière est utilisée pour convertir les adresses physiques en des décalages utilisables avec Rules-ng.
mmio-parse sur chaque architecture peut parser des logs provenant d'une autre architecture.
mmio-replay permet de rejouer des écritures de registres depuis les logs. C'est danagereux
Cette branche contient une version de mmio-convert écrite par jwstolk. Cet outil peut convertir les dumps d'un format à l'autre, mais les résultats ne sont pas toujours très précis. Si vous avez un vieux dump que vous ne pouvez pas reproduire, jetez un oeil sur mmio-convert.
4.2. Branche ''binformat'' de pq
Ici vit l'ancienne version de mmio-trace qui utilise le format de log binaire. Il n'y a pas de nouveaux développements ici, mais elle est maintenue pour les gens qui, pour une raison ou pour une autre, ne peuvent pas utiliser la branche master.
4.3. Arbre Git de jrmuizel
Les anciennes sources, sur l'arbre Git de jrmuizel : git://people.freedesktop.org/~jrmuizel/mmio-trace (gitweb), ne sont plus activement développées.
jrmuizel est celui qui a ressuscité mmio-trace et l'a apporté à Nouveau lorsque les développeurs n'avaient pas de solution pour étudier ce que faisait le blob de nvidia dans le noyau.
L'arbre Git de pq est un fork de la branche master de jrmuizel tel qu'elle était au 24 aout 2007.
5. Notes d'utilisation (version en dehors de l'arbre du kernel)
Vous pouvez injecter des marqueurs (lignes de texte) dans les logs de trace par un echo 'X is running' > /proc/mmio-marker.
- Seul un processeur actif est supporté, ne pas l'utiliser sur un système multiprocesseur. Vous pouvez désactiver les processeurs/core supplémentaies au moment du boot avec un argument kernel ou à chaud via une entrée sysFS
Ne pas redémarrer ./mmio-trace car il reprendra d'abord les vieilles données depuis les tampons du noyau. Vous devez décharger et recharger mmio.ko avant de redémarrer ./mmio-trace pour nettoyer les tampons du noyau.
Après le traçage, vérifiez dans vos logs noyau qu'il n'y ait pas d'erreurs de cpu 0 buffer full!!!. Si vous en avez, il y a des chances que des évènements aient été perdus. Vous pouvez refaire la trace avec un buffer de relais plus gros. La taille du buffer de relais est controllée par le paramètre n_subbufs du module kernel mmio. LA valeur par défaut est 128 et indique le nombre de block de 256kB réservés pour le buffer, donc 128 signifie 32MB. Augmentez le nombre, jusqu'à ce que n'obteniez plus le message de "buffer plein".
Trace pour les plages basses ISA, expérimental : appliquez 0001-ioremap-do-not-handle-the-low-ISA-range-specially.patch sur votre kernel ainsi que insmod mmio.ko ISA_trace=1 et avertissez PekkaPaalanen sur ce qui arrive. Si vous ne patchez pas votre kernel votre machine crashera, si le blob ne correspond à la plage ISA. Ceci est une fonction non testée.
Ancien driver Nvidia avec 2.6.25 - Pour build the nvidia driver with 2.6.25 vous aurez besoin des patches de nvnews, http://www.nvnews.net/vbulletin/showthread.php?t=110088.
Another thing is that you will probably see messages like NVRM: bad caching on address XXXXXXX: actual 0x173 != expected 0x17b in dmesg. This didn't happen with 2.6.25-rc6 but it now exists in 2.6.25-rc7 because of commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d546b67a940eb42a99f56b86c5cd8d47c8348c2a.
6. Connexion à Rules-ng
Rules-ng (CVS) est la définition d'une base de donnée qui décrit les registres matériels et un ensemble d'outils pour utiliser la base de données. Un des outils est staticdb. mmio-parse gère les greffons staticdb.
Staticdb est une base de données Rules-ng convertie en code C et compilée dans une biliothèque partagée. Elle permet de convertir les adresses brutes en noms de registres symboliques, de parcourir les registres indexés, et de convertir les valeurs des registres dans des formats plus conviviaux. Pour l'utiliser, vous devez récupérer Rules-ng depuis le CVS, et lancer make dans le répertoire staticdb/ pour obtenir bibliothèque de base de données. La bibliothèque est utilisée par les commandes ./mmio-parse -m NN -s path/to/libnvidia-mmio.so où NN est votre type de carte (variante dans les termes de Rule-ng).
7. À faire et suggestions
- Support des pages larges
- Compléter le support des instructions : se débarrasser des "unknown type" --- ou refactoriser les instruction de décodage KVM puis les fusionner ici (Argh!)
- Support d'un accès au traçage depuis l'espace utilisateur.
- filtrage des évènement basé sur le device et BAR, peut-être plage d'adresse
- changer le format du log
- backtraces
- identification du CPU
- Support PPC ?
- Réfléchir sur comment tracer la zone ISA ; David suggère de decommenter les contrôle sur la région ISA dans arch/i386/mm/ioremap.c devrait être suffisant pour activer les traces des plages ISA. Est ce réellement tout ? Ceci casse-t-il quelque chose
Améliorer mmio-parse.
- (Sortir les files de trace pour remplacer le collecteur de données Renouveau (nécessite le traçage des adresses en espace utilisateur).)
- Rendre la pagination depuis les ressources PCI vers les greffons staticdb configurable (actuellement codé en dur pour Nvidia BAR 0).