Récupérer, explorer et configurer les sources du noyau Linux

Apprentissage du Dev Linux en Kernel Mode

Moderator: Rick

Post Reply
Hydraxx
Site Admin
Posts: 148
Joined: Mon Jan 12, 2026 4:04 pm
Location: France
Contact:

Récupérer, explorer et configurer les sources du noyau Linux

Post by Hydraxx »

Récupérer, explorer et configurer les sources du noyau Linux

1. Introduction

Cette deuxième partie explique comment récupérer les sources du noyau Linux, comprendre leur organisation et préparer une configuration personnalisée.

Le laboratoire choisi est Ubuntu dans une machine virtuelle Hyper-V. Nous utiliserons GNU Make, Kbuild, Kconfig et les utilitaires de configuration fournis avec le noyau Linux.

Ce cours suppose que le langage C est connu. Il poursuit les exercices de la partie précédente sur les modules, sans imposer de recompiler ni de remplacer immédiatement le noyau exécuté.

Chaque notion s'appuie sur un exemple, l'explication de son utilité et une méthode pour vérifier le résultat. Les exemples sont adaptés aux versions modernes du noyau ; les noms de menus peuvent varier selon la version des sources.

Pour des raisons de sécurité, on expérimente dans une VM avec point de contrôle Hyper-V et copie séparée des fichiers importants. Cette partie ne change ni GRUB ni le noyau de démarrage : la construction complète et l'installation seront abordées dans la partie suivante.

Sommaire des thèmes
  • Comprendre les versions mainline, stable, LTS et les branches de développement.
  • Récupérer les sources sur kernel.org ou avec Git.
  • Explorer les répertoires arch, drivers, kernel, fs, mm et include.
  • Lire les fichiers Makefile, Kconfig et .config.
  • Comprendre CONFIG_, obj-y, obj-m et la compilation conditionnelle.
  • Choisir une configuration adaptée à Ubuntu et à la VM.
  • Utiliser defconfig, olddefconfig, localmodconfig et menuconfig.
  • Comparer les configurations avec diffconfig.
  • Comprendre les types et dépendances du langage Kconfig.
  • Ajouter sa propre option de menu et relier celle-ci à un fichier C.
  • Réaliser un TP complet, puis répondre aux exercices corrigés.

CHAPITRE 1 - Objectifs et principes du développement du noyau Linux

2. Pourquoi récupérer et configurer le noyau ?

Un driver Linux doit être compilé pour une plateforme, une version et une configuration du noyau cible. Les sources permettent de comprendre les interfaces internes et l'origine des objets qui composent une image ou un module.

Exemple : notre VM possède déjà un noyau Ubuntu. Si nous voulons écrire un petit module logiciel, une reconstruction complète de Linux n'est généralement pas nécessaire. Mais si nous voulons intégrer une fonctionnalité dans les sources, sélectionner des options ou explorer la façon dont un driver est inclus, il faut maîtriser l'arbre source, Kbuild et Kconfig.

À retenir : « télécharger les sources » n'est pas « compiler » ; « compiler » n'est pas « installer » ; « installer » n'est pas « démarrer sur le nouveau noyau ».

3. Distribution et noyau

Ubuntu est une distribution : elle livre le noyau, le shell, les services, les bibliothèques et des outils d'administration. Linux désigne ici le noyau qui arbitre notamment CPU, mémoire, processus, fichiers et périphériques.

Code: Select all

uname -r
cat /etc/os-release
uname -m
« uname -r » indique la release du noyau exécuté ; « /etc/os-release » décrit la distribution ; « uname -m » indique l'architecture machine exposée. Un suffixe Ubuntu comme « -generic » ne correspond pas directement à une version upstream officielle : la distribution adapte le noyau.

4. Objectifs et limites du chapitre

Nous apprendrons à choisir une version déterminée, récupérer son code, localiser des composants, comprendre les fichiers Makefile/Kconfig, préparer « .config », utiliser menuconfig et ajouter une nouvelle option. Nous n'allons pas remplacer le noyau de démarrage, signer des modules pour Secure Boot ni toucher au système principal.

5. Prérequis logiciels

Dans Ubuntu, pour un laboratoire habituel :

Code: Select all

sudo apt update
sudo apt install git build-essential bc flex bison libssl-dev \
  libelf-dev libncurses-dev dwarves xz-utils wget ca-certificates
  • git : gérer versions et commits ;
  • build-essential : GCC, make et outils usuels ;
  • bc, flex, bison : outils utilisés par certaines phases du build ;
  • libssl-dev et libelf-dev : bibliothèques de développement pour des outils du noyau ;
  • libncurses-dev : interface texte menuconfig ;
  • dwarves : paquet fournissant notamment pahole pour BTF ;
  • xz-utils : archives compressées ;
  • wget, ca-certificates : téléchargement HTTPS.
Les dépendances exactes varient avec la version et les options. Quand une compilation échoue, lire d'abord le nom du binaire ou de l'en-tête manquant, plutôt que d'installer des paquets au hasard.

6. Environnement matériel et sécurité

Pour une VM Ubuntu Desktop, 4 vCPU, 6 à 8 Gio de RAM et 50 Gio d'espace disponible offrent du confort. Ce ne sont pas des minima impératifs. La compilation intégrale consomme nettement plus que la simple consultation des sources. Le VHDX dynamique et les points de contrôle peuvent augmenter l'utilisation disque côté Windows.

Créez un point de contrôle Hyper-V avant toute modification importante, et une sauvegarde séparée de votre travail. Même si un snapshot permet de revenir en arrière, il ne remplace pas une sauvegarde indépendante.


CHAPITRE 2 - Les versions et les branches du noyau Linux

7. Lire un numéro de version

Une version upstream peut être 6.12.1 : première composante 6, deuxième 12, troisième 1 (mise à jour corrective de la série). Ce n'est PAS une promesse de compatibilité des interfaces internes, contrairement à l'idée qu'on se fait parfois du versionnement sémantique d'une bibliothèque.

