Outils pour utilisateurs

Outils du site


issue89:labo_linux_2

Table des matières

1

In the first part of this series, we saw what the Linux kernel is, and its place within a GNU/Linux operating system. We ended up by giving several reasons why a user of a modern operating system could still wish to compile his or her own kernel, centering our remarks specifically around the Ubuntu distribution. In this second chapter, we will consider the various ways of obtaining the source code for the kernel, explore its directory structure and see what other pieces we need in order to compile it. GETTING THE KERNEL SOURCE As usual with the Ubuntu distribution, the kernel source is available in a single software package from the command-line apt commands or your favorite graphical software manager. Basically, what we need to install is a single package, “linux-source”. This is a meta-package that points to whatever is the latest version of the kernel source in the repositories. So, in a terminal, go into administrator mode with: $ sudo bash and then refresh the package lists before downloading the kernel source. The refresh is important because kernel source packages do get updated from time to time, and the release version numbers can change. # apt-get update # apt-get install linux-source

Dans la première partie de cette série, nous avons vu ce qu'est le noyau Linux et son rôle dans un système d'exploitation GNU/Linux. Nous avons terminé en donnant plusieurs raisons pour lesquelles l'utilisateur d'un système d'exploitation moderne pourrait encore vouloir compiler son propre noyau, axant nos remarques sur la distribution Ubuntu. Dans ce deuxième chapitre, nous allons examiner les différentes façons d'obtenir le code source pour le noyau, explorer sa structure de répertoire et voir de quels autres morceaux nous avons besoin pour le compiler.

RÉCUPÉRER LES SOURCES DU NOYAU

Comme d'habitude avec la distribution Ubuntu, le code source du noyau est disponible dans un paquet logiciel unique obtenu avec la commande apt ou votre gestionnaire de paquets graphique favori. Nous avons simplement besoin d'installer un seul paquet, « linux-source ». C'est un méta-paquet qui pointe vers la dernière version du code source du noyau dans les dépôts. Donc, dans un terminal, passez en mode administrateur avec :

$ sudo bash

puis actualiser la liste de paquets avant de télécharger les sources du noyau. Le rafraîchissement est important parce que les paquets contenant les sources du noyau sont mis à jour de temps à autre, et les numéros de version de sortie peuvent changer.

# apt-get update

# apt-get install linux-source

2

At the time of writing, the 3.13.0 kernel needed to download 97.7MB of files. This is installed as a single compressed file in directory /usr/src/linux-source-3.13.0 - or with whatever version number you have downloaded. Switch directories to there # cd /usr/src/linux-source-3.13.0 and unzip the compressed file using the bunzip2 utility. The bzip compression algorithm gives better compression than the more common gzip, though at the expense of greater complexity. So do not be surprised if decompression takes some time! If it is not present on your system, you will first need to download and install the bzip utility programs: # apt-get install bzip2 # bunzip2 linux-source-3.13.0.tar.bz2 # tar xf linux-source-3.13.0.tar

Au moment où j'écris, le noyau 3.13.0 devait télécharger 97,7 Mo de fichiers. Ils sont installés en un seul fichier compressé dans le répertoire /usr/src/linux-source-3.13.0 - ou le numéro de version que vous avez téléchargé. Allez dans ce répertoire :

# cd /usr/src/linux-source-3.13.0

et décompressez le fichier à l'aide de l'utilitaire bunzip2. L'algorithme de compression bzip donne une meilleure compression que le gzip, plus commune, mais au détriment d'une plus grande complexité. Ainsi, ne soyez pas surpris si la décompression prend un certain temps !

S'il n'est pas présent sur votre système, vous devez d'abord télécharger et installer le programme bzip :

# apt-get install bzip2

# bunzip2 linux-source-3.13.0.tar.bz2

# tar xf linux-source-3.13.0.tar

3

We should now have a subdirectory also called linux-source-3.13.0, into which we change directories once more: # cd linux-source-3.13.0 It can be of help to create a direct link to the more recent kernel source tree, especially if we have more than one version: # ln -s /usr/src/linux-source-3.13.0/linux-source-3.13.0 /usr/src/linux and now /usr/src/linux points to the real directory at /usr/src/linux-source-3.13.0/linux-source-3.13.0. We can also do some cleaning up of the compressed files, if we need them no more. An alternative way of getting the kernel source is to simply get it from the kernel.org project archives. This ensures that we get the very latest kernel version, and also that we have access to release candidates of the next, future, version. At the time of writing, Ubuntu's kernel source version is 3.13.0, but kernel.org has already gone up to 3.15.4, and the next version's release candidate is at version number 3.16.

