No description
Find a file
2024-01-23 20:17:37 +01:00
task_01 fix typo and move folders with a better name 2024-01-04 20:49:18 +01:00
task_05 05 fix typo 2024-01-23 20:17:37 +01:00
task_06 fix typo and move folders with a better name 2024-01-04 20:49:18 +01:00
task_08 indent and checker 2024-01-11 19:55:48 +01:00
task_09 add task 9 2024-01-23 20:08:20 +01:00
.gitignore refactor code with linux convention 2023-01-23 19:21:45 +01:00
check.sh add basic script to check convention and auto indent 2023-01-30 02:04:35 +01:00
LICENSE add license 2023-01-23 19:21:45 +01:00
README.md add task 9 2024-01-23 20:08:20 +01:00

Eudyptula Challenge

Le challenge étant fermé, je m'appuie sur les questions trouvables sur des dépôts Github.

Vous pouvez trouver des réponses (ainsi que des questions) sur Github. Je rajouterai peut-être la liste des questions plus tard, afin de vous épargner quelques clics.

À noter que j'utilise la commande indent -linux pour pouvoir indenter et formater les fichiers sources selon la convention du kernel Linux. J'utilise aussi le script checkpatch.pl -f pour pouvoir vérifier plus en profondeur si mes fichiers sources suivent bien la convention (cf. tâche 4).

Compilation

La version utilisée et testée a varié durant la réalisation de ce challenge. Voici la liste des challenges et de la version de Linux utilisée. À noter que je n'ai pas prit le temps de tester ces challenges sur d'autres versions.

  • tâches 1 à 7: 6.1.1, GCC 12
  • tâches 8 à ... : 6.6.6, GCC 13

Il vous faut les fichiers d'en-têtes du kernel Linux (linux-headers sur les distributions basées Debian et apt pilulé).

Il suffit ensuite d'aller dans le dossier de votre choix et faire make. Parfois, d'autres commandes sont nécessaires. Lisez la partie réponse pour avoir ces dernières.

Réponses

L'Eudyptula challenge demande souvent des preuves de notre réussite. Vous pouvez retrouver les commandes et leur résultat ici. Si une tâche n'est pas indiquée, cela veut surement dire qu'elle n'est pas assez intéressante ou trop triviale (cf. tâche 7).

Tâche 1

Pour montrer que mon module marche bien, on regarde les logs du kernel avec la commande dmesg.

# après insmod hello.ko
[102102.117958] Coucou le gens !!!!
# après rmmod hello
[102108.046104] Tschuss !!!

Tâche 2

J'utilise Gentoo et configure puis compile moi-même mon kernel. Je passe cette étape.

Tâche 3

Patch basé sur la version v6.2-rc5 du kernel Linux, créé avec la commande git format-patch -1 HEAD.

From 6f41b705dbde5b42167c03b8d14ae695b226cb86 Mon Sep 17 00:00:00 2001
From: rick <rick@gnous.eu>
Date: Mon, 23 Jan 2023 16:49:42 +0100
Subject: [PATCH] custom extraversion

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index c1ead4cd2342..d67f2f5eb831 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 6
 PATCHLEVEL = 2
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -eudyptula
 NAME = Hurr durr I'ma ninja sloth
 
 # *DOCUMENTATION*
-- 
2.39.1

Tâche 4

Je n'ai pas mis les fichiers corrigés. Il suffit d'utiliser la commande indent pour pouvoir bien indenter le code dans un premier temps. Il faut ensuite utiliser le script scripts/checkpatch.pl sur les fichiers pour trouver les derniers soucis.

Tâche 5

Il faut dans un premier temps générer l'alias du module. Cela va permettre de lier les périphériques disponibles pour le module avec.

2 façons:

  • depmod $(uname -r) $(pwd)/task_5/my-usb-detect.ko en étant à la racine du dépôt git. Cela va cependant réécrire le fichier /lib/modules/$(uname -r)/modules.alias, ce qui peut casser votre installation Linux. Faites un backup de votre dossier avant.
  • cp task_5/my-usb-detect.ko /lib/modules/$(uname -r)/ && depmod -A