Exemple historique : 5.4 (sortie de série), 5.4.1 (correctif), 5.5-rc1 (première candidate d'une série suivante). Le « 5.x » du livre reflète l'époque de sa rédaction. En 2026, il faut choisir une version volontairement et consulter la documentation de CETTE version, pas suivre aveuglément tous les menus photographiés.

8. Mainline, release candidate, stable, LTS
  • mainline : branche principale où convergent les nouvelles évolutions ;
  • -rc : préversions destinées à stabiliser la prochaine sortie ;
  • stable : mises à jour correctives d'une version publiée ;
  • LTS ou longterm : série maintenue plus longtemps, selon des engagements qui peuvent changer ;
  • arbres de sous-systèmes : réseaux, pilotes, architectures, etc. ;
  • linux-next : intégration anticipée de changements en préparation.

Une LTS n'assure pas que les API internes des modules restent stables. Elle offre surtout une maintenance prolongée dans la série. Pour un laboratoire non consacré aux régressions, choisir une branche stable ou longterm encore maintenue au moment du test.

9. Pourquoi éviter une sélection automatique ?

La toute dernière version peut modifier Kconfig, déplacer des fichiers ou changer une API. À l'inverse, une ancienne version peut manquer de correctifs de sécurité et de compatibilité matérielle. Vérifiez la liste des séries maintenues sur https://www.kernel.org/ et fixez la version du laboratoire dans vos notes.

10. Noyau exécuté contre noyau source

Code: Select all

uname -r
ls -l /lib/modules/"$(uname -r)"/build
Le second chemin cible normalement le répertoire des fichiers de build du noyau actuellement chargé. Il sert notamment aux modules externes. Il ne s'agit pas nécessairement de l'arbre upstream complet que vous avez extrait dans votre dossier personnel.

Même si vous placez dans ~/kernel-lab les sources d'un autre noyau, « uname -r » ne changera pas. Seul un redémarrage vers une image effectivement installée changerait la version active.

Exercice : télécharger les sources 6.12 alors que la VM lance un noyau Ubuntu différent : est-ce un problème ? Non pour lire et configurer 6.12 ; potentiellement oui pour charger dans Ubuntu un module construit contre 6.12, car l'ABI interne et la configuration peuvent différer.

CHAPITRE 3 - Développement collaboratif, mainteneurs et Git

11. Comment le code évolue-t-il ?

Des contributeurs proposent des correctifs (« patches »). Les mainteneurs et les relecteurs examinent les comportements, la sécurité, les régressions, le style et les tests. Une modification qui compile n'est pas nécessairement acceptable. Les sous-systèmes réunissent leurs évolutions avant l'intégration dans la branche principale.

12. Le fichier MAINTAINERS

Le fichier MAINTAINERS, à la racine des sources, associe des chemins, des domaines et des responsables. Pour retrouver les interlocuteurs d'un composant :

Code: Select all

less MAINTAINERS
./scripts/get_maintainer.pl -f drivers/char/mem.c
Ce chemin est un exemple : vérifiez qu'il existe dans votre version. Sur un répertoire entier, le script peut donner beaucoup trop de résultats. Pour une contribution, utilisez des chemins précis et étudiez la documentation de soumission.

13. Dépôt, commit, branche et tag

Un commit identifie un état précis de l'historique avec des métadonnées. Une branche est un pointeur mobile ; un tag tel que v6.12 pointe généralement sur une publication précise. Un clone n'est pas une installation : il copie l'arbre Git, sans modifier le noyau lancé ni GRUB.

Code: Select all

git status
git log -5 --oneline
git tag --list 'v6.12*'
git show --stat --oneline HEAD
  • status : modifications locales ;
  • log : commits récents ;
  • tag : références nommées ;
  • show : détails du commit courant (HEAD).
Avant de changer de branche ou de tag, contrôler « git status » pour ne pas risquer de perdre son travail. Noter le hash de commit rend l'exercice reproductible.

14. Cycle de développement

Après une sortie, la « merge window » permet d'intégrer de nouvelles fonctionnalités. Puis arrivent généralement des versions -rc centrées sur la stabilisation. La version finale est publiée, suivie éventuellement de correctifs dans les branches stable. Cela explique pourquoi deux branches du noyau peuvent diverger momentanément.


CHAPITRE 4 - Récupération et préparation des sources du noyau

15. Archive ou Git ?

Une archive .tar.xz fournit une photographie des sources : plus simple, sans historique. Git permet de comparer les changements et remonter aux commits, au prix d'un téléchargement qui peut devenir important. Une distribution peut aussi fournir des sources PATCHÉES, différentes de l'arbre officiel upstream.

16. Archive officielle : exemple guidé

La version 6.12.1 ci-dessous est choisie seulement pour illustrer une URL concrète. Elle n'est pas recommandée comme noyau de production en 2026. Pour votre vrai travail, vérifiez et remplacez par une version encore maintenue.

Code: Select all

mkdir -p ~/sources-linux
cd ~/sources-linux
KVER=6.12.1
wget "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KVER}.tar.xz"
tar -tf "linux-${KVER}.tar.xz" | head
tar -xf "linux-${KVER}.tar.xz"
cd "linux-${KVER}"
ls
Pourquoi ces commandes ? « mkdir -p » crée le dossier ; « cd » change de répertoire ; KVER est une variable du shell ; « wget » télécharge ; « tar -tf » liste les entrées de l'archive ; « tar -xf » extrait ; « ls » permet de vérifier que les sources sont là.

Sécurité : vérifier l'origine et, idéalement, la signature de l'archive avec les mécanismes publiés par kernel.org. Ne recopiez pas une empreinte SHA256 d'une page aléatoire : comparez-la à celle d'une publication fiable et authentifiée.

17. Récupération avec Git

Code: Select all

cd ~
git clone --depth 1 --branch v6.12 \
  https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git \
  kernel-lab
cd kernel-lab
git status
git log -1 --oneline
« --depth 1 » limite l'historique obtenu ; « --branch v6.12 » sélectionne le tag de release utilisé ici ; le dernier argument est le nom du dossier local. Un clone superficiel ne permet pas d'explorer tous les anciens commits. Pour travailler sur une évolution historique, il faut approfondir ou refaire le clone.


18. Où travailler ?

Dans le dossier personnel, sans sudo :

Code: Select all

~/kernel-lab/       # sources de travail
~/kernel-build/     # futurs objets construits
~/notes-kernel/     # captures, notes, commandes
Pourquoi ? Les sources et objets appartiennent à l'utilisateur ; « sudo make » est généralement inutile et risque de créer des fichiers root qui gêneront les étapes suivantes. Distinguez construction et installation.

19. Contrôler l'extraction

Code: Select all

test -f Makefile && echo "Makefile présent"
test -f init/Kconfig && echo "Kconfig présent"
test -d drivers && echo "drivers présent"
head -n 8 Makefile
« test -f » vérifie un fichier ; « test -d » un dossier ; « && » lance la commande suivante seulement si la première réussit. Le Makefile racine indique notamment VERSION, PATCHLEVEL et SUBLEVEL. En cas d'absence de ces fichiers, vous n'êtes probablement pas dans la racine d'un arbre complet.

CHAPITRE 5 - Comprendre l’arborescence du noyau Linux

20. Où se trouvent les fonctionnalités ?

À la racine : Makefile, Kconfig, README, COPYING, MAINTAINERS et de nombreux répertoires. Il s'agit des fichiers sources, PAS des répertoires installés sur Ubuntu.

Code: Select all

cd ~/kernel-lab
ls -la | head -n 35
find . -maxdepth 1 -type d | sort
Les répertoires principaux ont les rôles indicatifs suivants :

Code: Select all

arch/           code spécifique aux architectures CPU
block/          couche des périphériques blocs
crypto/         infrastructure cryptographique
Documentation/  documentation technique
drivers/       nombreux pilotes matériels et virtuels
fs/            systèmes de fichiers et VFS
include/       en-têtes et déclarations
init/          initialisation du noyau
ipc/           communication interprocessus
kernel/        mécanismes centraux, planification, signaux...
lib/           utilitaires internes
mm/            gestion mémoire
net/           piles et protocoles réseau
samples/       exemples de code, selon version
scripts/       outils de configuration et compilation
security/      sécurité, LSM
tools/         outils connexes en espace utilisateur
virt/          virtualisation
Ces frontières ne sont pas absolues : le traitement mémoire a aussi du code spécifique sous arch/ et les pilotes peuvent interagir avec fs/ ou net/.

21. Le cas de drivers/

Le répertoire drivers/ contient des sous-dossiers par catégories. Un driver n'est pas forcément un pilote de carte PCI physique : un périphérique virtuel ou un module logiciel peut fournir un service au système.

Code: Select all

find drivers -maxdepth 2 -type d | head -n 40
git grep -n 'module_init(' -- drivers/ | head
« git grep -n » recherche du texte dans les fichiers suivis par Git et affiche les numéros de lignes. Avec une archive sans Git, employer « grep -R -n » sur un périmètre raisonnable.

22. Où trouver les déclarations ?

Les en-têtes sous include/linux/ déclarent des structures et fonctions internes. include/uapi/ concerne les interfaces exposées aux programmes utilisateur. Une déclaration interne n'est pas une ABI stable pour les modules tiers.

Code: Select all

git grep -n 'struct file_operations' -- include/
git grep -n 'module_param(' -- samples/ drivers/ | head
Cherchez la définition ET les usages : la signature seule n'explique ni l'ordre des appels, ni la durée de vie des objets, ni les invariants de synchronisation.

23. Kconfig et Makefiles locaux

Une fonctionnalité possède souvent trois éléments :
  • une option dans Kconfig ;
  • une règle associée à cette option dans Makefile ;
  • un ou plusieurs fichiers source C ou assembleur.
Exemple schématique :

Code: Select all

drivers/
  Kconfig
  Makefile
  char/
    Kconfig
    Makefile
    ...
Le chemin réel peut changer entre versions. Quand un menu a été déplacé, recherchez le symbole, pas seulement le texte visible du menu.


24. Mini-exercice : remonter jusqu'au code

Choisissez CONFIG_TUN si le symbole existe dans votre version :

Code: Select all

git grep -n -w 'config TUN' -- '*Kconfig*'
git grep -n 'CONFIG_TUN' -- '*Makefile*'
Puis ouvrez le source mentionné par le Makefile. Vous verrez la chaîne : définition du choix (Kconfig) -> sélection des fichiers (Kbuild) -> comportement réel (C).

CHAPITRE 6 - Make, Makefiles et système de compilation Kbuild

25. Pourquoi Kbuild existe-t-il ?

Le noyau contient des milliers de fichiers, plusieurs architectures et beaucoup de fonctionnalités facultatives. Compiler aveuglément tous les fichiers est inutile et parfois impossible. Kbuild sélectionne les bons objets selon l'architecture et « .config », puis coordonne leurs dépendances.

GNU make est un moteur généraliste lisant des règles. Kbuild est l'infrastructure du noyau autour de Makefiles et de scripts. Kconfig définit les options et les menus, qui sont ensuite résolus en une configuration.

26. Comparaison avec un petit programme C

Code: Select all

/* calcul.c */
int addition(int a, int b)
{
    return a + b;
}

/* main.c */
#include <stdio.h>
int addition(int a, int b);
int main(void)
{
    printf("%d\n", addition(2, 3));
    return 0;
}

Code: Select all

gcc -c calcul.c -o calcul.o
gcc -c main.c -o main.o
gcc main.o calcul.o -o test
./test
« -c » produit un objet sans lier l'exécutable ; la dernière commande gcc lie les deux objets. Kbuild accomplit une tâche analogue à une bien plus grande échelle, avec des règles spécifiques au noyau. Un « .o » noyau n'est pas un programme utilisateur autonome.

27. Chaîne de construction conceptuelle

Code: Select all

Kconfig -> choix utilisateur -> .config
                          | 
                          v
                 fichiers générés de config
                          |
Sources C/ASM + Makefiles Kbuild + compilateur
                          |
                          v
Objets .o -> archives internes -> vmlinux / modules .ko
                          |
                          v
                 image de démarrage
Deux questions sont séparées : « quelle fonction veut-on ? » (Kconfig) et « quels fichiers faut-il produire ? » (Kbuild). C'est fondamental pour savoir où intervenir.

28. Trois formes de règles

Code: Select all

obj-y += base.o
obj-m += diagnostic.o
obj-$(CONFIG_EXAMPLE_DRIVER) += example_driver.o
« obj-y » sélectionne un objet intégré au noyau ; « obj-m » un objet compilé comme module ; « obj-$(CONFIG_EXAMPLE_DRIVER) » devient obj-y si l'option vaut y, obj-m si elle vaut m, et n'ajoute rien si elle vaut n.

Pourquoi cette syntaxe ? Dans GNU make, « $(NOM) » remplace une variable par sa valeur. Kbuild prépare les symboles CONFIG_ pour permettre cette sélection. Dans un simple Makefile utilisateur non intégré à Kbuild, copier cette ligne ne suffit pas.

29. Module composé de plusieurs sources

Code: Select all

obj-$(CONFIG_EXAMPLE_DRIVER) += example_driver.o
example_driver-y := coeur.o diagnostics.o
Kbuild assemble coeur.o et diagnostics.o en example_driver.o ; si la valeur finale est m, il construit ensuite example_driver.ko. Pour éviter un conflit, ne créez pas ici un fichier example_driver.c portant le même nom que l'objet composite.

30. Module externe et noyau existant

Un module externe peut avoir un Makefile minimal :

Code: Select all

obj-m += demo_externe.o
Dans son dossier :

Code: Select all

make -C /lib/modules/"$(uname -r)"/build M="$PWD" modules
« -C » dit à make de se placer dans l'environnement de build du noyau cible ; « M="$PWD" » transmet le chemin absolu du dossier du module ; « modules » indique la cible. Cette commande utilise les fichiers de construction du noyau ACTIF, qui peuvent être différents des sources upstream téléchargées plus tôt.

31. Les résultats d'une construction

« vmlinux » est généralement le fichier ELF principal non compressé ; l'image de démarrage x86 peut être « arch/x86/boot/bzImage ». Un « .ko » est un module chargeable. « System.map » aide à examiner des symboles. Dans les noyaux modernes, les objets intégrés passent notamment par des archives « built-in.a ». Les noms exacts des fichiers temporaires changent parfois.


CHAPITRE 7 - CONFIG_, options du noyau et compilation conditionnelle

32. Qu'est-ce qu'un symbole CONFIG_ ?

Kconfig déclare des SYMBOLES comme « TUN », « MODULES » ou « DEBUG_INFO ». Quand une configuration est enregistrée, ils apparaissent sous le préfixe « CONFIG_ », par exemple « CONFIG_TUN=m ». Ces noms relient les menus, les scripts et parfois le code C. Il faut distinguer le nom Kconfig (« TUN ») et sa représentation dans « .config » (« CONFIG_TUN »).

Exemple dans un fichier Kconfig :

Code: Select all

config LAB_TEST
    tristate "Exemple pédagogique"
    default n
    help
      Active un exemple de laboratoire.
La déclaration crée le symbole LAB_TEST. « tristate » autorise trois états si la prise en charge des modules est disponible. « default n » préfère désactivé. « help » explique l'option dans l'interface.

33. Les trois valeurs

Code: Select all

CONFIG_LAB_TEST=y   # intégré à l'image du noyau
CONFIG_LAB_TEST=m   # construit comme module chargeable
# CONFIG_LAB_TEST is not set    # désactivé
Pour une option « bool », seules y ou n sont possibles. Pour une option « tristate », m est disponible si les dépendances et le support des modules l'autorisent. Un module m ne fonctionne pas nécessairement immédiatement : il faut encore produire son .ko et le charger, explicitement ou automatiquement.

34. Différence fondamentale : intégré et module

Si un pilote nécessaire au démarrage est intégré (« y »), le noyau possède directement son code. S'il est module (« m »), le fichier .ko doit être disponible et chargé au bon moment ; certaines fonctions critiques au démarrage nécessitent alors un initramfs correctement préparé.

Un driver « intégré » et un driver « module » peuvent remplir une fonction équivalente, mais leur cycle de chargement et leur gestion des ressources diffèrent. C'est la même idée générale qu'une liaison statique versus chargement séparé, sans être une équivalence parfaite.

35. Le chemin Kconfig -> Makefile -> fichier C

Code: Select all

# Kconfig
config LAB_TEST
    tristate "Mon composant"
    default n

# Makefile Kbuild
obj-$(CONFIG_LAB_TEST) += lab_test.o

# Fichier source correspondant : lab_test.c
Si LAB_TEST=y, l'objet participe à l'image. Si m, il participe à un module. Si n, il est omis. On peut donc prendre des décisions de build sans multiplier les « #ifdef » dans chaque fichier.

36. Les macros générées pour le C

Kbuild produit pendant la préparation des fichiers comme « include/generated/autoconf.h » et « include/config/auto.conf » (dans l'arbre des objets si O= est utilisé). Ils traduisent les options en définitions utilisables par les outils de build et le code.

Exemple conceptuel : pour une option booléenne activée, le préprocesseur peut disposer de « CONFIG_LAB_TEST » défini. Pour un symbole tristate réglé sur m, la représentation C peut prendre la forme « CONFIG_LAB_TEST_MODULE ». C'est pourquoi « #ifdef CONFIG_LAB_TEST » ne couvre PAS automatiquement les deux cas y et m.

37. Exemple C : séparer les cas

Code: Select all

#include <linux/kconfig.h>
#include <linux/printk.h>

static void exemple(void)
{
#if IS_ENABLED(CONFIG_LAB_TEST)
    pr_info("L'option LAB_TEST est active (y ou m).\n");
#else
    pr_info("LAB_TEST n'est pas activée.\n");
#endif
}
« IS_ENABLED » est une macro noyau qui permet de tester si un symbole vaut y OU m. Attention : si du code intégré au noyau appelle directement des fonctions qui n'existent que dans un module, « l'option est activée » ne garantit pas que ces fonctions soient accessibles à l'édition de liens ; « IS_REACHABLE » et la structure des dépendances peuvent alors être pertinents.

Autre exemple simple, uniquement pour une option bool :

Code: Select all

#ifdef CONFIG_LAB_VERBOSE
    pr_info("Journalisation détaillée active\n");
#endif
Ne recopiez pas cet extrait dans un programme utilisateur avec « stdio.h » : « pr_info » est une macro de journalisation noyau, pas un printf standard. Il faut construire ce code dans le contexte Kbuild adapté.

38. Les dépendances ne sont pas décoratives

Une option visible et activable peut dépendre d'une autre : architecture, prise en charge de modules ou infrastructure particulière. Si la dépendance est absente, l'option peut devenir invisible ou être limitée. Modifier « .config » à la main ne contourne pas proprement les règles : un nouvel appel à Kconfig peut corriger ou rejeter la valeur.

Exercice : si CONFIG_LAB_TEST=m, à quoi devient « obj-$(CONFIG_LAB_TEST) » ? Réponse : obj-m. Si le symbole est n ? L'objet n'est pas sélectionné par cette règle.

CHAPITRE 8 - Choisir une configuration initiale pour le noyau

39. Pourquoi éviter une configuration vide ?

Le noyau dépend d'options qui collaborent : systèmes de fichiers, pilotes de stockage, réseau, support de la plateforme et mécanismes du démarrage. Créer un .config à partir de rien peut conduire à un noyau qui compile mais ne démarre pas, ou même à un build impossible.

Pour un PC/serveur Ubuntu dans Hyper-V, le choix pédagogique le plus compréhensible est de partir d'une configuration fonctionnelle de distribution, puis de la réduire ou l'adapter. Pour un système embarqué, on privilégie souvent le defconfig fourni par la plateforme ou le fabricant du BSP.

40. La configuration par défaut

Code: Select all

cd ~/kernel-lab
make defconfig
« defconfig » génère une configuration de référence pour l'architecture et la plateforme ciblées. « Par défaut » ne veut pas dire « identique à Ubuntu » ni « adaptée à tous les périphériques de votre VM ».

Pour une autre architecture, un nom comme « make ARCH=arm64 defconfig » peut être approprié, mais la construction ultérieure exigera aussi un compilateur compatible avec l'architecture cible.

41. Réutiliser la configuration d'Ubuntu

Code: Select all

cd ~/kernel-lab
cp "/boot/config-$(uname -r)" .config
make olddefconfig
Étapes expliquées :
1) « /boot/config-$(uname -r) » est la configuration sauvegardée par la distribution pour la release en cours, lorsqu'elle est disponible ;
2) « cp » la copie vers les sources (elle n'installe rien) ;
3) « make olddefconfig » adapte le fichier aux options de l'arbre choisi, en conservant les valeurs compatibles et en attribuant des valeurs par défaut aux nouvelles entrées.