Vous devriez avoir maintenant un sous-répertoire appelé également linux-source-3.13.0, dans lequel nous nous rendons :

# cd linux-source-3.13.0

Il peut être utile de créer un lien direct vers la plus récente arborescence des sources du noyau, surtout si nous avons plus d'une version :

# ln -s /usr/src/linux-source-3.13.0/linux-source-3.13.0 /usr/src/linux

et maintenant /usr/src/linux pointe vers le répertoire réel /usr/src/linux-source-3.13.0/linux-source-3.13.0. Nous pouvons aussi faire un peu de nettoyage des fichiers compressés, si nous n'en avons plus besoin.

Une autre façon d'obtenir les sources du noyau est de les récupérer simplement depuis le projet kernel.org. Cela nous garantit d'obtenir la toute dernière version du noyau, et aussi d'accéder aux candidates de la prochaine version à venir. Au moment où j'écris, la version de source du noyau Ubuntu est la 3.13.0, mais kernel.org est déjà passé à 3.15.4, et la version candidate pour la prochaine version est la 3.16.

4

A word of warning may be appropriate, however: kernels that are not from the current stable version have not undergone the whole process of testing. They will include new features, and may possibly break your installation. If you do not need to test these future versions, it is best to stay with the stable ones. On the other hand, several older stable versions of the kernel source are also available at kernel.org; at the time of writing going back down to 2.6.32. It should be noted that these earlier versions have been updated with bug corrections and security updates since they came out; what is missing from earlier versions is merely the new features that have come out in newer versions. These older versions may come in handy, either to replicate the behavior of a system with an earlier configuration, or because a certain application needs a kernel from an earlier series. For example, an old hardware driver module available in source code may need a kernel source from the 2.0 series in order to compile correctly. These are probably fringe cases, however, and will rarely be seen by most users.

Un mot d'avertissement peut être approprié, cependant : les noyaux qui ne sont pas de la version stable actuelle n'ont pas subi l'ensemble du processus de tests. Ils vont inclure de nouvelles fonctionnalités et peuvent éventuellement casser votre installation. Si vous n'avez pas besoin de tester ces futures versions, il est préférable de rester sur les stables.

En revanche, plusieurs anciennes versions stables des sources du noyau sont également disponibles sur kernel.org ; au moment de la rédaction, on pouvait redescendre à la 2.6.32. Il convient de noter que ces versions antérieures ont été mises à jour avec des corrections de bogues et des mises à jour de sécurité depuis leur sortie ; ce qui manque dans les versions antérieures ce sont essentiellement les nouvelles fonctionnalités qui sont sorties dans les nouvelles versions.

Ces anciennes versions peuvent être utiles, soit pour reproduire le comportement d'un système avec une configuration ancienne, soit parce qu'une certaine application a besoin d'un noyau d'une série antérieure. Par exemple, un ancien module de pilote de matériel disponible dans le code source peut avoir besoin des sources de la série 2.0 du noyau afin de compiler correctement. Cependant, ce sont probablement des cas marginaux, qui sont rarement rencontrés par la plupart des utilisateurs.

5

Once downloaded, the compressed source file must be decompressed and un-tarred as with Ubuntu's packaged version. In this case, the tar file is compressed using XZ compression, a version of the popular 7-zip encoding from the Windows world. We will not need to install any further utility programs, tar itself can decompress this format. We can cd to wherever we downloaded the compressed file, transfer it to the /usr/src directory and uncompress it: # cp /home/alan/Downloads/linux-3.15.4.tar.xz /usr/src # cd /usr/src # tar xf linux-3.15.4.tar.xz This produces the linux-3.15.4 subdirectory, with the source files inside.