La deuxième méthode est la plus recommandée. Je l'ai trouvé après avoir écrit le module sans réussir à le charger. Le blog de Nihaal explique de manière détaillée le fonctionnement des modules et de la détection de périphériques.

# on branche le clavier
[ 6712.426017 ] usb 2-3: new full-speed USB device number 4 using xhci_hcd
[ 6712.569813 ] usb 2-3: New USB device found, idVendor=046d, idProduct=c52b, bcdDevice=24.01
[ 6712.569826 ] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 6712.569830 ] usb 2-3: Product: USB Receiver
[ 6712.569833 ] usb 2-3: Manufacturer: Logitech
[ 6712.575345 ] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:14.0/usb2/2-3/2-3:1.0/0003:046D:C52B.0007/input/input32
[ 6712.629923 ] hid-generic 0003:046D:C52B.0007: input,hidraw0: USB HID v1.11 Keyboard [Logitech USB Receiver] on usb-0000:00:14.0-3/input0
[ 6712.634279 ] input: Logitech USB Receiver Mouse as /devices/pci0000:00/0000:00:14.0/usb2/2-3/2-3:1.1/0003:046D:C52B.0008/input/input33
[ 6712.634743 ] input: Logitech USB Receiver Consumer Control as /devices/pci0000:00/0000:00:14.0/usb2/2-3/2-3:1.1/0003:046D:C52B.0008/input/input34
[ 6712.689561 ] input: Logitech USB Receiver System Control as /devices/pci0000:00/0000:00:14.0/usb2/2-3/2-3:1.1/0003:046D:C52B.0008/input/input35
[ 6712.689844 ] hid-generic 0003:046D:C52B.0008: input,hiddev96,hidraw1: USB HID v1.11 Mouse [Logitech USB Receiver] on usb-0000:00:14.0-3/input1
[ 6712.693283 ] hid-generic 0003:046D:C52B.0009: hiddev97,hidraw2: USB HID v1.11 Device [Logitech USB Receiver] on usb-0000:00:14.0-3/input2
# notre module s'est chargé tout seul !!
[ 6713.143767 ] Coucou le gens !!!!
[ 6713.259818 ] elogind-daemon[3774]: Watching system buttons on /dev/input/event18 (Logitech USB Receiver Consumer Control)
[ 6713.260009 ] elogind-daemon[3774]: Watching system buttons on /dev/input/event19 (Logitech USB Receiver System Control)
[ 6713.663077 ] elogind-daemon[3774]: Watching system buttons on /dev/input/event16 (Logitech USB Receiver)
# le clavier est débranché et notre module n'est pas déchargé.
[ 6716.982578 ] usb 2-3: USB disconnect, device number 4

Il faut le décharger à la main avec rmmod.

Tâche 6

Il existe plusieurs façons pour créer un nouveau fichier dans /dev. J'ai cependant décidé d'implémenter qu'une seule manière pour l'instant.

Pour pouvoir créer un fichier dans /dev, il faut créer le périphérique à la main. Il faut connaitre le numéro majeur du driver, ce qui se fait ou en regardant dans le fichier /proc/devices ou en regardant le journal du kernel. Il suffit de taper la commande suivante pour créer le fichier : mknod /dev/eudyptula c <majeur> 0. N'oubliez pas de changer les droits si vous souhaitez écrire dedans !

Je n'ai pas suivi les consignes à la lettre, en effet je n'utilise pas un misc char device mais un char device. C'est pour ça qu'il faut créer à la main le device. Je l'ai codé directement comme ça, ne trouvant pas beaucoup d'informations sur les misc char devices. En lisant des codes sources ainsi que la documentation, je comprends mieux comment en faire, mais j'ai décidé de ne pas changer tout le code que j'avais fait. Cepebdant, je le modifierai si l'on doit faire un char device plus tard.

Lorsqu'on ouvre le device, on reçoit la chaine coucou c'est rick. Si l'on souhaite écrire dans le fichier, il faut taper congruent, sinon un message d'erreur est retourné.

cat /dev/eudyptula
# coucou c'est rick
echo "congruent" > /dev/eudyptula
# aucune réponse, $? vaut 0
echo "bonjour12" > /dev/eudyptula
# -bash: echo: erreur d'écriture : Argument invalide
# $? vaut 1