ATTENTION : une configuration Ubuntu peut contenir des symboles ajoutés ou renommés par des correctifs de distribution. Une partie de ces options peut disparaître lorsque vous l'appliquez aux sources upstream. Vérifiez les changements, et ne considérez pas que les modules Ubuntu installés correspondent automatiquement au nouveau noyau.

42. oldconfig et olddefconfig

« oldconfig » lit une ancienne configuration et peut poser des questions sur les nouveaux symboles. « olddefconfig » choisit les valeurs par défaut sans demander une réponse à chaque nouveauté. Ce dernier est commode pour automatiser une adaptation, mais il ne remplace pas la vérification des choix importants.


43. Conseil : séparer sources et fichiers générés

La variable « O= » permet de choisir un dossier de build distinct :

Code: Select all

mkdir -p ~/kernel-build
cd ~/kernel-lab
make O="$HOME/kernel-build" defconfig
make O="$HOME/kernel-build" menuconfig
Les objets et « .config » se trouvent alors dans ~/kernel-build, PAS dans ~/kernel-lab. Utilisez le MÊME O= pour toutes les étapes de cette construction. Si vous passez d'un build dans les sources à un build séparé sans réfléchir, vous risquez de regarder le mauvais fichier « .config ».

Si vous utilisez O=, réutiliser la configuration Ubuntu ainsi :