Une fois téléchargé, le fichier source compressé doit être décompressé comme la version fournie par Ubuntu. Dans ce cas, le fichier tar est compressé en utilisant la compression XZ, une version de l'encodage 7-zip, populaire dans le monde Windows. Nous n'aurons pas besoin d'installer d'autres programmes utilitaires, la commande tar peut décompresser ce format. Nous pouvons aller à l'endroit où nous avons téléchargé le fichier compressé, le transférer vers le répertoire /usr/src et le décompresser :

# cp /home/alan/Downloads/linux-3.15.4.tar.xz /usr/src

# cd /usr/src

# tar xf linux-3.15.4.tar.xz

Cela crée le sous-répertoire linux-3.15.4, avec les fichiers sources à l'intérieur.

6

DIFFERENCES BETWEEN SOURCES So far, we have obtained not one but two different kernel source trees. The first, from the Ubuntu repositories, contains the structure shown below (top). The second source tree, directly from the kernel.org project website, is below (bottom). So they are basically the same tree structure, with a single difference: the “ubuntu” subdirectory. This is not a surprise, since the Ubuntu package is supposed to come originally from kernel.org, though some re-packaging may have taken place. We can confirm this by looking at how much space is occupied by each version: # du -sh * 626M linux-3.15.4 634M linux-source-3.13.0 Ubuntu's version is slightly larger – even though it contains an earlier kernel version. This confirms that Ubuntu has in fact altered the kernel in some way. The differences are what Ubuntu calls the “Ubuntu patches” to the kernel. The interested reader will find more information on Ubuntu's Kernel Team and what they do on their wiki page: https://wiki.ubuntu.com/Kernel

DIFFÉRENCES ENTRE LES SOURCES

Jusqu'à présent, nous avons obtenu non pas une, mais deux arborescences de sources du noyau. La première, depuis les dépôts Ubuntu, contient la structure représentée ci-dessous (en haut).

La deuxième arborescence, directement téléchargée depuis le site du projet kernel.org, est ci-dessous (en bas).

Donc, elles ont essentiellement la même structure, avec une seule différence : le sous-répertoire « ubuntu ». Ce n'est pas une surprise, puisque le paquet Ubuntu est censé provenir de kernel.org, même si une remise en forme a pu avoir lieu. Nous pouvons confirmer cela en regardant combien d'espace est occupé par chaque version :

# du -sh *

626M linux-3.15.4

634M linux-source-3.13.0

La version d'Ubuntu est légèrement plus grosse, bien qu'elle contienne une version antérieure du noyau. Cela confirme qu'Ubuntu a en effet modifié le noyau d'une certaine façon. Les différences sont ce qu'Ubuntu appelle les « patches Ubuntu » au noyau. Le lecteur intéressé trouvera plus d'informations sur l'équipe du noyau d'Ubuntu et ce qu'ils font sur leur page wiki : https://wiki.ubuntu.com/Kernel

7

EXPLORING THE SOURCE DIRECTORY STRUCTURE When we take a look at the source code directory tree, the first thing we see are several text files immediately at the tree root. As always, README is a great place to start. This file contains some quick instructions to get you up and running. However, some parts are slightly outdated, for example referring to the LILO boot manager that is little used nowadays, and not at all on Ubuntu distributions. The CREDITS and MAINTAINERS files contain a list of people who have contributed to the kernel code and some of the parts they have been responsible for. The perusal of these two files can give us a perspective of how the kernel is in fact the product of a team of programmers working together. Linus Torvalds and Greg Kroah-Hartman are perhaps the best-known participants and project leaders, but they are by no means alone. The Documentation directory is a large and not very well structured collection of mainly (very) technical notes. Most of the material here relates to specific hardware and procedures setup in the kernel, and unfortunately will be of little help to the beginner.

EXPLORATION DE L'ARBORESCENCE DES SOURCES

Quand nous jetons un œil à l'arborescence du code source, nous voyons d'abord plusieurs fichiers texte immédiatement à la racine. Comme toujours, le fichier README est un excellent point de départ. Ce fichier contient quelques instructions rapides pour vous permettre de démarrer. Toutefois, certaines parties sont un peu obsolètes, par exemple la référence au gestionnaire de démarrage LILO qui est peu utilisé de nos jours, et pas du tout sur les distributions Ubuntu. Les fichiers CREDITS et MAINTAINERS contiennent une liste de personnes qui ont contribué au code du noyau et quelques-unes des parties dont ils ont été responsables. La lecture de ces deux fichiers peut nous donner un aperçu du travail d'équipe des programmeurs, qui mène à la construction du noyau. Linus Torvalds et Greg Kroah-Hartman sont peut-être les participants les plus connus et les chefs de projet, mais ils ne sont vraiment pas seuls.

