II. Cross-compilation: Initrd/Initramfs

Il faut préciser que l’installation d’un système linux sur un serveur NAS Buffalo LS-XL pose quelques contraintes, qui ne sont pas des moindre: Il n’y a ni port USB, ni lecteur CD dessus. On ne va compter que sur le port ethernet, sur lequel il va falloir donc tout faire.
De plus, pour compliquer un peu plus l’installation, le chargeur de démarrage (bootloader, U-Boot pour les systèmes embarqués) n’offre aucune possibilité de gérer les séquences de boot. Démarrer son système à partir du disque dur interne est le SEUL choix offert.
Par contre, en l’absence de disque dur, le serveur essaie tout de même de démarrer le système à partir des informations de la mémoire RAM, plus précisément, dans le ramdisk (disque virtuel). Et c’est là où se repose l’astuce. Nous allons utiliser cette “faille” pour y installer temporairement dans la RAM, un système linux qui va prendre en charge l’installation du système d’exploitation (ici, un Debian). C’est exactement le même procédé qui est utilisé par les live Cds.
Le système chargé dans le ramdisk se lance avec le stricte minimum, met en cache les programmes dont il a besoin (ls, cp, mount, etc.), et tout ça, sans avoir besoin d’accéder à un disque dur physique. Par contre, il faut faire attention à mettre tout le système en mémoire sinon, on aurait un kernel panic en l’absence de disque dur.

Pour rappel, un système sous linux a besoin de deux chose pour pouvoir se lancer:
– Un noyau (uImage)
– Un système de fichier root (rootfs, ou /) contenant le programme init.

Grâce à l’image initrd (INITial Ram Disk), le bootloader peut l’utiliser pour charger tous les outils nécessaire au ramdisk afin d’y monter le rootfs. Il est important de noter que l’ajout ou la suppression de pilotes (drivers), compilés en modules (LKM), dans Initrd ne nécessite pas de compilation du noyau.

Pour mieux comprendre l’intérêt de l’initrd lors du boot, je vous ai copié un extrait de la documentation de initrd.txt.

When using initrd, the system typically boots as follows:

1) the boot loader loads the kernel and the initial RAM disk
2) the kernel converts initrd into a « normal » RAM disk and
frees the memory used by initrd
3) if the root device is not /dev/ram0, the old (deprecated)
change_root procedure is followed. see the « Obsolete root change
mechanism » section below.
4) root device is mounted. if it is /dev/ram0, the initrd image is
then mounted as root
5) /sbin/init is executed (this can be any valid executable, including
shell scripts; it is run with uid 0 and can do basically everything
init can do).
6) init mounts the « real » root file system
7) init places the root file system at the root directory using the
pivot_root system call
8) init execs the /sbin/init on the new root filesystem, performing
the usual boot sequence
9) the initrd file system is removed

Note that changing the root directory does not involve unmounting it.
It is therefore possible to leave processes running on initrd during that
procedure. Also note that file systems mounted under initrd continue to
be accessible.

Traduction

Quand on utilise initrd, la procédure de boot type du système est la suivante:

1) le bootloader charge le noyau et l’initrd
2) le noyau convertit l’initrd en disque RAM “normal” et libère la mémoire occupée par initrd
3) si le périphérique root n’est pas dans /dev/ram0, l’ancienne procédure (obsolète) change_root est suivie
4) le périphérique racine (root) est monté. Si c’est /dev/ram0, alors l’image initrd est monté comme root
5) /sbin/init est exécuté
6) init monte (mount) le “vrai” système de fichier racine
7) init place le système de fichier root comme répertoire racine
8) init exécute /sbin/init dans le nouveau système de fichier, en performant la séquence de boot habituelle
9) le système de fichier initrd est supprimé

Noter que le changement de répertoire racine ne nécessite pas de le démonter (unmount). Il est donc possible de laisser les processus dans initrd tourner durant toute la procédure. A noter également que les systèmes de fichiers montés sous initrd continuent à être accessible.

Ce qu’il faut retenir de ce texte est que, l’initrd est le rootfs (système de fichier) temporaire.

1. Téléchargement de l’installeur initramfs pour debian

Télécharger le fichier initrd.buffalo, puis le renommer en orig_uImage.

/opt/nasbuild# mkdir initramfs

/opt/nasbuild# cd initramfs/

/opt/nasbuild/initramfs# wget _http://http.debian.net/debian/dists/unstable/main/installer-armel/current/images/orion5x/network-console/buffalo/ls-chl/initrd.buffalo -O orig_uImage
!—–Tronquée—–!
orig_uImage 100%[=====================>] 6.58M 3.09MB/s in 2.1s

2015-10-16 19:16:51 (3.09 MB/s) – ‘orig_uImage’ saved [6897551/6897551]

2. Initrd/initramfs