Code: Select all

cp "/boot/config-$(uname -r)" ~/kernel-build/.config
make O="$HOME/kernel-build" olddefconfig
Vérification : « ls -l ~/kernel-build/.config ». Le fichier est en ASCII lisible. N'éditez pas aveuglément chaque option ; laissez les outils Kconfig résoudre les dépendances.

CHAPITRE 9 - La configuration par les modules avec localmodconfig

44. La logique de localmodconfig

Une distribution active de nombreuses fonctions pour couvrir beaucoup de configurations matérielles. Notre VM n'en utilise qu'une partie au moment du test. « make localmodconfig » essaie de préparer un « .config » où les modules inutilisés ne sont pas retenus, en s'appuyant sur la liste des modules chargés.

Cette stratégie est un RACCOURCI, pas une détection exhaustive des périphériques. Un module non chargé au moment du relevé pourrait être indispensable plus tard : clé USB, VPN, autre système de fichiers, périphérique ajouté à chaud, fonctionnalité réseau particulière.

45. Ce que montre lsmod

Code: Select all

lsmod
lsmod | head -n 15
Colonnes usuelles : nom du module, taille et informations d'utilisation. La liste décrit les modules présents dans le noyau à cet instant. Un code intégré « y » n'y apparaît pas comme module chargeable ; un périphérique peut aussi avoir son driver compilé directement dans l'image.