Le répertoire Documentation est une collection volumineuse et pas très bien structurée, principalement de notes (très) techniques. La plupart des documents ici se rapporte à des configurations matérielles et des procédures spécifiques au noyau, et sera malheureusement de peu d'aide pour le débutant.

8

The other directories are the kernel source code. The very basic stuff, mostly related to process scheduling and control, is in a directory named kernel. Other important parts are broken out into different directories: fs (file systems), ipc (inter-process communication), mm (memory management), net (networking), sound (sound drivers), etc. Several directories handle specific hardware needs. In the first place, the arch directory was created to contain low-level code to handle each type of architecture supported by the kernel. This is the only place where you should find assembly code instead of the C language. Having the very large majority of the code in C helps the kernel be adapted to different hardware platforms when needed: most C code will not need to be re-written, but simply compiled for the new physical architecture. On the other hand, each specific platform may need some very low-level coding just to take care of initial kernel booting. If you take a look in this directory, you will appreciate the diversity of hardware platforms supported by the Linux kernel. You will find not just the Intel 32-bit Architecture IA32 under x86 and AMD 64-bit architecture under ia64, but also well-known names such as alpha (the DEC Alpha processor), powerpc (the Intel-Apple-Motorola PowerPC), sparc (Sun's SPARC), and more modern architectures such as arm (the 32-bit ARM family used in tablets and phones) and even arm64 (the newer 64-bit version of the ARM).

Les autres répertoires abritent le code source du noyau. Les trucs de base, essentiellement liés à la planification et au contrôle de processus, est dans un répertoire nommé kernel. D'autres éléments importants sont répartis dans différents répertoires : fs (systèmes de fichiers), ipc (communication inter-processus), mm (gestion de la mémoire), net (réseau), sound (pilotes audio), etc.

Plusieurs répertoires gèrent des besoins matériels spécifiques. En premier lieu, le répertoire arch a été créé pour contenir du code de bas niveau pour gérer chaque type d'architecture supportée par le noyau. C'est le seul endroit où vous pourrez trouver du code en assembleur au lieu du langage C. Avoir la très grande majorité du code en C permet au noyau d'être adapté à différentes plateformes matérielles en cas de besoin : la plupart du code C n'aura pas besoin d'être ré-écrit, mais simplement compilé pour la nouvelle architecture physique. Par contre, chaque plateforme spécifique peut avoir besoin de code de bas niveau simplement pour gérer le démarrage initial du noyau. Si vous jetez un œil dans ce répertoire, vous apprécierez la diversité des plateformes matérielles prises en charge par le noyau Linux. Vous trouverez non seulement les architectures Intel 32-bit IA32 sous x86 et AMD 64-bit sous ia64, mais également des noms bien connus tels que alpha (le processeur DEC Alpha), powerpc (le PowerPC Intel-Apple-Motorola), sparc (le SPARC de Sun), et des architectures plus modernes tels que arm (la famille ARM 32-bit utilisée dans les tablettes et téléphones) et même arm64 (la version plus récente 64-bit d'ARM).

9

Another important directory is drivers. Together with the sound directory (containing specific drivers for sound processing hardware) and several other minor directories, here is where you would see the drivers for each type of hardware the kernel supports. Basically, if there is code in this directory that knows how to handle your piece of hardware, it may work in a GNU/Linux system. Otherwise, things may get really complicated to get it to function. Please bear in mind that each piece of driver code in this directory does not address any particular brand or make of hardware, but rather the controller chips used in that device. For example, in directory drivers/net/ethernet/realtek we can find a file called 8139cp.c. This device driver handles any Ethernet network card using the RealTek RTL-8139C+ series controller, which at the time was used by many different card manufacturers, and sold under probably more than 100 different brand names. Some versions were used in exchangeable PCI-interface cards, while others were soldered directly into computer's motherboards. But all can use the same driver code developed initially (as was much of the network interface code) by Donald Becker, as is mentioned in the C file's initial commentary section.