Apparement – Je n’ai pas vérifié cette information en faisant des tests de mon côté, mais je la prends comme argent comptant – le serveur NAS ne peut pas booter correctement avec l’image fournie par Debian (initrd.buffallo), qui est une image initramfs. Il nous faut donc convertir cette image en image initrd.

Etape 1. Extraction du contenu de l’initramfs

L’image initramfs est une image compressée de l’archive cpio au format bzip ou gzip. La commande “file” permet de donner sous quel méthode de compression a été utilisée.

/opt/nasbuild/initramfs$ ls
orig_uImage
/opt/nasbuild/initramfs$ file orig_uImage
orig_uImage: u-boot legacy uImage, debian-installer ramdisk, Linux/ARM, RAMDisk Image (gzip), 6897487 bytes, Fri Sep 11 01:02:57 2015, Load Address: 0x02000000, Entry Point: 0x02000000, Header CRC: 0xFCFF08CF, Data CRC: 0x6B9B8156

#Extraire l’image gzippé de l’initramfs
/opt/nasbuild/initramfs# dd if=orig_uImage ibs=64 skip=1 | zcat > orig_initramfs.cpio

La commande dd est utilisée pour dupliquer le fichier d’origine orig_uImage, mais sans le header. Pour en savoir un peu plus sur la commande dd, je vous renvoie à cet article, puis celle-là.

Les options “ibs=64” et “skip=1” suppriment tout ce qui se trouve sur les 64 premiers bits de ce fichier.

La commande « zcat », tout comme « gunzip -c », décompresse le fichier sans supprimer le fichier d’origne.
Pour résumer, l’image initrd.buffalo (uRamdisk) est une archive cpio compressée au format gzip, et contient:
– Un header (64 premiers octets)
– Une image du ramdisk

Quand on parle de “kernel header” (ou tout simplement, “header”), on fait référence au code source du noyau. C’est ce dont on a besoin pour (re)compiler n’importe quel module.
Petite parenthèse, vous avez certainement entendu parlé de header lors de la virtualisation, avec des problèmes de “header not found” par exemple.
Ce header n’étant pas nécessaire pour démarrer notre système, on peut donc s’en passer en le supprimant de l’image orig_initramfs.cpio.

Etape 2. Création et montage du RAMDISK

Il nous faut maintenant créer un ramdisk (disque virtuelle) initrd, de taille fixe (bloc) égale à 20 Mo dans la mémoire (RAM). Initrd sera donc contenu dans un bloc. On parlera de “block storage”, qu’il faut formater avec un système de fichier (ext2, le système de fichier par défaut pour Initrd) avant de pouvoir le monter. Mkfs est l’outil qu’il nous faut pour le faire.

# Creation du ramdisk de 20 Mo
/opt/nasbuild/initramfs# dd if=/dev/zero of=initrd bs=1M count=20
/opt/nasbuild/initramfs# /sbin/mkfs.ext2 initrd
/opt/nasbuild/initramfs# ls -l
total 24092
-rw-r–r– 1 root root 20971520 Nov 4 23:08 initrd
-rw-r–r– 1 root root 16925184 Nov 4 23:04 orig_initramfs.cpio
-rw-r–r– 1 root root 6897551 Sep 11 01:02 orig_uImage

“A l’origine, l’initrd ou initramfs a essentiellement pour but d’accomplir les opérations préalables au montage du système de fichiers racine, notamment en chargeant les modules nécessaires s’ils ne sont pas compilés en dur dans le noyau. Cela permet de créer un noyau polyvalent mais léger sans mettre tous les pilotes en dur”. (Lu sur le site debian-fr.org démarrer sans image initramfs)

Pour rappel, initrd est une image de disque, compressée puis gzippée, de type bloc. Un des problèmes que ce type d’image peut poser est, l’espace mémoire inutilisé par le ramdisk ne peut être assigné ailleurs. De plus, si le disque virtuel est trop plein, bien qu’il y a encore assez d’espace sur l’ensemble de la RAM, il n’est pas possible d’augmenter la taille du ramdisk sans avoir à le reformater, puis refaire le disque. Il faut donc bien prévoir à l’avance la taille du disque virtuel pour éviter ce genre de problème.
Pour information, l’image du rootfs doit absolument être de taille inferieure à la RAM, à laquelle on soustrait la taille de la mémoire qu’occupe le système en pleine charge. Il faut garder en mémoire cette règle, surtout quand on essaie d’installer un système linux sur un système embarqué ayant très peu de mémoire.
Ce qu’il faut aussi savoir, c’est que, primo, initramfs est le successeur de initrd depuis la version 2.6 du noyau Linux. Initramfs est une archive de type cpio, et non de type bloc comme pour initrd.
Secondo, initrd sert en tant que système de fichier principal temporaire monté dans la RAM, avec le noyau, le couple initrd/noyau permet de démarrer un système sans avoir à monter un disque physique.