46. Sauvegarder un instantané

Code: Select all

lsmod > /tmp/modules-chargees.txt
head /tmp/modules-chargees.txt
« > » redirige la sortie standard vers un fichier, en remplaçant son contenu. Le fichier sera utilisable même après que d'autres applications auront modifié les modules chargés. Notez que /tmp peut être nettoyé lors d'un redémarrage : déplacez votre instantané dans ~/notes-kernel si vous souhaitez le conserver.

47. Générer la configuration

En supposant que ~/kernel-build/.config existe déjà :

Code: Select all

cd ~/kernel-lab
make O="$HOME/kernel-build" \
  LSMOD=/tmp/modules-chargees.txt localmodconfig
« LSMOD= » est un paramètre transmis à Make/Kbuild pour désigner le relevé de modules. Ce n'est pas le nom d'un dossier. La commande peut prendre du temps et signaler des options nouvelles suivant l'écart entre la configuration d'origine et le code cible.

48. Pourquoi cette approche peut être dangereuse

Scénario : vous n'avez jamais branché de périphérique USB dans la VM. Sa prise en charge peut ne pas figurer dans les modules actifs, puis être écartée. Vous connectez ensuite le périphérique : il ne fonctionne plus dans le noyau personnalisé. Autre scénario : un driver est nécessaire très tôt au démarrage, mais son absence n'est pas visible dans la liste des modules.

Conclusion : pour la première compilation destinée au démarrage, une configuration de distribution validée est souvent plus prudente qu'un localmodconfig agressif. Pour une VM de test que l'on peut restaurer, localmodconfig peut être un excellent exercice de compréhension.

49. Prouver la réduction

Sauvegardez la configuration AVANT la modification :

Code: Select all

cp ~/kernel-build/.config ~/kernel-build/config-avant-localmod
make O="$HOME/kernel-build" \
  LSMOD=/tmp/modules-chargees.txt localmodconfig
scripts/diffconfig ~/kernel-build/config-avant-localmod \
  ~/kernel-build/.config | head -n 40
Vous verrez les changements de symboles. La moindre réduction ne prouve pas que la configuration est bonne : seuls des tests ultérieurs le montreront.

CHAPITRE 10 - Les commandes de configuration et de nettoyage

50. Lire les objectifs disponibles

Code: Select all

cd ~/kernel-lab
make help
C'est la première commande à essayer si un tutoriel présente une cible inconnue. La liste dépend du Makefile et de la version étudiés.

51. Tableau des cibles principales

Code: Select all

make defconfig       configuration par défaut de plateforme
make oldconfig       adapte l'ancienne config, avec questions
make olddefconfig    adapte, valeurs par défaut sans questions
make menuconfig      interface texte ncurses
make nconfig         autre interface de configuration en texte
make xconfig         interface graphique Qt, si dépendances présentes
make localmodconfig  réduction selon les modules chargés
make savedefconfig   crée une configuration minimale de référence
make help            aide et liste des cibles proposées
Quand on utilise O=, il faut le fournir à ces commandes : « make O="$HOME/kernel-build" nconfig », par exemple. « savedefconfig » est pratique pour sauvegarder un delta de configuration minimal, mais un defconfig n'est pas la copie intégrale de toutes les valeurs affichées dans « .config ».

52. olddefconfig dans la vie réelle

Vous recevez un fichier .config préparé pour une autre version du noyau. Si vous lancez immédiatement « make », les dépendances peuvent imposer de nouvelles valeurs. La bonne pratique est de conserver une copie de référence puis de faire « make olddefconfig » et d'inspecter la différence.

53. Nettoyage : les pièges
  • « make clean » enlève de nombreux fichiers générés, sans chercher à effacer la configuration comme le ferait mrproper ;
  • « make mrproper » nettoie beaucoup plus, y compris « .config » et d'autres fichiers générés ;
  • « make distclean » va encore plus loin pour certains résidus.

Ne lancez pas ces commandes par réflexe lorsque vous essayez simplement de relancer menuconfig. Sauvegardez « .config » AVANT. Avec O=, vérifiez quel arbre d'objets est visé.

54. Pourquoi éviter sudo ?

« make menuconfig » travaille dans un dossier dont vous êtes propriétaire. Si vous avez besoin de sudo pour créer « .config », vérifiez les permissions : vous avez peut-être auparavant exécuté une compilation en root. Corrigez la cause au lieu d'accumuler des commandes privilégiées.


CHAPITRE 11 - Personnaliser le noyau avec menuconfig

55. À quoi sert l'interface ?

menuconfig est une interface en mode texte (généralement ncurses) permettant de parcourir des options Kconfig. Ce n'est pas un IDE, ni un chargeur de modules. Le menu contrôle la configuration du FUTUR build, sans appliquer en direct ces choix au noyau en fonctionnement.

56. Lancer le menu

Code: Select all

cd ~/kernel-lab
make O="$HOME/kernel-build" menuconfig
Si une bibliothèque ou des en-têtes ncurses manquent, « libncurses-dev » doit être installé. En environnement purement terminal, agrandissez la fenêtre pour éviter les menus coupés.

57. Navigation
  • Flèches : choisir une ligne ;
  • Entrée : ouvrir un sous-menu ;
  • Espace : basculer un choix compatible avec ses dépendances ;
  • Y / M / N : demander respectivement intégré / module / désactivé quand autorisé ;
  • « ? » : aide de l'entrée ;
  • « / » : recherche par symbole ou libellé ;
  • Exit / Save : sortir et enregistrer.

Les touches et les libellés peuvent changer légèrement selon la version. Si « M » ne fonctionne pas, demandez-vous si la fonctionnalité accepte les modules ET si ses dépendances sont satisfaites.

58. Comprendre les symboles visuels

Dans les interfaces historiques, « [ ] » évoque une option bool désactivée, « [*] » une option bool active ; « < > », « <M> » et « <*> » désignent généralement les états possibles d'une option tristate. Le rendu exact peut varier. Une option grisée n'est pas forcément un bug : une dépendance peut la rendre non modifiable.

59. Recherche avec la touche /