Un autre répertoire important est drivers. Avec le répertoire sound (contenant les pilotes spécifiques pour les matériels de traitement du son) et plusieurs autres répertoires mineurs, c'est ici que vous trouverez les pilotes pour chaque type de matériel que le noyau prend en charge. Fondamentalement, s'il y a du code dans ce répertoire qui sait comment gérer votre matériel, il pourrait fonctionner dans un système GNU/Linux. Sinon, ça risque d'être vraiment compliqué de le faire fonctionner.

Gardez s'il vous plaît à l'esprit que chaque bout de code d'un pilote dans ce répertoire ne s'occupe pas d'une marque particulière de matériel, mais plutôt des puces de contrôle utilisées dans ce matériel. Par exemple, dans le répertoire drivers/net/ethernet/realtek nous pouvons trouver un fichier appelé 8139cp.c. Ce pilote de périphérique gère n'importe quelle carte réseau Ethernet utilisant un contrôleur Realtek de la série RTL-8139C+ qui, à l'époque, a été utilisé par de nombreux fabricants de cartes différentes et vendu sous probablement plus de 100 marques différentes. Certaines versions ont été utilisées dans des cartes d'interface PCI interchangeables, tandis que d'autres ont été soudées directement sur les cartes mères. Mais toutes peuvent utiliser le même code du pilote développé initialement (comme c'est le cas pour la plupart du code d'interface réseau) par Donald Becker, comme il est mentionné dans la section de commentaire au début du fichier C.

10

The firmware directory is the other place where we will find bits of code that are not written in the C programming language. A modern computer can in some ways be seen as a multicomputer network: the main computer hands off some of the work to daughter systems: the sound processing system, the graphics card, the network card, a hard drive, a printer, etc, are all formed by small computing environments, each controlled by a micro-controller acting as a small CPU in its own right. Firmware is a concept that comes from the introduction of non-volatile memory in both in domestic electronic apparatus and in internal computer components. These daughter systems now have the capability of running not only programs that were written once and for all in ROM chips, “engraved in stone” so to speak, but can also load programs on the fly into various forms of re-writable memory (EE-PROM or “Flash” memory). This memory on the daughter board contains programs in binary form, destined not for the computer's CPU but for the micro-controller of each apparatus or component. To initialize and use some of these devices, we will need not only a device driver - which is a program run by our computer's CPU and resident in its own memory - but also a piece of firmware - known as a “binary blob” - that must be loaded into the device's memory on initialization. These are not considered as part of the kernel itself.

Le répertoire firmware est l'autre endroit où nous allons trouver des morceaux de code qui ne sont pas écrits dans le langage de programmation C. Un ordinateur moderne peut à certains égards être considéré comme un réseau d'ordinateurs multiples : l'ordinateur principal délègue une partie du travail à d'autres systèmes : le système de traitement du son, la carte graphique, la carte réseau, un disque dur, une imprimante, etc., sont tous formés par de petits environnements informatiques, chacun contrôlé par un micro-contrôleur agissant comme un petit CPU à part entière. Le firmware est un concept qui vient de l'apparition de la mémoire non volatile, à la fois dans les appareils électroniques domestiques et dans les composants informatiques internes. Ces systèmes ont maintenant la capacité d'exécuter non seulement des programmes qui ont été écrits une fois pour toutes dans les puces ROM, « gravé dans la pierre » pour ainsi dire, mais peuvent également charger des programmes à la volée dans diverses formes de mémoire réinscriptible (EE-PROM ou mémoire « Flash »). Cette mémoire sur la carte fille contient des programmes sous forme binaire, qui ne sont pas destinés au CPU de l'ordinateur, mais au micro-contrôleur de chaque appareil ou composant.

Pour initialiser et utiliser certains de ces dispositifs, nous aurons besoin non seulement d'un pilote de périphérique - qui est un programme géré par le CPU et résidant dans notre ordinateur dans sa propre mémoire - mais aussi d'un morceau de firmware, connu comme un « blob binaire », qui doit être chargé dans la mémoire du périphérique lors de l'initialisation. Ces derniers ne sont pas considérés comme faisant partie du noyau lui-même.

11

