Première approche de la compilation du noyau
Avant d'entamer la compilation, il convient d'installer la bibliothèque de compression nécessaire sur le système Debian/Ubuntu :
sudo apt-get install lzop
La séquence de compilation pour une plateforme ARM s'enchaîne ensuite ainsi :
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make distclean
make imx_v7_defconfig
make menuconfig
make all -j$(nproc)
La configuraton par défaut imx_v7_defconfig s'applique via l'outil conf du système Kconfig :
scripts/kconfig/conf --defconfig=arch/arm/configs/imx_v7_defconfig Kconfig
L'interface graphique de configuration permet d'ajuster les options du noyau. Une fois les modifications terminées, la sortie de menuconfig déclenche automatiquement la compilation complète.
Nettoyage et préparation de l'environnement
La cible distclean effectue un nettoyage exhaustif. En mode verbeux (V=1), on observe l'invocation récursive de scripts/Makefile.clean sur chaque sous-répertoire du projet :
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean V=1
Le processus parcourt l'ensemble de l'arborescence — des pilotes matériels aux systèmes de fichiers, en passant par les couches réseau et le sous-système son — pour éliminer les artefacts de compilation précédents. Les fichiers nettoyés incluent les tables de symboles, les images intermédiaires compressées, et les fichiers objet générés.
Génération de la configuration
L'étape defconfig construit les outils nécessaires puis génère le fichier .config final :
make -f ./scripts/Makefile.build obj=scripts/basic
make -f ./scripts/Makefile.build obj=scripts/kconfig imx_v7_defconfig
Les outils fixdep et conf sont compilés à la volée. Le script conf parse ensuite l'ensemble des Kconfig pour produire la configuration définitive du noyau.
Déroulement de la compilation complète
La phase all débute par la génération des en-têtes et des fichiers d'offsets d'architecture. Les étapes clés se succèdent :
- Génération des wrappers d'en-têtes ARM dans
arch/arm/include/generated/asm/ - Construction des outils de traitement du Device Tree (
dtc) - Compilation du code d'initialisation (
init/) - Assemblage du code d'entrée du noyau et des routines VFP
- Construction du VDSO (Virtual Dynamic Shared Object)
- Compilation du code spécifique à la machine (
arch/arm/mach-imx/)
Le système de construction continue avec les sous-systèmes fondamentaux : gestion mémoire (mm/), systèmes de fichiers (fs/), pilotes de périphériques (drivers/), et pile réseau (net/).
Structure de l'arborescence du noyau
| Répertoire | Contenu fonctionnel |
|---|---|
arch/ |
Code dépendant de l'architecture (ARM, x86, etc.) |
block/ |
Gestion des périphériques à blocs |
crypto/ |
Algorithmes cryptographiques |
Documentation/ |
Documentation technique |
drivers/ |
Pilotes de périphériques organisés par catégorie |
firmware/ |
Images de micro-logiciel |
fs/ |
Implémentations des systèmes de fichiers |
include/ |
En-têtes du noyau |
init/ |
Code d'initialisation du noyau |
ipc/ |
Mécanismes de communication inter-processus |
kernel/ |
Code principal du noyau |
lib/ |
Routines utilitaires |
mm/ |
Gestion de la mémoire virtuelle |
net/ |
Pile réseau |
samples/ |
Exemples de code |
scripts/ |
Scripts et outils de construction |
security/ |
Modules de sécurité |
sound/ |
Sous-système audio |
tools/ |
Outils utilitaires |
usr/ |
Génération de l'initramfs |
virt/ |
Virtualisation (KVM) |
Configuration de l'environnement VSCode
Pour faciliter la navigation dans les sources, un fichier .vscode/settings.json filtre les éléments superflus :
{
"search.exclude": {
"**/*.o": true,
"**/*.su": true,
"**/*.cmd": true,
"arch/alpha": true,
"arch/arc": true,
"arch/arm64": true,
"arch/avr32": true,
"arch/[b-z]*": true,
"arch/arm/plat*": true,
"arch/arm/mach-[a-h]*": true,
"arch/arm/mach-[n-z]*": true,
"arch/arm/mach-i[n-z]*": true,
"arch/arm/mach-m[e-v]*": true,
"arch/arm/mach-k*": true,
"arch/arm/mach-l*": true
},
"files.exclude": {
"**/.git": true,
"**/*.o": true,
"**/*.su": true,
"**/*.cmd": true
}
}
Analyse du Makefile principal
Identification de la version
VERSION = 4
PATCHLEVEL = 1
SUBLEVEL = 15
EXTRAVERSION =
Options de contrôle du make
MAKEFLAGS += -rR --include-dir=$(CURDIR)
L'option -rR désactive les règles implicites et les variables intégrées, garantissant un environnnement de construction prévisible.
Gestion de la verbosité
Le comportement silencieux s'active via make -s ou la variable silent, supprimant l'affichage des commandes exécutées.
Variables d'inclusion des en-têtes
USERINCLUDE := \
-I$(srctree)/arch/$(hdr-arch)/include/uapi \
-I$(srctree)/arch/$(hdr-arch)/include/generated/uapi \
-I$(srctree)/include/uapi \
-I$(objtree)/include/generated/uapi \
-include $(srctree)/include/linux/kconfig.h
LINUXINCLUDE := \
-I$(srctree)/arch/$(SRCARCH)/include \
-I$(objtree)/arch/$(SRCARCH)/include/generated \
$(USERINCLUDE)
Export des symboles de construction
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE
export AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP
export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
Mécanisme de configuration defconfig
L'invocation make imx_v7_defconfig déclenche la chaîne suivante :
- Détermination des cibles de configuration (
config-targets=1) - Construction des outils de base (
scripts_basic) - Exécution via
scripts/Makefile.build
Cible scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
Qui s'expanse en :
make -f ./scripts/Makefile.build obj=scripts/basic
Logique de construction générique
Le fichier scripts/Makefile.build constitue le cœur du système de compilation. Pour un objet donné, il détermine :
kbuild-dir: le répertoire source réelkbuild-file: le Makefile spécifique du module- Les cibles à construire (
builtin-target,lib-target,extra-y, etc.)
Génération finale du fichier .config
La règle finale s'exprime comme :
%_defconfig: scripts/kconfig/conf
$(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ Kconfig
L'outil conf lit la configuration par défaut spécifiée et matérialise toutes les options dans le fichier .config à la racine des sources.
Options de compilation modulaires
Flags locaux au Makefile courant
ccflags-y # Options du compilateur C
asflags-y # Options de l'assembleur
ldflags-y # Options de l'éditeur de liens
Ces variables n'affectent que le Makefile où elles sont définies, sans propagation aux sous-répertoires.
Flags propagés dans la hiérarchie
subdir-ccflags-y # Options GCC pour le répertoire et ses descendants
subdir-asflags-y # Options assembleur pour le répertoire et ses descendants
Flags spécifiques par module objet
CFLAGS_module.o = -DCONFIG_FEATURE_X # Définit un symbole pour module.o uniquement
AFLAGS_entry.o = -march=armv7-a # Options d'assemblage spécifiques
Production des artefacts finaux
La compilation aboutit à plusieurs livrables essentiels :
| Artefact | Description |
|---|---|
vmlinux |
Image ELF non compressée du noyau |
arch/arm/boot/Image |
Image binaire brute |
arch/arm/boot/zImage |
Image auto-extractible compressée |
arch/arm/boot/dts/*.dtb |
Binaires de description matérielle |
*.ko |
Modules chargeables |
Le processus final d'assemblage de l'image compressée implique la chaîne :
OBJCOPY arch/arm/boot/Image
LZO arch/arm/boot/compressed/piggy.lzo
AS arch/arm/boot/compressed/piggy.lzo.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Les modules sont ensuite traités en deux phases : compilation des sources, puis construction des fichiers .ko via MODPOST et ld -r pour la résolution des symboles.