Tapez le nom du symbole, par exemple « IKCONFIG », sans préfixe « CONFIG_ ». L'écran de recherche permet souvent de voir la localisation, le texte du menu, les dépendances et les symboles associés. C'est plus robuste que d'apprendre l'emplacement d'un menu dans un livre imprimé en 2020.

Exemple : si un symbole dépend de « PROC_FS », et que cette dépendance est n, la possibilité de l'activer peut être limitée. La recherche aide à comprendre pourquoi.

60. Paramètres à ne pas modifier au hasard

Les options liées au système de fichiers racine, aux disques, à l'architecture, à la mémoire et à la sécurité peuvent influer sur le démarrage. Pour cette première exploration, choisissez une fonctionnalité pédagogique non essentielle. Évitez de désactiver des éléments que vous n'avez pas identifiés.

61. Sauvegarde et validation

En sortant, validez « Save » et vérifiez :

Code: Select all

ls -l ~/kernel-build/.config
grep '^CONFIG_IKCONFIG=' ~/kernel-build/.config
Un grep sans résultat ne signifie pas automatiquement « option inexistante » : les options désactivées peuvent apparaître sous forme de commentaire « # CONFIG_... is not set ».

Code: Select all

grep 'CONFIG_IKCONFIG' ~/kernel-build/.config
L'option peut aussi ne pas exister dans la version choisie. Vérifiez via la recherche menuconfig.


CHAPITRE 12 - Comparer et vérifier les fichiers de configuration

62. Pourquoi comparer ?

Un « .config » peut contenir des milliers de lignes. Après une modification apparemment mineure, Kconfig peut ajuster des options dépendantes. Sans comparaison, on ne sait pas exactement ce qui a changé. Il est utile de disposer d'un état de référence avant toute expérimentation.

63. Préparer deux copies

Code: Select all

cp ~/kernel-build/.config ~/kernel-build/config-avant
make O="$HOME/kernel-build" menuconfig
cp ~/kernel-build/.config ~/kernel-build/config-apres
Dans menuconfig, modifiez un seul paramètre facile à identifier, puis sauvegardez. Vous conservez ainsi un état initial et final sans dépendre du fichier « .config.old », dont la disponibilité et le contenu peuvent varier.

64. diff et diffconfig

Code: Select all

diff -u ~/kernel-build/config-avant \
  ~/kernel-build/config-apres | less

cd ~/kernel-lab
scripts/diffconfig ~/kernel-build/config-avant \
  ~/kernel-build/config-apres
« diff -u » compare les lignes textuelles brutes, avec contexte. « scripts/diffconfig » comprend la forme des symboles CONFIG_ et rend souvent les différences plus lisibles. Cet outil est fourni avec les sources du noyau, dans scripts/ ; son chemin est relatif à l'arbre source.

65. Lire les différences

Un changement « n -> y » signifie que le symbole a été activé, « m -> y » que l'élément passe d'un module au noyau intégré. Un changement « m -> n » peut supprimer un driver du build. Toutes les modifications ne sont pas dangereuses, mais chaque suppression dans le chemin de démarrage doit être comprise.

66. Éditer .config : pourquoi la prudence ?

« .config » est du texte, mais il représente le résultat d'une résolution Kconfig. Une modification manuelle de « CONFIG_FOO=n » peut être normalisée par « olddefconfig », ignorée à cause d'une dépendance ou produire un état trompeur. Préférez l'interface ou un outil comme « scripts/config » quand vous savez précisément ce que vous faites.

Exemple d'activation ciblée d'un booléen, si le symbole existe :

Code: Select all

cd ~/kernel-lab
scripts/config --file "$HOME/kernel-build/.config" -e IKCONFIG
make O="$HOME/kernel-build" olddefconfig
« --file » choisit le fichier à modifier ; « -e » demande l'activation. Vérifiez ensuite sa valeur : Kconfig peut l'ajuster selon les contraintes. La commande ne fait pas apparaître magiquement un symbole absent des sources.


CHAPITRE 13 - Comprendre le langage Kconfig

67. Ce qu'est un fichier Kconfig

Kconfig n'est ni du code C ni un Makefile. C'est un langage déclaratif : il annonce des symboles, leur type, leurs dépendances, leurs valeurs proposées et les textes d'aide. Les interfaces « menuconfig » et « nconfig » lisent ces déclarations pour construire leurs menus.

Exemple :

Code: Select all

menu "Fonctionnalités du laboratoire"

config LAB_VERBOSE
    bool "Activer les logs supplémentaires"
    default n
    help
      Ajoute des messages pour faciliter le diagnostic.

endmenu
« menu » et « endmenu » encadrent un menu. « config LAB_VERBOSE » introduit un symbole. « bool » impose y/n. L'utilisateur voit le texte entre guillemets. « default n » évite l'activation automatique. Les lignes sous « help » sont indentées et forment une documentation destinée à l'utilisateur.

68. Les types disponibles

« bool » : oui/non. « tristate » : y/m/n selon le support des modules. « int » : entier décimal. « hex » : entier hexadécimal. « string » : chaîne. Le type détermine les valeurs admissibles et leur présentation dans l'interface.

Exemple :

Code: Select all

config LAB_LIMIT
    int "Limite expérimentale"
    range 1 100
    default 10

config LAB_LABEL
    string "Étiquette de laboratoire"
    default "demo"
« range 1 100 » impose un intervalle ; « default 10 » fournit une valeur tant qu'une sélection plus prioritaire n'impose pas autre chose. Un « string » doit être traité comme une donnée : évitez de construire naïvement des chemins shell à partir de valeurs non contrôlées.

69. Dépendances et visibilité

Code: Select all

config LAB_BASE
    bool "Infrastructure de base"
    default n

config LAB_ADVANCED
    bool "Fonctionnalité avancée"
    depends on LAB_BASE
    default n
La seconde option n'est activable que si LAB_BASE satisfait la dépendance. L'expression peut utiliser « && », « || », « ! » et des comparaisons. Pour les tristates, le modèle logique contient n, m et y ; ce n'est pas un simple booléen du langage C.

70. « select » n'est pas « depends on »

« depends on X » impose une contrainte au choix courant. « select X » peut forcer un symbole cible et ne doit pas être employé à la légère : dans certaines situations il contourne ses dépendances habituelles. Le langage Kconfig recommande de réserver « select » surtout à des symboles internes sans dépendances difficiles. « imply X » fournit une recommandation plus faible qu'un « select ».

71. Menus, sous-menus et choix exclusifs

Code: Select all

choice
    prompt "Mode de fonctionnement"
    default LAB_MODE_SAFE

config LAB_MODE_SAFE
    bool "Mode prudent"

config LAB_MODE_FAST
    bool "Mode expérimental"

endchoice
« choice » autorise ici un choix exclusif entre deux modes. Un menu est une structure de navigation ; il n'impose pas, par lui-même, qu'une seule option soit sélectionnée.

72. Inclure d'autres fichiers

Code: Select all

source "drivers/lab/Kconfig"
« source » charge un fichier de configuration supplémentaire. C'est ainsi qu'un menu général peut réunir des dizaines de sous-systèmes sans mettre tous les symboles dans un seul fichier gigantesque. Ne créez pas cette ligne si le chemin ne correspond pas réellement à un fichier existant.