There has been some dispute about the nature of the firmware included with the Linux kernel. Some distributions, such as Ubuntu itself, have little qualms about including firmware that is not open-source or released under the GPL license. Their take is that the end-user wishes simply to have things work; since they have acquired the hardware, they must also have access to the software necessary to make it function. But there is also the contrary standpoint, proposed notably by Richard Stallman and adopted by distributions such as gNewSense, that argues that proprietary and non-open binary blobs may work, or not. They may work particularly well in some cases, and fail miserably in others – and for reasons unknown. Since nobody except the manufacturer has access to the source code, there is no way of assessing the firmware code, making it better, or adapting it to new needs. It is for this reason that the kernel.org project members take pains to trace the origins of binary blobs distributed with the kernel, as may be seen in file firmware/WHENCE. It is also for this reason that distributions such as Ubuntu or Linux Mint permit the installation of certain non open-source drivers, but only at the user's initiative and specifying clearly they come without any support from the distribution's team.

Il y a eu un différend à propos de la nature du firmware inclus dans le noyau Linux. Certaines distributions, comme Ubuntu, ont peu de scrupules à inclure des firmwares qui ne sont pas Open Source ou publiés sous la licence GPL. Leur point de vue est que l'utilisateur final souhaite simplement avoir des choses qui fonctionnent ; puisqu'ils ont acquis le matériel, ils doivent aussi avoir accès aux logiciels nécessaires pour le faire fonctionner. Mais il y a aussi le point de vue contraire, proposé notamment par Richard Stallman et adopté par des distributions comme gNewSense, qui soutient que les blobs binaires propriétaires et non ouverts peuvent fonctionner, ou pas. Ils peuvent fonctionner particulièrement bien dans certains cas et échouer lamentablement dans d'autres, et pour des raisons inconnues. Comme personne à part le fabricant n'a accès au code source, il n'est pas possible d'évaluer le code du firmware, pour l'améliorer ou pour l'adapter aux nouveaux besoins. C'est pour cette raison que les membres du projet kernel.org prennent soin de retracer les origines des blobs binaires distribués avec le noyau, comme on le voit dans le fichier firmware/WHENCE. C'est aussi pour cette raison que les distributions comme Ubuntu ou Linux Mint permettent l'installation de certains pilotes non Open Source, mais seulement à l'initiative de l'utilisateur et en précisant clairement qu'ils sont livrés sans aucun soutien de l'équipe de la distribution.

12

WHAT ELSE DO WE NEED? Once we have the kernel source decompressed on our disk, we will need several things in order to compile it. Naturally, we will need the C language compiler, but that will not be all. For the readers who may need a quick primer on the process of compilation, let us begin by describing some concepts. In order to compile a program written in a compiled programming language, in the first place we will need the program itself, or what is called the source code. This is simply a text file that contains the program instructions, though the extension will have been changed to “.c” to mark it as a C source code file, and not a file containing mere text. We will now follow with a short example of a C program, contained in a file named “hello.c”. This is perhaps the best-known example of C programming, that almost all programmers will have seen at some point: #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { printf(“Hello, world!\n”); }

QUE NOUS FAUT-IL D'AUTRE ?

Une fois que les sources du noyau sont décompressés sur notre disque, nous aurons besoin de plusieurs choses pour pouvoir le compiler. Naturellement, nous aurons besoin du compilateur C, mais ce ne sera pas tout.

Pour les lecteurs qui auraient besoin d'une explication rapide sur le processus de compilation, nous commençons par décrire certains concepts. Pour compiler un programme écrit dans un langage de programmation compilé, nous aurons tout d'abord besoin du programme lui-même, ou ce qu'on appelle le code source. C'est tout simplement un fichier texte qui contient les instructions de programme, même si l'extension a été changée en « .c » pour indiquer qu'il s'agit d'un fichier de code source C, et non pas d'un simple fichier contenant du texte. Nous allons maintenant poursuivre avec un court exemple d'un programme en C, contenu dans un fichier nommé « bonjour.c ». C'est peut-être l'exemple le plus connu de la programmation C, que presque tous les programmeurs auront vu à un moment donné :

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char *argv[]) {

printf("Bonjour tout le monde !\n"); 

}

13

