Article HowTo pour développer des pilotes de périphériques Linux embarqués en tant que modules de noyau. Tout le contenu de cet article peut être exécuté sur Raspberry Pi.
Je pense que la première étape du développement de Linux Devadler est difficile. Il y a peu de matériaux, et je pense que la plupart des gens seront frustrés en touchant le livre O'Reilly. (J'étais ...)
Dans cet article, je vais procéder selon le contenu de "Programmation du pilote de périphérique Linux (Yutaka Hirata)". Je pense que ce livre est très facile à comprendre et bon. Cependant, comme il a été publié en 2008 et qu'il est ancien, je vais le vérifier tout en l'exécutant sur le Raspberry Pi afin qu'il fonctionne dans l'environnement actuel (décembre 2017). (À partir du milieu, il sera séparé du contenu du livre)
Aussi, je voulais le rendre aussi simple que possible, donc je ne préparerai pas d'environnement de développement croisé et développerai avec Raspeye lui-même. Par conséquent, quel que soit le système d'exploitation hôte, ceux qui ont une tarte aux râpes peuvent l'essayer immédiatement. (Nous recommandons le style de développement du codage sur un PC hôte tel que Windows et de le transférer vers Raspeye par SFTP)
--__ 1ère fois: Préparation de l'environnement de construction et création d'un module de noyau simple <-------------- ------- Contenu de cette fois __
Tout d'abord, préparons l'environnement et créons un module de noyau simple.
https://github.com/take-iwiw/DeviceDriverLesson/tree/master/01_01 https://github.com/take-iwiw/DeviceDriverLesson/tree/master/01_02
Comme mentionné au début, nous allons développer sur Raspeye. Autrement dit, construit dans l'environnement natif. Par conséquent, en gros, vous pouvez utiliser gcc etc. sur la tarte à la râpe telle quelle, vous ne devriez donc pas avoir besoin de préparation. Cependant, des en-têtes, etc. sont nécessaires pour accéder aux fonctions du noyau. Installez avec la commande suivante. Cela installera l'en-tête complet et le Makefile pour la construction ici (/ usr / src / linux-headers-4.9.41-v7 + /
). De plus, un lien symbolique vers ici sera créé ici (/ lib / modules / 4.9.41-v7 + / build
). (Ce répertoire est pour mon environnement)
sudo apt-get install raspberrypi-kernel-headers
C'est tout ce qu'il y a à faire, car il ne construit pas tout le noyau.
Tout d'abord, écrivons uniquement le comportement lorsque le module du noyau est chargé (insmod) et déchargé (rmmod). C'est comme Hello World. Nommez le fichier test.c. Spécifiez le point d'entrée pour insmod avec module_init
et le point d'entrée pour rmmod avec module_exit
. Puisque printf ne peut pas être utilisé dans le noyau, printk est utilisé.
test.c
#include <linux/module.h>
static int test_init(void)
{
printk("Hello my module\n");
return 0;
}
static void test_exit(void)
{
printk("Bye bye my module\n");
}
module_init(test_init);
module_exit(test_exit);
Je pense que vous pouvez créer le module du noyau en tapant vous-même la commande gcc, mais il est difficile de spécifier le chemin d'inclusion de différentes manières. Comme mentionné ci-dessus, le Makefile pour la construction est préparé, alors utilisez-le. Créez un Makefile comme celui ci-dessous, définissez le nom du fichier source et appelez le Makefile dans / lib / modules / 4.9.41-v7 + / build
. En fait, la partie de 4.9.41-v7 + change en fonction de l'environnement, alors obtenez-la avec la commande ʻuname`.
Makefile
obj-m := test.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
Dans le répertoire contenant test.c et Makefile ci-dessus, make
. Ensuite, test.ko doit être terminé. Après cela, essayez de charger le module avec ʻinsmodet de décharger le module avec
rmmod`.
make
sudo insmod test.ko
sudo rmmod test.ko
dmesg
Enfin, jetons un œil au résultat obtenu par printk avec dmesg. Ensuite, vous pouvez voir que le code implémenté est en cours d'exécution comme indiqué ci-dessous.
[ 2324.171986] Hello my module
[ 2327.753108] Bye bye my module
S'il n'y a pas de \ n
lors de l'exécution de printk, il ne semble pas être sorti dans le journal dmesg. Apparemment, il sort dans le tampon pour dmesg au moment de \ n
.
printk imprime son contenu dans un tampon en mémoire au lieu du terminal. Le tampon ressemble à un tampon en anneau et sera écrasé. dmesg imprime simplement ce tampon. Il est enregistré sous forme de fichier dans cat / var / log / syslog
. Cependant, veuillez noter qu'il semble qu'il soit écrit à une fréquence raisonnable plutôt que d'être écrit immédiatement dans ce fichier. En cas de plantage, il est possible que le journal souhaité n'ait pas été écrit.
Voici un exemple de création de MyModule.ko à partir de test01.c et test02.c. Créez un Makefile comme celui ci-dessous. Le fichier .o requis pour générer MyModule.o
est spécifié dans MyModule-objs
. Par conséquent, le préfixe de «MyModule-objs» doit être «MyModule». Le module résultant peut être chargé avec sudo insmod MyModule.ko
.
CFILES = test01.c test02.c
obj-m := MyModule.o
MyModule-objs := $(CFILES:.c=.o)
all:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
Avec ce sentiment, je vais le résumer petit à petit. Ceci est mon mémo d'étude. Si vous écrivez quelque chose de mal, faites le moi savoir
Recommended Posts