73. Quelques constructions courantes

Code: Select all

config LAB_EXTRA
    tristate "Option supplémentaire"
    depends on MODULES
    default m
    help
      Exemple utile pour étudier les contraintes.
Ici « depends on MODULES » fait dépendre l'option de la prise en charge des modules. Mais cela ne veut PAS dire que « m » est la seule valeur possible : lorsque les conditions le permettent, un tristate peut aussi valoir y. Pour forcer un comportement bien précis, il faut concevoir les dépendances et les règles de build ensemble.


CHAPITRE 14 - Ajouter une option personnalisée au noyau

74. Objectif : un module de laboratoire

Nous voulons une option « CONFIG_LAB_DEMO » dont le menu propose y, m ou n. Nous fournirons un petit fichier C qui écrit un message lors de son initialisation. Le but est de comprendre comment une entrée Kconfig sélectionne un objet Kbuild : nous n'allons pas encore charger un nouveau noyau dans la VM.

75. Préparer une modification réversible

Avec un dépôt Git propre :

Code: Select all

cd ~/kernel-lab
git status
cp drivers/misc/Kconfig drivers/misc/Kconfig.avant-lab
cp drivers/misc/Makefile drivers/misc/Makefile.avant-lab
Les deux copies sont des précautions temporaires. Avant de publier une modification, retirez ces copies du dossier source si elles n'ont plus d'utilité et utilisez Git pour contrôler les différences.

76. Ajouter l'entrée Kconfig

Ouvrez « drivers/misc/Kconfig » et vérifiez sa structure (menus, blocs « if », « endmenu »). Ajoutez la déclaration suivante dans une zone appropriée du menu des périphériques divers, en respectant les structures existantes :

Code: Select all

config LAB_DEMO
    tristate "Module pedagogique LAB_DEMO"
    default n
    help
      Ajoute un petit exemple de laboratoire.
      Ne pilote aucun materiel.
Pourquoi dans drivers/misc ? Cette zone réunit des composants divers dans de nombreuses versions du noyau. Ce placement est PÉDAGOGIQUE, pas une règle universelle de conception. Pour un vrai pilote, choisissez un sous-système approprié ; vérifiez surtout que le Kconfig parent est réellement référencé par l'arbre.

77. Associer une règle de compilation

Ajoutez dans « drivers/misc/Makefile » :

Code: Select all

obj-$(CONFIG_LAB_DEMO) += lab_demo.o
Cette ligne signifie : sélectionner lab_demo.o lorsque l'option est active. Avec y : objet intégré ; avec m : module. Sans cette règle, une entrée apparaîtrait dans le menu sans pour autant ajouter le fichier C au build.

78. Écrire le code C

Créer « drivers/misc/lab_demo.c » :

Code: Select all

#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>

static int __init lab_demo_init(void)
{
    pr_info("lab_demo: initialisation\n");
    return 0;
}

static void __exit lab_demo_exit(void)
{
    pr_info("lab_demo: retrait\n");
}