The first two lines indicate we wish to include several header files. These contain no code properly speaking, but just the definition of several function interfaces (such as “printf”). If we include them, the compiler will suppose these functions are available when reading in (“parsing”) our program file. The program's main body - the “main” function - contains just one single line, instructing the system to print a character string on screen. In order to actually execute this program, we will need to translate the complete program into an executable or binary file. This process is what is known as compilation. Readers of Greg Walters' “Programming in Python” series in these very same pages will have noted that no such translation process is needed for the Python programming language. This latter belongs to the class of “interpreted languages”; the programs produced in an interpreted language are not executed directly, but rather interpreted instruction-by-instruction on the fly by a program called - you guessed it! - an interpreter. In the case of compiled languages such as C, however, no such interpreter exists, and so we need to convert the source code into an executable file before getting to test our program and knowing if it actually works.

Les deux premières lignes indiquent que nous voulons inclure plusieurs fichiers d'en-tête. Ceux-ci ne contiennent pas de code à proprement parler, mais juste la définition de plusieurs interfaces de fonctions (comme « printf »). Si nous les incluons, le compilateur suppose que ces fonctions sont disponibles lors de la lecture (« l'analyse ») de notre fichier de programme. Le corps principal du programme - la fonction « main » - contient juste une seule ligne, demandant au système d'afficher une chaîne de caractères à l'écran.

Afin de réellement exécuter ce programme, nous aurons besoin de traduire le programme complet dans un fichier exécutable ou binaire. Ce processus est ce qu'on appelle la compilation.

Les lecteurs de « Programmer en Python », la série de Greg Walters dans ces mêmes pages, auront noté qu'un tel processus de traduction n'est pas nécessaire pour le langage de programmation Python. Ce dernier appartient à la classe des « langages interprétés » ; les programmes produits dans un langage interprété ne sont pas exécutées directement, mais plutôt interprétés instruction par instruction à la volée par un programme appelé - vous l'aurez deviné ! - un interpréteur. Dans le cas des langages compilés comme C, cependant, aucun interpréteur n'existe, et nous avons donc besoin de traduire le code source dans un fichier exécutable avant d'arriver à tester notre programme et savoir si cela fonctionne réellement.

14

Both approaches have benefits and drawbacks. By using compiled languages, we get an executable file that can run very fast, and the end user will only need access to this single file. On the other hand, interpreted languages will give the end user access to the source code, which he or she can modify and tune to their needs. But they would need to have an interpreter for that particular language installed on their system, and the end result executes a tad more slowly. To compile our test “hello.c” program, supposing we have the gcc C language compiler installed on our system (if not, we will need to install package “gcc”), we can issue: $ cc hello.c -o hello This tells the C language compiler (“cc”, get it?) to compile source code file “hello.c”, producing executable file “hello”. Note that in the UNIX and GNU/Linux world, executable files need not have the “.exe” extension. Once the file is compiled, the resulting executable can be executed by issuing: $ ./hello Hello, world!

Les deux approches ont des avantages et des inconvénients. En utilisant les langages compilés, nous obtenons un fichier exécutable qui peut se dérouler très rapidement, et l'utilisateur final n'aura besoin d'accéder qu'à ce fichier unique. En revanche, les langages interprétés donneront à l'utilisateur final accès au code source, qu'il pourra modifier et ajuster à ses besoins. Mais il faut qu'un interpréteur pour ce langage particulier soit installé sur leur système et le résultat final s'exécutera un peu plus lentement.