Si vous voulez savoir un peu plus la différence entre initramfs et initrd, je vous propose de lire cette article puis celle là.

# montage du ramdisk
/opt/nasbuild/initramfs# mkdir rootfs
/opt/nasbuild/initramfs# mount initrd rootfs

Pour avoir la liste des fichiers montés, je vous propose les commandes “lsblk” (LiSt BLock device: disque dur, CDRom, etc.) puis “fdisk -l”.
~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 10M 0 part
├─sda3 8:3 0 18.7G 0 part /
├─sda4 8:4 0 7.7G 0 part [SWAP]
└─sda5 8:5 0 439.3G 0 part /home
sr0 11:0 1 1024M 0 rom
loop0 7:0 0 20M 0 loop /opt/nasbuild/initramfs/rootfs

# fdisk -l
Disk /dev/sda: 465.8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 21D716B8-4FA6-41C3-8441-0B1B39B326FC

Device Start End Sectors Size Type
/dev/sda1 2048 4095 2048 1M BIOS boot
/dev/sda2 4096 24575 20480 10M Linux filesystem
/dev/sda3 24576 39282687 39258112 18.7G Linux filesystem
/dev/sda4 39282688 55492607 16209920 7.7G Linux swap
/dev/sda5 55492608 976771071 921278464 439.3G Linux filesystem

Disk /dev/loop0: 20 MiB, 20971520 bytes, 40960 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Etape 3. Extraction du contenu de initramfs

Il faut ensuite extraire le contenu du fichier orig_initramfs.cpio, qui pour rappel, est une image initramfs. Puis placer le fichier extrait dans le ramdisk de taille 20 Mo, formaté en EXT2.

#extraire le fichier initramfs gzippé et le placer dans le ramdisk
/opt/nasbuild/initramfs# cd rootfs
/opt/nasbuild/initramfs/rootfs# cpio -idv < ../orig_initramfs.cpio
!—–Tronquée—–!
33057 blocks

Il y a trois modes (option) pour cpio. Celui qui nous intéresse ici est l’option -i. Cette option offre la possibilité de créer des archives à partir de nos fichiers, que l’on placera ensuite dans le rootfs qui est notre système de fichier.
L’option -v (verbose, ou bavard en français), offre la possibilité au cpio d’afficher à l’écran ce qui se passe. On devrait voir les informations sur l’extraction, l’archivage, et la copie du fichier orig_initramfs.cpio.
Il faut rajouter l’option -d au cpio, puisque par défaut, cpio ne crée pas de dossier. Il faut donc le lui dire d’en créer un, si c’est nécessaire.

Voyons maintenant le contenu du dossier rootfs.

/opt/nasbuild/initramfs/rootfs# ls
bin etc initrd lost+found mnt run sys usr
dev init lib media proc sbin tmp var

Etape 4. Mise à jour des modules

Durant cette étape, nous allons remplacer tous les modules du rootfs par ceux créés avec le noyau dans la première partie du chapitre.

/opt/nasbuild/initramfs/rootfs# rm -rfv lib/modules/*
/opt/nasbuild/initramfs/rootfs# cd ../../linux-3.3.4/
/opt/nasbuild/linux-3.3.4# make INSTALL_MOD_PATH=../initramfs/rootfs/ modules_install
/opt/nasbuild/linux-3.3.4# cd ../initramfs/rootfs/

Après avoir supprimé les modules de l’initramfs, la commande MAKE nous permet de compiler de nouveaux modules, basés sur le noyau construit dans le chapitre précédent.

Etape 5. Configuration automatique

Il nous faut maintenant créer un fichier préconfiguré (preseed.cfg) dans le dossier rootfs, afin d’automatiser une partie de l’installation.

/opt/nasbuild/initramfs/rootfs# cat << EOF > preseed.cfg
d-i lowmem/low note

d-i netcfg/get_hostname string unassigned-hostname
d-i netcfg/get_domain string unassigned-domain

d-i network-console/password password rootme
d-i network-console/password-again password rootme
EOF

/opt/nasbuild/initramfs/rootfs# ls
bin etc initrd lost+found mnt proc sbin tmp var
dev init lib media preseed.cfg run sys usr

Il nous fallait ce script pour activer l’installation à distance via le service SSH. Vous pouvez modifier le mot de passe rootme dans ce fichier, par un autre de votre choix. Ce mot de passe vous sera demandé lors de la connection à l’installeur de Debian.

Etapte 6. Démonter (unmount) le système de fichier et empaquetter l’initrd

/opt/nasbuild/initramfs/rootfs# cd ..

# finalisation
/opt/nasbuild/initramfs/# umount rootfs

~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 10M 0 part
├─sda3 8:3 0 18.7G 0 part /
├─sda4 8:4 0 7.7G 0 part [SWAP]
└─sda5 8:5 0 439.3G 0 part /home
sr0 11:0 1 1024M 0 rom