module_init(lab_demo_init);
module_exit(lab_demo_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Exemple de configuration Kconfig/Kbuild");
Explications détaillées :
  • « linux/init.h » fournit notamment les annotations « __init » et « __exit » ;
  • « linux/module.h » fournit les macros de module ;
  • « linux/printk.h » permet l'usage de « pr_info » ;
  • « static » limite ici la visibilité de la fonction à ce fichier ;
  • « __init » marque une fonction d'initialisation, dont le traitement dépend du fait que le code soit intégré ou modulaire ;
  • le retour « 0 » signale le succès de l'initialisation ;
  • « __exit » concerne le chemin de sortie, notamment lors du retrait d'un module ;
  • « module_init » et « module_exit » enregistrent les points d'entrée et de sortie ;
  • « MODULE_LICENSE » et « MODULE_DESCRIPTION » fournissent des métadonnées.

Ce programme n'ouvre aucun périphérique, n'alloue aucune mémoire et n'enregistre aucun numéro de device. L'exemple évite volontairement les problèmes de durée de vie et de synchronisation pour isoler le mécanisme de configuration.

79. Vérifier la visibilité dans menuconfig

Code: Select all

cd ~/kernel-lab
make O="$HOME/kernel-build" menuconfig
Dans l'interface, rechercher « LAB_DEMO » avec « / ». Choisir « M » si proposé ; sauvegarder et quitter. La disponibilité de M dépend du support des modules et des contraintes de la configuration choisie.

Code: Select all

grep 'CONFIG_LAB_DEMO' ~/kernel-build/.config
Résultat recherché : « CONFIG_LAB_DEMO=m ». Si vous obtenez y, le code serait intégré à une construction complète de l'image. Si n, l'objet ne sera pas sélectionné par cette règle.

80. D'où viennent les macros C ?

Après préparation de la configuration :

Code: Select all

make O="$HOME/kernel-build" prepare
grep 'LAB_DEMO' ~/kernel-build/include/generated/autoconf.h
Pour m, la représentation C peut inclure une macro telle que « CONFIG_LAB_DEMO_MODULE » plutôt qu'un simple « CONFIG_LAB_DEMO ». C'est précisément pourquoi les tests « IS_ENABLED() » sont préférables à un « #ifdef » simpliste si les cas y et m doivent tous deux être pris en compte.

81. Valider les modifications

Code: Select all

git diff -- drivers/misc/Kconfig drivers/misc/Makefile
git status --short
« git diff » montre les ajouts aux fichiers suivis ; « git status » montre aussi le nouveau fichier C non suivi. Contrôlez l'orthographe : le nom « LAB_DEMO » doit être identique dans Kconfig, Makefile et les recherches.

Ne chargez PAS le module produit par une autre version du noyau directement dans Ubuntu. La construction, le démarrage de l'image correspondante et le test d'insertion appartiennent au chapitre suivant. Pour apprendre simplement à compiler un module sur le noyau Ubuntu actuel, utilisez plutôt les en-têtes correspondant à « uname -r » et la méthode du module externe présentée au chapitre 6.

CHAPITRE 15 - Travaux pratiques : préparer un noyau personnalisé

82. Préparer le laboratoire

Créez un point de contrôle Hyper-V, lancez Ubuntu, relevez « uname -r » et « uname -m », puis choisissez une version source fixée. Vérifiez le disque disponible avec « df -h » et la RAM avec « free -h ». Pourquoi ? Une configuration peut réussir même si le disque ne suffira pas à la compilation suivante.

83. Télécharger et identifier

Suivez la méthode Git décrite au chapitre 4, puis notez « git rev-parse HEAD ». Vérifiez que « Makefile », « Kconfig », « drivers/ » et « Documentation/ » existent. Ne poursuivez pas si vous êtes dans un mauvais dossier.

84. Créer une base

Code: Select all

mkdir -p ~/kernel-build
cd ~/kernel-lab
cp "/boot/config-$(uname -r)" ~/kernel-build/.config
cp ~/kernel-build/.config ~/kernel-build/config-distribution
make O="$HOME/kernel-build" olddefconfig
Si « /boot/config-$(uname -r) » n'existe pas, utilisez un « defconfig » adapté :

Code: Select all

make O="$HOME/kernel-build" defconfig
Ne supposez pas qu'une configuration de distribution fonctionne parfaitement telle quelle sur les sources upstream : c'est un POINT DE DÉPART, à analyser.

85. Tester un changement isolé

Code: Select all

cp ~/kernel-build/.config ~/kernel-build/config-reference
make O="$HOME/kernel-build" menuconfig
Recherchez une option non essentielle, modifiez-la et sauvegardez. Comparez :

Code: Select all

scripts/diffconfig ~/kernel-build/config-reference \
  ~/kernel-build/.config
Expliquez les changements inattendus en examinant les dépendances des symboles concernés.

86. Ajouter LAB_DEMO

Reprenez les trois étapes du chapitre 14 : déclaration Kconfig, règle Makefile et fichier C. Activez « LAB_DEMO=m ». Vérifiez « .config », puis contrôlez les ajouts avec « git diff » et « git status ». Cette étape démontre que Kconfig sélectionne une option et que Kbuild connaît l'objet à construire.

87. Vérifications et limites

Code: Select all

grep 'CONFIG_LAB_DEMO' ~/kernel-build/.config
grep 'CONFIG_LAB_DEMO' drivers/misc/Makefile
test -f drivers/misc/lab_demo.c && echo "Source présente"
La présence de ces trois éléments ne signifie pas encore que le module est compilé ou chargé : elle établit uniquement que notre chaîne de configuration est en place. C'est un résultat utile et contrôlable.

88. Revenir à un état propre

Utilisez Git pour examiner précisément les modifications à conserver. Pour abandonner un TP, revenez aux versions sauvegardées des fichiers Kconfig/Makefile et retirez seulement le fichier C que vous avez créé. Ne lancez pas un nettoyage Git destructeur sans lire les fichiers affectés : vos autres travaux pourraient être perdus.

Livrables conseillés pour le forum : la version du noyau, le hash Git, la configuration initiale, les différences après menuconfig, le contenu du petit Kconfig, le Makefile et le C, plus une courte explication de chaque étape.

CHAPITRE 16 - Exercices, questions et corrections


89. Questions de compréhension
  • Q1. « uname -r » change-t-il après « git checkout » ?
  • Q2. Quelle est la différence entre « CONFIG_FOO=y » et « =m » ?
  • Q3. Un Makefile contient « obj-$(CONFIG_FOO) += foo.o ». Si FOO=n, foo.c est-il sélectionné par cette règle ?
  • Q4. Pourquoi localmodconfig peut-il rendre un noyau incomplet ?
  • Q5. Pourquoi copier un « .config » Ubuntu puis lancer olddefconfig ?
  • Q6. Quelle est la différence entre « depends on » et « select » ?
  • Q7. Pourquoi comparer les configurations après un changement ?
  • Q8. Quelle différence entre « vmlinux », « bzImage » et « .ko » ?
  • Q9. Si une option tristate vaut m, pourquoi « #ifdef CONFIG_FOO » n'est-il pas un test universel ?
  • Q10. Un module compilé contre les sources 6.12 peut-il forcément être chargé sur une VM Ubuntu dont la release diffère ?

90. Corrections expliquées
  • R1. Non. Git modifie la copie de travail, pas le noyau exécuté.
  • R2. y sélectionne une inclusion au noyau ; m sélectionne un module, si autorisé. Cela ne garantit ni installation ni chargement.
  • R3. Non. Si FOO=m, la règle participe à la génération d'un module ; si y, à la construction intégrée.
  • R4. Les modules non chargés lors de l'inventaire ne couvrent pas tous les usages futurs, le matériel ajouté plus tard ou certains besoins de démarrage.
  • R5. Récupérer des choix fonctionnels tout en laissant Kconfig adapter les symboles aux sources effectivement utilisées. Il faut ensuite inspecter les changements.
  • R6. « depends on » limite la sélection de l'option courante ; « select » force potentiellement un autre symbole et peut contourner certaines de ses contraintes.
  • R7. Une option peut modifier des dépendances et déclencher d'autres changements que celui demandé dans l'interface.
  • R8. vmlinux est le noyau ELF principal, bzImage est une image de démarrage x86, « .ko » un module chargeable. Leurs usages et formats ne sont pas interchangeables.
  • R9. Les symboles « module » peuvent être exposés au C via « CONFIG_FOO_MODULE ». Utilisez les macros Kconfig adaptées (« IS_ENABLED », éventuellement « IS_REACHABLE ») selon le type de code.
  • R10. Non. Les interfaces internes, symboles exportés, options et métadonnées de version peuvent être incompatibles.

CHAPITRE 17 - Conclusion et préparation du chapitre suivant


91. Bilan du chapitre et savoir-faire

Ce chapitre a établi le chemin complet du choix technique :

Code: Select all

Version précise -> sources -> Kconfig -> .config
                                 |
                                 v
                      Kbuild et Makefiles
                                 |
                                 v
                      sources sélectionnées
                                 |
                                 v
              objets et modules lors du futur build

L'essentiel pour un développeur de drivers : savoir où trouver un code, comment il est sélectionné, quand il est intégré ou construit comme module, et pourquoi une option peut être bloquée par des dépendances. Ce sont des compétences directement transférables à la maintenance d'un driver.

Dans le chapitre suivant, nous pourrons aborder le build lui-même, les outils de diagnostic, l'installation dans la VM, l'initramfs et le chargeur de démarrage. Nous vérifierons le fonctionnement avec une procédure de retour arrière. Ne confondez jamais un message « build succeeded » avec la preuve qu'un noyau démarre ou qu'un module est sûr.

Annexes - Références et rappels

Glossaire
  • Upstream : sources du projet principal, avant adaptations d'une distribution.
  • Kconfig : langage de description des options de configuration.
  • Kbuild : mécanismes de compilation et d'assemblage du noyau.
  • .config : résultat de la configuration, propre à un arbre/une cible.
  • Module .ko : fichier compilé destiné au chargeur de modules du noyau.
  • O= : dossier de sortie séparé de l'arbre source.
  • Tag : référence Git nommée à un état précis.
  • ABI : contrat binaire ; l'ABI interne des modules Linux n'est pas garantie stable entre noyaux.

Dépannage rapide
  • « No rule to make target » : mauvais dossier, cible inexistante ou chemin erroné.
  • « ncurses ... not found » : dépendances de menuconfig absentes.
  • Option introuvable : rechercher son symbole et contrôler les dépendances.
  • .config disparu : avez-vous lancé mrproper, ou oublié O= ?
  • Module invalide au chargement : vérifier d'abord noyau cible, version, architecture, options et signature requise.

Documentation officielle à consulter
https://www.kernel.org/ — versions et sources officielles
https://docs.kernel.org/kbuild/kconfig-language.html — langage Kconfig
https://docs.kernel.org/kbuild/kconfig.html — outils de configuration
https://docs.kernel.org/kbuild/makefiles.html — règles Kbuild
https://docs.kernel.org/kbuild/modules.html — modules externes
https://docs.kernel.org/process/2.Process.html — processus de développement

Return to “Kernel Linux”

Who is online

Users browsing this forum: No registered users and 1 guest