Pour compiler notre programme de test « bonjour.c », en supposant que nous avons le compilateur C gcc installé sur notre système (sinon, nous aurons besoin d'installer le paquet “gcc”), nous pouvons saisir :

$ cc bonjour.c -o bonjour

Ceci demande au compilateur C (« cc », vous comprenez ?) de compiler le fichier de code source « bonjour.c », et de produire le fichier exécutable « bonjour ». Notez que dans le monde UNIX et GNU/Linux, les fichiers exécutables n'ont pas besoin de l'extension « .exe ». Une fois le fichier compilé, l'exécutable résultant peut être lancé par la commande :

$ ./bonjour

Bonjour tout le monde !

15

Naturally, things can get a little more complex when a large application project contains several hundred C and header files. In the case of the Linux kernel, not all of these are always to be compiled – depending on which target architecture (Intel 32-bit Architecture, IA64, …) we are compiling for. To simplify things, a file containing instructions on what to compile, in which order, and using which compilation parameters, can be drawn up. This makefile can be seen as a pattern or guide for the compilation process. Going back to our sample program, we could write the file “Makefile” with the following contents: hello: cc hello.c -o hello Now, each time we wish to compile the file, we could use the make command to run the file contents for us: $ make hello and the corresponding instructions from the makefile would be executed.

Naturellement, les choses peuvent devenir un peu plus complexes quand un gros projet applicatif contient plusieurs centaines de fichiers C et en-têtes. Dans le cas du noyau Linux, tous ces fichiers ne sont pas toujours compilés, selon l'architecture cible (Intel 32-bit, IA64, …) pour laquelle nous compilons. Pour simplifier les choses, on peut écrire un fichier contenant des instructions sur ce qu'il faut compiler, dans quel ordre, et avec quels paramètres de compilation. Ce makefile peut être considéré comme un modèle ou guide pour le processus de compilation.

Pour en revenir à notre exemple de programme, nous pourrions écrire le fichier « Makefile » avec le contenu suivant :

bonjour:

      cc bonjour.c -o bonjour 

Maintenant, à chaque fois que nous souhaitons compiler le fichier, nous pourrions utiliser la commande make pour exécuter le contenu du fichier :

$ make bonjour

et les instructions correspondantes dans le makefile seraient exécutés.

16

As you might suspect, both the compiler and the make-build environment are largely used in order to simplify the Linux kernel compilation process. This is why we will need to have installed not only the C compiler itself, but also several utility programs: GNU make itself, a bzip decompressor, etc.. The following packages will be needed at some point in the process: gcc binutils make bzip2 coreutils The kernel compilation process may be configured to a certain extent using the makefile system. To do so, several configuration scripts are available. The simplest, invoked by issuing: $ make config is a simple text-based script that needs no further software to work. However, the two graphical configuration utilities: $ make xconfig and $ make gconfig rely respectively on the qt and gtk widget frameworks developed originally for the KDE and Gnome desktop managers. In the first case, “xconfig” will need to have the following packages installed: qt4-default qt4-qmake

Comme vous vous en doutez, pour simplifier le processus de compilation du noyau Linux, le compilateur et l'environnement make de construction sont tous les deux largement utilisés. C'est pourquoi nous aurons besoin d'avoir installé non seulement le compilateur C lui-même, mais aussi plusieurs programmes utilitaires : GNU make lui-même, un décompresseur bzip, etc. Les paquets suivants seront nécessaires à un certain moment dans le processus :

gcc binutils make bzip2 coreutils   Le processus de compilation du noyau peut être configuré dans une certaine mesure en utilisant le système de makefile. Pour ce faire, plusieurs scripts de configuration sont disponibles. Le plus simple, invoqué par la commande :

$ make config

est un script basé sur du texte simple qui ne nécessite aucun autre logiciel pour fonctionner. Cependant, les deux utilitaires de configuration graphique :

$ make xconfig

et

$ make gconfig

reposent respectivement sur les environnements de widgets qt et gtk développés à l'origine pour les gestionnaires de bureau KDE et Gnome. Dans le premier cas, « xconfig » aura besoin des paquets suivants :

qt4-default qt4-qmake

17

If using the gtk version, “gconfig” will need packages: libgtk2.0-dev libglib2.0-dev libglade2-dev Finally, my preferred way of configuring the kernel is using the curses-based make menuconfig This text-based but more user-friendly environment will need the following package: ncurses-dev Now that we have all the bits and pieces we will need, in the next part of this series we will go through the available compilation options, and actually end up by compiling our first kernel.

Si vous utilisez la version gtk, « gconfig » aura besoin des paquets :

libgtk2.0-dev libglib2.0-dev libglade2-dev

Enfin, ma préférence pour configurer le noyau va à l'interface « curses » :

make menuconfig

Cet environnement convivial basé sur du texte amélioré nécessite le paquet suivant :

ncurses-dev

Maintenant que nous avons tous les morceaux dont nous aurons besoin, dans la prochaine partie de cette série, nous allons passer en revue les options de compilation disponibles et terminer en compilant notre premier noyau.

issue89/labo_linux_2.txt · Dernière modification : 2015/02/10 17:24 de auntiee