Si tout comme moi vous souhaitez faire de la programmation bas niveau, il vous faudra un jour ou l’autre comprendre comment fonctionne le noyau Linux.
Dans ce post je vais donc expliquer comment compiler puis installer un noyau Linux pour faire du kernel debugging et tout pleins de choses cool.
Pré-requis :
- Une distribution Linux pour compiler le kernel
- GCC, make, git, libncurses5-dev, bc
- Savoir dompter la ligne de commande
Si vous n’avez pas de machine de test à utiliser ou que vous avez peur d’endomager la partie hardware, je vous conseille de passer par une machine virtuelle (VM) avec Virtual Box.
J’ai eu quelques problèmes avec VMware lors de l’installation des initramfs.
Dans mon cas je vais utiliser un vieux MAcBook de 2008 qui tourne sous Ubuntu 16.04 x86_64.
Préparation
Dans un premier temps il faut récuperer les fichiers source du noyau. Si vous êtes un aventurier vous pouvez les récuperer directement sur la branche Master de Github : git clone https://github.com/torvalds/linux
Sinon vous allez récuperer une version stable depuis kernel.org.
Dans notre cas on va prendre la dernière version stable à ce jour : 4.11.8
$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.11.8.tar.xz
Puis nous désarchivons l’archive contenant les sources du noyau Linux 4.11.8.
$ tar Jxvf linux-4.11.8.tar.xz
Enfin rendez-vous dans le repertoire de Linux : cd linux-4.11.8
.
Compilation
Nous somme maintenant dans le repertoire du kernel que nous allons utiliser.
Assurez-vous d’avoir bien installé tous les outils dans les pré-requis.
Nous allons premièrement créer un fichier .config
qui enregistre toutes les options de compilation du noyau. Pour ce faire lancez la commande make defconfig
.
L’option defconfig
permet de générer un fichier de configuration par défaut pour l’architecture de votre processeur.
1
2
3
4
5
6
7
$ make defconfig
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
*** Default configuration is based on 'x86_64_defconfig'
#
# configuration written to .config
#
Puis nous allons modifier les options de compilation du Makefile. Lancez un make menuconfig
.
1
2
3
4
5
6
7
8
9
10
$ make menuconfig
HOSTCC scripts/kconfig/mconf.o
HOSTCC scripts/kconfig/lxdialog/checklist.o
HOSTCC scripts/kconfig/lxdialog/util.o
HOSTCC scripts/kconfig/lxdialog/inputbox.o
HOSTCC scripts/kconfig/lxdialog/textbox.o
HOSTCC scripts/kconfig/lxdialog/yesno.o
HOSTCC scripts/kconfig/lxdialog/menubox.o
HOSTLD scripts/kconfig/mconf
scripts/kconfig/mconf Kconfig
Vous devriez avoir une interface ncurses comme ceci :
Pour ma part il faut que j’ajoute quelques drivers pour le trackpad de mon Macbook
Je vais aussi demander la compilation du kernel avec KGDB pour le kernel debugging en activant les options que ceci :
N’hésitez pas à tester des options pour la compilation du noyau sur votre VM.
Dès que vous avez configuré comme bon vous semble le fichier .config
nous pouvons lancer la compilation avec make
.
Pour gagner du temps j’utilise tous les coeurs de mon processeur pour effectuer plusieurs jobs à la fois ce qui permet au Makefile de compiler n objets à la fois (n = nombre de coeurs).
Vous pouvez utiliser la commande nproc
pour vous assurer du nombre de coeurs que vous avez à votre disposition
1
2
$ nproc
2
Dans mon cas je n’ai que 2 coeurs sur ma machine. Lançons la compilation comme ceci :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ make -j $(nproc)
scripts/kconfig/conf --silentoldconfig Kconfig
SYSTBL arch/x86/entry/syscalls/../../include/generated/asm/syscalls_32.h
CHK include/config/kernel.release
UPD include/config/kernel.release
WRAP arch/x86/include/generated/asm/clkdev.h
WRAP arch/x86/include/generated/asm/dma-contiguous.h
WRAP arch/x86/include/generated/asm/early_ioremap.h
WRAP arch/x86/include/generated/asm/mcs_spinlock.h
WRAP arch/x86/include/generated/asm/mm-arch-hooks.h
CHK include/generated/uapi/linux/version.h
UPD include/generated/uapi/linux/version.h
CHK include/generated/utsrelease.h
UPD include/generated/utsrelease.h
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
[...]
OBJCOPY arch/x86/boot/vmlinux.bin
AS arch/x86/boot/header.o
LD arch/x86/boot/setup.elf
OBJCOPY arch/x86/boot/setup.bin
BUILD arch/x86/boot/bzImage
Setup is 15836 bytes (padded to 15872 bytes).
System is 10415 kB
CRC db999948
Kernel: arch/x86/boot/bzImage is ready (#1)
En fonction de la configuration hardware de votre machine virtuelle ou physique cela peut prendre ou plus ou moins du temps.
Installation
Dès que la compilation est terminée nous pouvons installer les nouveaux modules :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ sudo make modules_install
INSTALL drivers/input/mouse/appletouch.ko
INSTALL drivers/input/mouse/bcm5974.ko
INSTALL drivers/input/mouse/cyapatp.ko
INSTALL drivers/input/mouse/sermouse.ko
INSTALL drivers/thermal/x86_pkg_temp_thermal.ko
INSTALL fs/efivarfs/efivarfs.ko
INSTALL lib/crc-itu-t.ko
INSTALL net/ipv4/netfilter/ipt_MASQUERADE.ko
INSTALL net/ipv4/netfilter/iptable_nat.ko
INSTALL net/ipv4/netfilter/nf_log_arp.ko
INSTALL net/ipv4/netfilter/nf_log_ipv4.ko
INSTALL net/ipv4/netfilter/nf_nat_ipv4.ko
INSTALL net/ipv4/netfilter/nf_nat_masquerade_ipv4.ko
INSTALL net/ipv6/netfilter/nf_log_ipv6.ko
INSTALL net/netfilter/nf_log_common.ko
INSTALL net/netfilter/nf_nat.ko
INSTALL net/netfilter/nf_nat_ftp.ko
INSTALL net/netfilter/nf_nat_irc.ko
INSTALL net/netfilter/nf_nat_sip.ko
INSTALL net/netfilter/xt_LOG.ko
INSTALL net/netfilter/xt_addrtype.ko
INSTALL net/netfilter/xt_mark.ko
INSTALL net/netfilter/xt_nat.ko
DEPMOD 4.11.8
Nous avons installé les nouveaux modules. Il ne nous reste plus qu’à générer un initrd pour notre noyau et installer le kernel et autres composants essentiels avec la commande make install
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ sudo make install
sh ./arch/x86/boot/install.sh 4.11.8 arch/x86/boot/bzImage \
System.map "/boot"
run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 4.11.8 /boot/vmlinuz-4.11.8
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 4.11.8 /boot/vmlinuz-4.11.8
update-initramfs: Generating /boot/initrd.img-4.11.8
run-parts: executing /etc/kernel/postinst.d/pm-utils 4.11.8 /boot/vmlinuz-4.11.8
run-parts: executing /etc/kernel/postinst.d/unattended-upgrades 4.11.8 /boot/vmlinuz-4.11.8
run-parts: executing /etc/kernel/postinst.d/update-notifier 4.11.8 /boot/vmlinuz-4.11.8
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 4.11.8 /boot/vmlinuz-4.11.8
Generating grub configuration file ...
Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.
Found linux image: /boot/vmlinuz-5.9.0
Found initrd image: /boot/initrd.img-5.9.0
Found linux image: /boot/vmlinuz-4.11.8
Found initrd image: /boot/initrd.img-4.11.8
Found linux image: /boot/vmlinuz-4.9.0
Found initrd image: /boot/initrd.img-4.9.0
Found linux image: /boot/vmlinuz-4.9.0.old
Found initrd image: /boot/initrd.img-4.9.0
Found linux image: /boot/vmlinuz-4.4.0-72-generic
Found initrd image: /boot/initrd.img-4.4.0-72-generic
Found linux image: /boot/vmlinuz-4.4.0-38-generic
Found initrd image: /boot/initrd.img-4.4.0-38-generic
Found linux image: /boot/vmlinuz-4.4.0-21-generic
Found initrd image: /boot/initrd.img-4.4.0-21-generic
done
Ok tout est bon, pour appliquer le nouveau kernel à votre distribution Linux, il suffit de redemarrer avec la commande reboot
en tant que root.
Pour vérifier l’application du nouveau noyau fraichement compilé on utilise la commande uname
comme ceci :
1
2
$ uname -a
Linux kernel-dev 4.11.8 #1 SMP Sun Jul 2 12:04:58 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
On voit bien que les changements ont été appliqués car c’est bel et bien la version correspondant au noyau que nous avons récupéré sur kernel.org. Nous pouvons aussi comparer le date de compilation avec la date courante :
1
2
$ date
Sun Jul 2 12:12:32 EDT 2017
Celle-ci correspond bien, donc tout est bon.
Pour conclure, la compilation du noyau Linux et une étape importante à comprendre pour ensuite se lancer plus profondement dans la programmation kernel et bas niveau.
Si vous souhaitez en savoir plus sur le noyau Linux, je vous invite à jeter un oeil au Gitbook de 0xax : Linux Insides.
Ce E-Book gratuit explique les concepts du noyau, du démarrage de celui-ci à la gestion de mémoire en passant pas les Syscalls.
Si vous avez besoin d’infos contactez-moi sur twitter: @matteyeux
Github : https://github.com/matteyeux