/opt/nasbuild/initramfs/# gzip initrd

Il ne nous reste plus qu’à générer la nouvelle image ramdisk, avec la commande mkimage.

#Générer une image Ramdisk initrd.buffalo
/opt/nasbuild/initramfs/# mkimage -A arm -O linux -T ramdisk -C gzip -a 0x0 -e 0x0 -n initrd -d initrd.gz initrd.buffalo

Et voilà, notre nouvel image initrd, en remplacement de initramfs, est enfin prêt.

Résumé des différentes étapes de la création de la création d’initrd

#Telechager l’image initrd.buffalo
/opt/nasbuild# mkdir initramfs
/opt/nasbuild# cd initramfs/
/opt/nasbuild/initramfs# wget _http://http.debian.net/debian/dists/unstable/main/installer-armel/current/images/orion5x/network-console/buffalo/ls-chl/initrd.buffalo -O orig_uImage

#Copier l’image sans le header
/opt/nasbuild/initramfs# dd if=orig_uImage ibs=64 skip=1 | zcat > orig_initramfs.cpio

#Creer un ramdisk de 20 Mo
/opt/nasbuild/initramfs# dd if=/dev/zero of=initrd bs=1M count=20
/opt/nasbuild/initramfs# /sbin/mkfs.ext2 initrd

#Monter le ramdisk
/opt/nasbuild/initramfs# mkdir rootfs
/opt/nasbuild/initramfs# mount initrd rootfs

#Copier l’archive dans le systeme de fichier rootfs
/opt/nasbuild/initramfs# cd rootfs
/opt/nasbuild/initramfs/rootfs# cpio -idv < ../orig_initramfs.cpio

#Supprimer les modules du rootfs
/opt/nasbuild/initramfs/rootfs# sudo rm -fr lib/modules/*

# Copier les modules construit avec le noyau
/opt/nasbuild/initramfs/rootfs# cd ../../linux-3.3.4/
/opt/nasbuild/linux-3.3.4# sudo make INSTALL_MOD_PATH=../initramfs/rootfs/ modules_install

/opt/nasbuild/linux-3.3.4# cd ../initramfs/rootfs/

#Créer le fichier preseed.cfg avec les informations ci-dessous
/opt/nasbuild/initramfs/rootfs# cat << EOF > preseed.cfg
d-i lowmem/low note

d-i netcfg/get_hostname string unassigned-hostname
d-i netcfg/get_domain string unassigned-domain

d-i network-console/password password rootme
d-i network-console/password-again password rootme
EOF

#Démonter le système de fichier en empaqueter le nouveau initrd
/opt/nasbuild/initramfs/rootfs# cd ..

#Finalisation
/opt/nasbuild/initramfs/# sudo umount rootfs
/opt/nasbuild/initramfs/# gzip initrd

#Générer la nouvelle image Ramdisk initrd.buffalo
/opt/nasbuild/initramfs/# mkimage -A arm -O linux -T ramdisk -C gzip -a 0x0 -e 0x0 -n initrd -d initrd.gz initrd.buffalo

Sources:

Ce que je trouve génial sur la documentation de linux, c’est qu’il n’y a pas de date de péremption. Certe, certains documents datent un peu, mais on peut toujours les accomoder à nos besoins.

[Debian] Programme en cache
[Debian] Création d’un initramfs
What is the difference between initrd and initramfs?
https://wiki.debian.org/fr/Initrd
Hacking RAM disks
What is ramfs?
[Debian] démarrer sans image initramfs
How to View, Modify and Recreate initrd.img
How to create your own initial ram disk (initrd)
Chapter 1. Linux Filesystem Hierarchy – 1.8. /initrd
What is Initrd Image ? How To Create Initrd Image In Linux
initrd, modules, and tools
GNU Make
HowTo Repack root filesystem (ramdisk)
Tuning dd block size
What Are Kernel Headers?
Forum Linux.noyau comprendre le lien entre les headers du noyau et les modules

Publicités

I. Cross-Compilation: Création du noyau

Tentative d’installation d’un Debian sur un serveur NAS Buffalo LS-XL

Il y a quatre étapes pour l’installation d’un système Debian sur un serveur NAS Buffalo LS-XL. Je précise que j’utilise aussi Debian sur le système hôte.

Dans un premier temps, il faut créer deux modules, un noyau et un initramfs (ou initrd), pour pouvoir démarrer le serveur NAS avec nos propres configurations. Ceux installés sur le serveur ne nous permet pas d’installer un autre système d’exploitation que celui livré par défaut.

Ensuite il nous faut un serveur TFTP pour y placer tout ce dont on a besoin pour l’amorçage du serveur à partir du réseau. Bien entendu, il y aura besoin d’un système hôte pour accéder à distance au contenu du serveur, et y installer le système d’exploitation.