Tache 8

L'ajout d'une nouvelle string dans le fichier ne supprime l'entièreté du contenu du fichier. J'ai testé les sémaphores avec des msleep (<linux/delay.h>) rajouté dans le code. Il est possible de tester en décommentant le premier define.

ls -l /sys/kernel/debug/eudyptula/
# total 0
# -rw-rw-r-- 1 root root 0 Jan  9 22:46 foo
# -rw-rw-rw- 1 root root 0 Jan  9 22:44 id
# -r--r--r-- 1 root root 0 Jan  9 22:45 jiffies
echo pouet > /sys/kernel/debug/eudyptula/foo
cat /sys/kernel/debug/eudyptula/foo
# pouet
echo coucou ! > /sys/kernel/debug/eudyptula/foo
cat /sys/kernel/debug/eudyptula/foo
# coucou !
cat /sys/kernel/debug/eudyptula/id
# pouetpouet
echo congruent > /sys/kernel/debug/eudyptula/id
echo $?
# 0
echo pouet > /sys/kernel/debug/eudyptula/id
# bash: echo: write error: Invalid argument
echo $?
# 1
echo pouet > /sys/kernel/debug/eudyptula/jiffies
# bash: echo: write error: Permission denied
cat /sys/kernel/debug/eudyptula/jiffies
# 4345895105
cat /sys/kernel/debug/eudyptula/jiffies
# 4345895338
echo pouet > /sys/kernel/debug/eudyptula/foo &
cat /sys/kernel/debug/eudyptula/foo
# cat: /sys/kernel/debug/eudyptula/foo: Invalid argument
cat /sys/kernel/debug/eudyptula/foo &
cat /sys/kernel/debug/eudyptula/foo &
echo pouet > /sys/kernel/debug/eudyptula/foo
# bash: echo: write error: Invalid argument
rmmod hello
ls -l /sys/kernel/debug/eudyptula/
# ls: cannot access '/sys/kernel/debug/eudyptula/': No such file or directory

Tache 9

Idem que la tache 8 pour tester les sémaphores.

ls -l /sys/eudyptula/
# total 0
# -rw-r--r-- 1 root root 4096 Jan 23 18:42 foo
# -rw-rw-rw- 1 root root 4096 Jan 23 18:42 id
# -r--r--r-- 1 root root 4096 Jan 23 18:42 jiffies
echo pouet > /sys/eudyptula/foo
cat /sys/eudyptula/foo
# pouet
echo coucou ! > /sys/eudyptula/foo
cat /sys/eudyptula/foo
# coucou !
cat /sys/eudyptula/id
# pouetpouet
echo -n congruent > /sys/eudyptula/id
echo $?
# 0
echo pouet > /sys/eudyptula/id
# bash: echo: write error: Invalid argument
echo $?
# 1
echo pouet > /sys/eudyptula/jiffies
# bash: /sys/eudyptula/jiffies: Permission denied
cat /sys/eudyptula/jiffies
# 4344413015
cat /sys/eudyptula/jiffies
# 4344413465
echo pouet > /sys/eudyptula/foo &
cat /sys/eudyptula/foo
# cat: /sys/eudyptula/foo: Invalid argument
cat /sys/eudyptula/foo &
cat /sys/eudyptula/foo &
echo pouet > /sys/eudyptula/foo
# bash: echo: write error: Invalid argument
rmmod sysfs
ls -l /sys/eudyptula/
# ls: cannot access '/sys/eudyptula/': No such file or directory

Informations diverses

Je liste dans cette section quelques informations que j'ai pu découvrir en lisant des ressources histoire de pouvoir les retrouver rapidement dans le futur.

/proc

  • devices : On peut retrouver la liste des drivers avec leur numéro majeur, le tout découpé entre les character devices et les block devices.

Les devices

  • character devices: on ne lit qu'un caractère dans ce type de device, c'est comme ça que fonctionne un clavier par exemple
  • block devices: on va lire le device uniquement par "block" (char * ou char[]), le disque dur par exemple