En dernier, il nous faut de nouveau créer un nouveau noyau pour pouvoir commencer cette fois ci, l’installation de Debian sur le serveur NAS puisqu’il n’y en a pas de noyau sur mesure pour les serveurs LS-XL sur le site officiel de Debian.

Avant de commencer les manipulations, je vous propose de lire entièrement cet article, puis de comprendre ce qu’il faut faire et ensuite. Les étapes intermédiaires, comme par exemple accéder à un dossier, ne seraient pas toujours affichés dans la liste des commandes à taper. Cependant, pour vous aider à vous situer dans les différents répertoires, j’ai placé leurs noms avant chaque commande (ex. /opt/nasbuild# ). Le dièse “#” implique que les commandes doivent être effectuées en mode root.

Je tiens à préciser qu’on ne partira pas d’un construction d’un noyau à partir de rien. Le noyau sur lequel on va se baser serait la version 3.3.4 disponible sur le site officiel de Buffalo, et qui devrait être compatible avec les serveurs LS-XL.

I. Cross-Compilation: compilation du noyau

Dans cet article, je vais parler de la préparation d’un noyau linux compatible ARM9, à lancer lors du démarrage du serveur NAS.

Avant de parler de cross-compilation, il faut comprendre ce que c’est qu’une compilation. Si je peux le résumer ainsi, une compilation est le fait de transformer un langage compréhensible par l’homme en un langage compréhensible par une machine, en utilisant un Compilateur. Un compilateur transforme les codes sources en codes exécutables spécifique à une machine.

On parle de cross-compilation quand la machine cible, celle qui va recevoir les instructions de compilation, n’a pas la même architecture que la machine hôte, celle sur laquelle vous effectuez la compilation. Ici, je vais compiler un noyaux linux à partir d’un ordinateur MAC Intel (hôte), avec la version 3.3.4 du noyau linux, pour architecture ARM.

Dans ce qui suit, on va plutôt parler de Toolchain (chaîne de compilation), dont le compilateur n’en est qu’un élément.

Etape 1: Téléchargement de tous les tarballs nécessaire à la compilation

Les logiciels tierces, c’est à dire ceux qui ne font pas parties des logiciels par défaut dans Debian, devraient être placés dans /opt.

Note: J’ai du rajouter un tiret devant les liens en http pour éviter d’avoir des hyperliens dans les commandes à exécuter.

# cd /opt
/opt# mkdir nasbuild
/opt/nasbuild# wget _http://buffalo.jp/php/los.php?to=gpl/storage/ls-x/165/linux-3.3.4.tar.gz -O linux-3.3.4.tar.gz

Le noyaux linux fourni par Buffalo ne peut démarrer qu’avec le cross-compilateur gcc CodeSourcery arm-2007q3.

/opt/nasbuild# wget _http://downloads.nas-central.org/LSPro_ARM9/DevelopmentTools/CrossToolchains/CodeSourcery/arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu.tar.bz2

Téléchargement de Mkimage, qui est un utilitaire pour nous permettre de créer les images du noyau et de l’initrd dont on aura besoin pour la suite. On en reparlera dans un autre chapitre.

/opt/nasbuild# wget _http://downloads.nas-central.org/LSPro_ARM9/DevelopmentTools/CrossToolchains/mkimage

Etape 2: Préparation de l’environnement

Préparer l’environement en installant le compilateur et le mkimage.

/opt/nasbuild# tar -jxvf arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu.tar.bz2

/opt/nasbuild# cd arm-2007q3

/opt/nasbuild/arm-2007q3# ls -a
. .. arm-none-eabi bin include lib libexec share

/opt/nasbuild/arm-2007q3# cd bin

/opt/nasbuild/arm-2007q3/bin# cp ../../mkimage .

/opt/nasbuild/arm-2007q3/bin# chmod a+x mkimage

Copier mkimage dans /bin, rendez ce fichier exécutable, puis ajouter à la variable PATH le chemin pour y accéder.

/opt/nasbuild/arm-2007q3/bin# ls
arm-none-eabi-addr2line arm-none-eabi-gcov arm-none-eabi-readelf
arm-none-eabi-ar arm-none-eabi-gdb arm-none-eabi-run
arm-none-eabi-as arm-none-eabi-gdbtui arm-none-eabi-size
arm-none-eabi-c++ arm-none-eabi-gprof arm-none-eabi-sprite
arm-none-eabi-c++filt arm-none-eabi-ld arm-none-eabi-strings
arm-none-eabi-cpp arm-none-eabi-nm arm-none-eabi-strip
arm-none-eabi-g++ arm-none-eabi-objcopy mkimage
arm-none-eabi-gcc arm-none-eabi-objdump
arm-none-eabi-gcc-4.2.1 arm-none-eabi-ranlib

/opt/nasbuild/arm-2007q3/bin# echo “$PATH”
“/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”

/opt/nasbuild/arm-2007q3/bin# export PATH=$PATH:`pwd`

On peut avoir le même résultat avec la commande: export PATH=$PATH:$PWD.

/opt/nasbuild/arm-2007q3/bin# echo “$PATH”
“/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/nasbuild/arm-2007q3/bin

Vérifier que l’on peut lancer n’importe quelle commande située de /opt/nasbuild/arm-2007q3/bin, ceci afin de nous assurer qu’on peut lancer directement la commande mkimage plus tard dans l’article.

# arm-none-eabi-gcc –version
arm-none-eabi-gcc (CodeSourcery Sourcery G++ Lite 2007q3-53) 4.2.1
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Note: il y a deux tirets « — » devant « version ».

/opt/nasbuild# wget http://buffalo.jp/php/los.php?to=gpl/storage/ls-x/165/linux-3.3.4.tar.gz -O linux-3.3.4.tar.gz

/opt/nasbuild# tar -zxvf linux-3.3.4.tar.gz

Etape 3: Compilation du Noyau

C’est le moment de créer l’image de boot (uImage) qu’on utilisera pour démarrer le serveur NAS via le réseau.

/opt/nasbuild# cd linux-3.3.4

Dans le fichier Makefile, remplacer arm-none-linux-gnueabi- par le préfixe du compilateur arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu.tar.bz2, puis vérifier bien que “arm” est la valeur associée à ARCH.

/opt/nasbuild/linux-3.3.4# vim Makefile
!——–Tronquée————!
ARCH ?= arm
#CROSS_COMPILE ?= arm-none-linux-gnueabi-
CROSS_COMPILE ?= arm-none-eabi-
!——–Tronquée————!

Comme valeur associée au CROSS_COMPILE, on peut aussi lui donner le chemin absolue vers le toolchain ARM Linux comme suit:

CROSS_COMPILE ?= /opt/nasbuild/linux-3.3.4/bin/arm-none-eabi-

Importer, puis si nécessaire éditer les scripts Configure (./config). Deux options pour le faire:

1. Copier le fichier de configuration du noyau buffalo_nas_fw_88f6281.config dans le dossier /opt/nasbuild/linux-3.3.4.

/opt/nasbuild/linux-3.3.4# ls buffalo/configs/
buffalo_hswdhtgl_arm_100.config buffalo_nas_fw_88f6281.config
buffalo_lsgl_arm_100.config buffalo_nas_fw_88f6281_tsxel.config
buffalo_lsgl_arm_101.config buffalo_nas_fw_atom_d510_101.config
buffalo_lsgl_arm_102.config buffalo_nas_fw_atom_d510.config
buffalo_lsgl_hs_arm_100.config buffalo_nas_fw_kiri.config
buffalo_lsqgl_arm_200.config buffalo_tshtgl_arm_100.config
buffalo_lswsgl_arm_100.config buffalo_tshtgl_arm_110.config
buffalo_lswsgl_arm_200.config buffalo_tsxl_arm_100.config
buffalo_lswtgl_arm_100.config kirkwood.config
buffalo_lswtgl_arm_200.config marvell_config100.config
buffalo_lswwn_arm_200.config marvell_lsgl_100.config
buffalo_nas_fw_200.config marvell_tshtgl_100.config

Le choix du fichier de configuration buffalo_nass_fw_88f6281 n’est pas anodin. Les deux processeurs Marvell Kirkwood 88F6192 (celui de notre serveur NAS) et 88F6281, sont de la même famille et ont pratiquement les mêmes caractéristiques.

/opt/nasbuild/linux-3.3.4# cp buffalo/configs/buffalo_nas_fw_88f6281.config .config
/opt/nasbuild/linux-3.3.4# vim .config

Ci-dessous les informations qui devraient être dans le script configure, en rouge le plus important.

#CONFIG_CMDLINE
CONFIG_CMDLINE= »console=ttyS0,115200 root=/dev/ram0 panic=5 lowmem=1″
# CONFIG_CMDLINE_FROM_BOOTLOADER is not set
# CONFIG_CMDLINE_EXTEND is not set
CONFIG_CMDLINE_FORCE=y

#CONFIG_DEVTMPFS
CONFIG_DEVTMPFS=y

#CONFIG_PHONE
# CONFIG_PHONE is not set

#CONFIG_LEGACY_PTYS
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16

#CONFIG_IP_ROUTE_CLASSID
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_ROUTE_CLASSID=y

#CONFIG_HID_SUPPORT
# CONFIG_HID_SUPPORT is not set

#CONFIG_USB_SUPPORT
# CONFIG_USB_SUPPORT is not set

Metter en commentaire tout ce qui suit, c’est à dire, aux lignes contenant CONFIG_USB, il faut y ajouter un # devant:

# CONFIG_USB_

#CONFIG_RTC_CLASS
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE= »rtc0″

CONFIG_RTC_DRV_MV=y

Mettez en commentaire les autres lignes contenant CONFIG_RTC_* , et même ceux cités ci-dessus, si vous n’en voyez pas l’utilité.

En option, vous pouvez aussi ajouter les informations ci-dessous dans le même ficher .config.

#CONFIG_TEXTSEARCH
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m

2. Une autre option, au lieu d’éditer le fichier buffalo_nas_fw_88f6281.config, serait d’importer les scripts Configure disponibles ici (lsxl-install.config) ou (kernel_.config_for_ls-xl.txt ).

/opt/nasbuild/linux-3.3.4# mv lsxl-install.config .config
/opt/nasbuild/linux-3.3.4# make oldconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf –oldconfig Kconfig
#
# configuration written to .config
#

La commande MAKE s’utilise généralement avec l’option -jN (N = nombres de processeurs/core sur la machine hôte x 2), afin d’optimiser la compilation en utilisant tous les processeurs de la machine hôte.

La commande LSPCU permet d’afficher le nombre de processeurs présent sur l’ordinateur (CPU = 4). On a donc, N = 8 (4CPU x 2).

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 37
Model name: Intel(R) Core(TM) i5 CPU M 520 @ 2.40GHz
Stepping: 5
CPU MHz: 1197.000
CPU max MHz: 2395.0000
CPU min MHz: 1197.0000
BogoMIPS: 4788.41
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3072K
NUMA node0 CPU(s): 0-3

/opt/nasbuild/linux-3.3.4# make -j8 uImage
(durée de la compilation: 3 minutes)

uImage est l’image du noyau dans un format compatible u-boot.

/opt/nasbuild/linux-3.3.4# make -j8 modules
CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[1]: ‘include/generated/mach-types.h’ is up to date.
CALL scripts/checksyscalls.sh
!——–Tronquée————!
Building modules, stage 2.
MODPOST 67 modules
!——–Tronquée————!
(durée de la compilation: 1 minute)

Ces deux dernières commandes permettent de compiler le noyau ainsi que ces modules, et que l’on peut fusionner en une seule commande “make -j8 uImage modules”.

Le noyau et module nouvellement créés, sont maintenant disponible dans /opt/nasbuild/linux-3.3.4/arch/arm/boot.

/opt# tree -L 3
.
├── nasbuild
│   ├── arm-2007q3
│   │   ├── arm-none-eabi
│   │   ├── bin
│   │   ├── include
│   │   ├── lib
│   │   ├── libexec
│   │   └── share
│   ├── arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
│   ├── linux-3.3.4
│   │   ├── arch
│   │   ├── binaries
│   │   ├── block
│   │   ├── buffalo
│   │   ├── cesa
│   │   ├── COPYING
│   │   ├── CREDITS
│   │   ├── crypto
│   │   ├── Documentation
│   │   ├── drivers
│   │   ├── firmware
│   │   ├── fs
│   │   ├── include
│   │   ├── init
│   │   ├── ipc
│   │   ├── Kbuild
│   │   ├── Kconfig
│   │   ├── kernel
│   │   ├── lib
│   │   ├── LspReadme.txt
│   │   ├── LspReleaseNotes_KW.txt
│   │   ├── MAINTAINERS
│   │   ├── Makefile
│   │   ├── Makefile.88f6281
│   │   ├── Makefile.atom_d510
│   │   ├── Makefile.mv78100
│   │   ├── mm
│   │   ├── modules.builtin
│   │   ├── modules.order
│   │   ├── Module.symvers
│   │   ├── net
│   │   ├── README
│   │   ├── REPORTING-BUGS
│   │   ├── samples
│   │   ├── scripts
│   │   ├── security
│   │   ├── sound
│   │   ├── System.map
│   │   ├── tools
│   │   ├── usr
│   │   ├── virt
│   │   ├── vmlinux
│   │   └── vmlinux.o
│   ├── linux-3.3.4.tar.gz
│   └── mkimage

La prochaine étape serait de configurer initrd (initramfs) afin d’avoir les pilotes nécessaire au démarrage du serveur NAS.

 Résumé des différentes étapes de la création du Noyau

Etape 1: Téléchargement de tous les tarballs nécessaire à la compilation

/opt/nasbuild# wget _http://buffalo.jp/php/los.php?to=gpl/storage/ls-x/165/linux-3.3.4.tar.gz -O linux-3.3.4.tar.gz

/opt/nasbuild# wget _http://downloads.nas-central.org/LSPro_ARM9/DevelopmentTools/CrossToolchains/CodeSourcery/arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu.tar.bz2

/opt/nasbuild# wget _http://downloads.nas-central.org/LSPro_ARM9/DevelopmentTools/CrossToolchains/mkimage

Etape 2: Préparation de l’environnement

/opt/nasbuild# tar -jxvf arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu.tar.bz2

/opt/nasbuild/arm-2007q3/bin# cp ../../mkimage .

/opt/nasbuild/arm-2007q3# chmod a+x mkimage

/opt/nasbuild/arm-2007q3# export PATH=$PATH:`pwd`

/opt/nasbuild# wget _http://buffalo.jp/php/los.php?to=gpl/storage/ls-x/165/linux-3.3.4.tar.gz -O linux-3.3.4.tar.gz

/opt/nasbuild# tar -zxvf linux-3.3.4.tar.gz

Etape 3: Compilation du Noyau

/opt/nasbuild/linux-3.3.4# vim Makefile
!——–Tronquée————!
ARCH ?= arm
#CROSS_COMPILE ?= arm-none-linux-gnueabi-
CROSS_COMPILE ?= arm-none-eabi-
!——–Tronquée————!

Copier les scripts Configure disponibles ici (lsxl-install.config) ou (kernel_.config_for_ls-xl.txt) dans .config.

/opt/nasbuild/linux-3.3.4# mv lsxl-install.config .config
/opt/nasbuild/linux-3.3.4# make oldconfig

/opt/nasbuild/linux-3.3.4# make -j8 uImage modules

Annexe: commande MAKE

Ci-dessous, en non-grisée, la liste des options utilisées pour construire notre noyau.

# make help
Cleaning targets:
clean – Remove most generated files but keep the config and
enough build support to build external modules
mrproper – Remove all generated files + config + various backup files
distclean – mrproper + remove editor backup and patch files

Configuration targets:
config – Update current config utilising a line-oriented program
nconfig – Update current config utilising a ncurses menu based program
menuconfig – Update current config utilising a menu based program
xconfig – Update current config utilising a QT based front-end
gconfig – Update current config utilising a GTK based front-end
oldconfig – Update current config utilising a provided .config as base
localmodconfig – Update current config disabling modules not loaded
localyesconfig – Update current config converting local mods to core
silentoldconfig – Same as oldconfig, but quietly, additionally update deps
defconfig – New config with default from ARCH supplied defconfig
savedefconfig – Save current config as ./defconfig (minimal config)
allnoconfig – New config where all options are answered with no
allyesconfig – New config where all options are accepted with yes
allmodconfig – New config selecting modules when possible
alldefconfig – New config with all symbols set to default
randconfig – New config with random answer to all options
listnewconfig – List new options
oldnoconfig – Same as silentoldconfig but set new symbols to n (unset)

Other generic targets:
all – Build all targets marked with [*]
* vmlinux – Build the bare kernel
* modules – Build all modules
modules_install – Install all modules to INSTALL_MOD_PATH (default: /)
firmware_install- Install all firmware to INSTALL_FW_PATH
(default: $(INSTALL_MOD_PATH)/lib/firmware)
dir/ – Build all files in dir and below
dir/file.[oisS] – Build specified target only
dir/file.lst – Build specified mixed source/assembly target only
(requires a recent binutils and recent build (System.map))
dir/file.ko – Build module including final link
modules_prepare – Set up for building external modules
tags/TAGS – Generate tags file for editors
cscope – Generate cscope index
gtags – Generate GNU GLOBAL index
kernelrelease – Output the release version string
kernelversion – Output the version stored in Makefile
headers_install – Install sanitised kernel headers to INSTALL_HDR_PATH
(default: /opt/nasbuild/linux-3.3.4/usr)
!——–Tronquée————!
Architecture specific targets (arm):
* zImage – Compressed kernel image (arch/arm/boot/zImage)
Image – Uncompressed kernel image (arch/arm/boot/Image)
* xipImage – XIP kernel image, if configured (arch/arm/boot/xipImage)
uImage – U-Boot wrapped zImage
bootpImage – Combined zImage and initial RAM disk
(supply initrd image via make variable INITRD=)
dtbs – Build device tree blobs for enabled boards
install – Install uncompressed kernel
zinstall – Install compressed kernel
uinstall – Install U-Boot wrapped compressed kernel
Install using (your) ~/bin/installkernel or
(distribution) /sbin/installkernel or
install to $(INSTALL_PATH) and run lilo
!——–Tronquée————!

Si vous avez oublié de rajouter au $PATH le chemin vers les binaires que vous avez crées, vous allez avoir un messages

# make help
make: arm-none-eabi-gcc: Command not found

Notes:

Kernel Compilation
Introduction to cross-compiling for Linux
Linux Kernel in a Nutshell
Linux Kernel Driver DataBase
Compiling a new Kernel (and Reiser4)Debian : Compiler un noyau avec « kernel-package »
Noyau Linux, modules, et initrd