Pourquoi le noyau Linux a-t-il plus de 15 millions de lignes de code? [fermé]


109

Quel est le contenu de cette base de code monolithique?

Je comprends la prise en charge de l’architecture du processeur, la sécurité et la virtualisation, mais je n’imagine pas qu’elle compte plus de 600 000 lignes.

Quels sont les motifs historiques et actuels pour lesquels les pilotes sont inclus dans la base de code du noyau?

Ces 15 millions et plus de lignes incluent-ils chaque pilote pour chaque élément de matériel? Si tel est le cas, la question se pose alors: pourquoi les pilotes sont-ils incorporés dans le noyau et non des packages séparés, détectés automatiquement et installés à partir d'ID de matériel?

La taille de la base de code pose-t-elle un problème pour les périphériques à stockage limité ou à mémoire limitée?

Il semblerait que la taille du noyau des périphériques ARM soumis à des contraintes d’espace serait gonflée si tout cela était intégré. Y a-t-il beaucoup de lignes sélectionnées par le pré-processeur? Appelez-moi fou, mais je ne peux pas imaginer une machine nécessitant autant de logique pour exécuter ce que je comprends être le rôle d'un noyau.

Existe-t-il des preuves que sa taille sera un problème dans plus de 50 ans en raison de sa nature apparemment en croissance constante?

L'inclusion des pilotes signifie que le nombre de périphériques augmentera.

EDIT : Pour ceux qui pensent que c'est la nature des noyaux, après quelques recherches, j'ai réalisé que ce n'était pas toujours le cas. Il n'est pas nécessaire que le noyau soit aussi volumineux, car le micro - noyau Mach de Carnegie Mellon était répertorié à titre d'exemple 'habituellement sous 10 000 lignes de code'.


9
En 2012, il comptait plus de 5 millions de lignes réservées aux conducteurs. 1,9 million de lignes pour prendre en charge différentes architectures de processeurs. Plus d'infos h-online.com/open/features/…
steve

11
Oui, j'ai codé un compilateur, un analyseur lexical et un générateur de code octet pour une langue. La récursion était complète et il n'y avait pas besoin de 10 000 lignes.
Jonathan

5
(regardé maintenant, il y avait environ 2 700 lignes)
Jonathan

4
Vous devez télécharger et configurer make menuconfigpour voir quelle quantité de code peut être activée / désactivée avant la construction.
Casey

6
@JonathanLeaders: J'ai réalisé des compilateurs complets pour LISP, comme des langages, en moins de 100 lignes, avec des programmes de test rendant Mandelbrots. Cela dépend toujours.
phresnel

Réponses:


43

Les pilotes sont maintenus dans le noyau. Ainsi, lorsqu'un changement de noyau nécessite une modification globale (recherche ou remplacement) (ou une modification manuelle), il est effectué par la personne qui effectue le changement. La mise à jour de votre pilote par des personnes apportant des modifications à l'API constitue un très bel avantage, au lieu d'avoir à le faire vous-même lorsqu'elle ne compile pas sur un noyau plus récent.

L'alternative (ce qui est le cas pour les pilotes maintenus en dehors de l'arborescence), est que le correctif doit être resynchronisé par ses mainteneurs pour suivre toutes les modifications.

Une recherche rapide a permis de lancer un débat sur le développement de pilotes dans l’arbre ou en dehors de celui-ci .

La façon dont Linux est maintenu consiste principalement à tout conserver dans le référentiel principal. La construction de petits noyaux simplifiés est prise en charge par les options de configuration permettant de contrôler #ifdefs. Ainsi, vous pouvez absolument construire de minuscules noyaux dépouillés qui ne compilent qu'une infime partie du code dans l'ensemble du référentiel.

L’utilisation intensive de Linux dans les systèmes embarqués a permis de mieux prendre en charge la suppression de données que ce que Linux avait eu des années auparavant, lorsque l’arbre source du noyau était plus petit. Un noyau 4.0 super-minimal est probablement plus petit qu'un noyau 2.4.0 super-minimal.


4
Maintenant, CELA comprend pourquoi il est logique d’avoir tout le code ensemble, cela permet d’économiser des heures de travail au détriment des ressources informatiques et des dépendances excessives.
Jonathan

8
@JonathanLeaders: ouais, cela évite le bit-rot pour les conducteurs avec une maintenance peu active. Il est également probablement utile de disposer de tout le code du pilote pour prendre en compte les principales modifications. La recherche sur tous les appelants d'une API interne peut permettre à un pilote de l'utiliser d'une manière que vous ne pensiez pas, ce qui pourrait éventuellement influencer un changement auquel vous pensiez.
Peter Cordes

1
@JonathanLeaders arrive sur xd, comme si ces lignes supplémentaires prenaient beaucoup plus de place, dans les mesures modernes d'installation sur un PC.
Junaga

3
@Junaga: vous réalisez que Linux est très portable et évolutif, n'est-ce pas? Consommer 1 Mo de mémoire noyau utilisée en permanence sur un système embarqué de 32 Mo est un gros problème. La taille du code source n'est pas importante, mais la taille binaire compilée l'est toujours. La mémoire du noyau n'est pas paginée, donc même avec de l'espace de swap, vous ne pouvez pas la récupérer.
Peter Cordes

1
@Rolf: C'est gros, mais ce n'est pas des spaghettis. Il est actuellement assez bien architecturé sans dépendances à double sens entre le code principal et les pilotes. Les pilotes peuvent être laissés de côté sans casser le noyau. Lorsqu'une fonction interne ou une API est refactorisée, les pilotes doivent donc l'utiliser différemment, mais il est peut-être nécessaire de changer de pilote, mais c'est normal pour le refactoring.
Peter Cordes

79

Selon cloc exécuté sous 3.13, Linux représente environ 12 millions de lignes de code.

  • 7 millions de LOC dans les pilotes /
  • 2 millions de LOC en arch /
  • seulement 139 000 LOC dans le noyau /

lsmod | wc Sur mon ordinateur portable Debian, 158 modules ont été chargés au moment de l'exécution. Le chargement dynamique de modules est donc un moyen bien utilisé de prendre en charge le matériel.

Le système de configuration robuste (par exemple make menuconfig) est utilisé pour sélectionner le code à compiler (et plus précisément, le code à ne pas compiler). Les systèmes intégrés définissent leur propre .configfichier avec uniquement le support matériel qui leur tient à coeur (y compris le support matériel intégré au noyau ou sous forme de modules chargeables).


3
Compter les modules ne suffit pas, beaucoup peut-être construit par config
Alex

5
Je pense que nous pouvons en conclure que le noyau Linux est énorme car il prend en charge toutes sortes de configurations de périphériques, et non parce qu’il est scandaleusement complexe. Nous voyons ici que très peu des lignes de 15 m sont actuellement utilisées. Bien que, comme presque toutes les choses soient, cela puisse être trop complexe, au moins nous pouvons dormir la nuit en sachant que c'est raisonnable
Jonathan

2
@JonathanLeaders: Oui. Outre les modules pour périphériques étranges, il existe des modules pour les systèmes de fichiers obscurs, les protocoles de réseau, etc. ...
psmears

6
@JonathanLeader Je me souviens du début de Linux - même faire fonctionner le programme d'installation (même s'il y en avait un!) Était très pénible - il y a encore des distributions où vous devez sélectionner le pilote de votre souris manuellement. Faire des choses comme le réseautage ou, Dieu nous en garde, X-window, le travail, était un rite de passage. Lors de ma première installation de Red Hat, j'ai dû écrire mon propre pilote graphique car il n'y avait que trois (!) Pilotes disponibles. Avoir des bases fonctionnelles par défaut est un signe de maturité - et vous pouvez évidemment vous permettre de peaufiner davantage avec un système embarqué, où il n’ya que quelques combinaisons matérielles.
Luaan

2
@JonathanLeaders Comme vous le savez sans doute, le LOC dans le code source est plus ou moins sans importance. Si vous voulez savoir combien de mémoire le noyau utilise, il y a beaucoup plus de moyens directs .
goldilocks

68

Pour ceux qui sont curieux, voici le détail du linecount pour le miroir GitHub:

=============================================
    Item           Lines             %
=============================================
  ./usr                 845        0.0042
  ./init              5,739        0.0283
  ./samples           8,758        0.0432
  ./ipc               8,926        0.0440
  ./virt             10,701        0.0527
  ./block            37,845        0.1865
  ./security         74,844        0.3688
  ./crypto           90,327        0.4451
  ./scripts          91,474        0.4507
  ./lib             109,466        0.5394
  ./mm              110,035        0.5422
  ./firmware        129,084        0.6361
  ./tools           232,123        1.1438
  ./kernel          246,369        1.2140
  ./Documentation   569,944        2.8085
  ./include         715,349        3.5250
  ./sound           886,892        4.3703
  ./net             899,167        4.4307
  ./fs            1,179,220        5.8107
  ./arch          3,398,176       16.7449
  ./drivers      11,488,536       56.6110
=============================================

driverscontribue à beaucoup de linecount.


19
C'est intéressant. Encore plus intéressants sont les points potentiellement faibles du code, où les programmeurs étaient agacés:grep -Pir "\x66\x75\x63\x6b" /usr/src/linux/ | wc -l
jimmij

4
@jimmij '\ x73 \ x68 \ x69 \ x74' pourrait être plus commun selon cette recherche révolutionnaire (si légèrement datée) .
Nick T

3
Aléatoire: le dossier le plus proche des 600 000 LOC estimés par l'OP est la documentation.
Davidmh

1
./documentationa plus de 500 000 lignes de code? ....quoi?
C_B

1
@drewbenn Je l'ai plus compris car "la documentation n'est pas vide?"
Izkata

43

Jusqu'à présent, les réponses semblent être "oui, il y a beaucoup de code" et personne ne s'attaque à la question avec la réponse la plus logique: 15M +? ET ALORS? Qu'est-ce que 15 millions de lignes de code source ont à voir avec le prix du poisson? Qu'est-ce qui rend cela si inimaginable?

Linux fait clairement beaucoup. Beaucoup plus que toute autre chose ... Mais certains de vos arguments montrent que vous ne respectez pas ce qui se passe lors de sa construction et de son utilisation.

  • Tout n'est pas compilé. Le système de construction du noyau vous permet de définir rapidement des configurations qui sélectionnent des ensembles de code source. Certaines sont expérimentales, certaines anciennes, d'autres inutiles pour tous les systèmes. Regardez /boot/config-$(uname -r)(sur Ubuntu) make menuconfiget vous verrez combien est exclu.

    Et c'est une distribution de bureau à cible variable. La configuration pour un système intégré ne prendrait que ce dont elle a besoin.

  • Tout n'est pas intégré. Dans ma configuration, la plupart des fonctionnalités du noyau sont construites sous forme de modules:

    grep -c '=m' /boot/config-`uname -r`  # 4078
    grep -c '=y' /boot/config-`uname -r`  # 1944
    

    Pour être clair, ils pourraient tous être intégrés ... Tout comme ils pourraient être imprimés et transformés en un sandwich en papier géant. Cela n'aurait aucun sens si vous ne réalisiez pas une construction personnalisée pour une tâche matérielle distincte (dans ce cas, vous auriez déjà limité le nombre de ces éléments).

  • Les modules sont chargés dynamiquement. Même lorsqu'un système dispose de milliers de modules, il vous permet de ne charger que ce dont vous avez besoin. Comparez les sorties de:

    find /lib/modules/$(uname -r)/ -iname '*.ko' | wc -l  # 4291
    lsmod | wc -l                                         # 99
    

    Presque rien n'est chargé.

  • Les micro-noyaux ne sont pas la même chose. Seulement 10 secondes en regardant l’image principale de la page Wikipedia que vous avez liée mettraient en évidence le fait qu’elles sont conçues de manière complètement différente.

    Les pilotes Linux sont internalisés (généralement sous la forme de modules chargés dynamiquement), et non par l'utilisateur, et les systèmes de fichiers sont également internes. Pourquoi est-ce pire que d'utiliser des pilotes externes? Pourquoi le micro est-il meilleur pour l'informatique à usage général?


Les commentaires soulignent encore une fois que vous ne l'obtenez pas. Si vous souhaitez déployer Linux sur du matériel discret (par exemple, aérospatiale, une TiVo, une tablette, etc.), vous le configurez pour ne générer que les pilotes dont vous avez besoin . Vous pouvez faire la même chose sur votre bureau avec make localmodconfig. Vous vous retrouvez avec une petite construction de noyau à des fins sans aucune flexibilité.

Pour les distributions comme Ubuntu, un seul paquet de noyau de 40 Mo est acceptable. Non, il est préférable de préférer le scénario d'archivage et de téléchargement massif qui consiste à conserver plus de 4000 modules flottants sous forme de packages. Il utilise moins d’espace disque pour eux, est plus facile à empaqueter au moment de la compilation, plus facile à stocker et convient mieux à leurs utilisateurs (qui disposent d’un système qui fonctionne simplement).

L'avenir ne semble pas être un problème non plus. Le rythme de la vitesse du processeur, la densité / coût des disques et les améliorations de la bande passante semblent beaucoup plus rapides que la croissance du noyau. Un paquet de noyau de 200 Mo dans 10 ans ne serait pas la fin si le monde.

Ce n'est pas non plus une rue à sens unique. Le code est expulsé s'il n'est pas maintenu.


2
La préoccupation concerne principalement les systèmes embarqués. Comme vous le montrez, vous avez 4 000 modules non utilisés sur votre propre système. Dans certaines petites applications robotiques ou aérospatiales (READ: non à usage général), cela constituerait un gaspillage inacceptable.
Jonathan

2
@ JonathanLeaders Je pense que vous pouvez les supprimer en toute sécurité. Sur une installation de bureau, ils sont là au cas où vous branchez quelque chose sur un port USB, modifiez une configuration matérielle, etc.
Didier A.

1
Oui, exactement. Je reste toujours surpris par des hypothèses telles que "vous pouvez brancher un périphérique USB à tout moment et nous avons donc besoin de 15 millions de lignes de code" sont écrites au niveau du noyau et non au niveau de la distribution, vu que Linux est utilisé dans les téléphones appareils embarqués. Eh bien, je suppose que le distro fait abattre la liste sur son propre. Je pense simplement que le support de plug-in devrait être additif et non soustractif, c'est-à-dire qu'une distro accepterait en quelque sorte de le remplacer en ajoutant des sources de paquetages, par opposition aux configurations ARM intégrées indiquant au noyau qu'il ne représentait qu'un pour cent de sa taille actuelle
Jonathan

5
@ JonathanLeaders, vous n'exécuteriez jamais un noyau configuré pour un poste de travail sur un système intégré. Notre système intégré comprend 13 modules et a supprimé tout le support matériel dont nous n’avions pas besoin (ainsi que de nombreuses autres personnalisations). Arrêtez de comparer les ordinateurs de bureau aux systèmes intégrés. Linux fonctionne bien car il supporte tout et peut être personnalisé pour inclure uniquement ce qui vous importe . Et ces modules 4k sont vraiment très bien sur les ordinateurs de bureau: quand mon dernier ordinateur portable est mort, je viens de mettre le disque dur dans un ordinateur portable beaucoup plus récent et tout fonctionne .
drewbenn

3
Cette réponse, par ailleurs bonne / précieuse, souffre d’un ton nettement agressif et combatif. -1.
TypeIA

19

Nombre de lignes des sources compilées Linux tinyconfig tinyconfig bubble graph svg (violon)

script shell pour créer le JSON à partir de la construction du noyau, à utiliser avec http://bl.ocks.org/mbostock/4063269


Edit : avéré unifdefavoir certaines limitations ( -Iest ignoré et -includenon pris en charge, ce dernier est utilisé pour inclure l'en-tête de configuration généré) à ce stade, l'utilisation catne change pas grand chose:

274692 total # (was 274686)

script et procédure mis à jour.


En plus des pilotes, arch, etc., il y a beaucoup de code conditionnel compilé ou non en fonction de la configuration choisie, le code n'est pas nécessairement dans les modules chargés dynamiquement, mais construit dans le noyau.

Ainsi, les sources téléchargées de linux-4.1.6 , ont choisi le tinyconfig , il n’active pas les modules et honnêtement, je ne sais pas ce qu’il permet ni ce qu’un utilisateur peut en faire au moment de l’exécution, de toute façon, configure le noyau:

# tinyconfig      - Configure the tiniest possible kernel
make tinyconfig

construit le noyau

time make V=1 # (should be fast)
#1049168 ./vmlinux (I'm using x86-32 on other arch the size may be different)

le processus de construction du noyau laisse les fichiers cachés appelés *.cmdavec la ligne de commande servant également à construire des .ofichiers, à traiter ces fichiers et à extraire la copie cible et les dépendances script.shci-dessous et à l'utiliser avec find :

find -name "*.cmd" -exec sh script.sh "{}" \;

cela crée une copie pour chaque dépendance de la cible .onommée.o.c

code .c

find -name "*.o.c" | grep -v "/scripts/" | xargs wc -l | sort -n
...
   8285 ./kernel/sched/fair.o.c
   8381 ./kernel/sched/core.o.c
   9083 ./kernel/events/core.o.c
 274692 total

en-têtes .h (désinfectés)

make headers_install INSTALL_HDR_PATH=/tmp/test-hdr
find /tmp/test-hdr/ -name "*.h" | xargs wc -l
...
  1401 /tmp/test-hdr/include/linux/ethtool.h
  2195 /tmp/test-hdr/include/linux/videodev2.h
  4588 /tmp/test-hdr/include/linux/nl80211.h
112445 total

@JonathanLeaders a eu du plaisir à y travailler, content que quelqu'un l'aime
Alex

9

Les compromis entre les noyaux monolithiques ont été débattus en public entre Tananbaum et Torvalds dès le début. Si vous n'avez pas besoin de passer dans l'espace utilisateur pour tout, l'interface du noyau peut être plus simple. Si le noyau est monolithique, il peut être plus optimisé (et plus compliqué!) En interne.

Nous avons eu des modules comme compromis depuis un bon moment. Et cela continue avec des choses comme DPDK (déplacer davantage de fonctionnalités réseau hors du noyau). Plus il y a de noyaux ajoutés, plus il est important d'éviter le verrouillage; ainsi, plus de choses se déplaceront dans l'espace utilisateur et le noyau se réduira.

Notez que les noyaux monolithiques ne sont pas la seule solution. Sur certaines architectures, la limite noyau / espace utilisateur n'est pas plus chère que tout autre appel de fonction, ce qui rend les micro-noyaux attrayants.


1
"Sur certaines architectures, la limite noyau / espace utilisateur n'est pas plus chère que tout autre appel de fonction" - intéressant! Quelle serait cette architecture? Cela semble incroyablement difficile à faire si vous n'abandonnez pas au moins une protection de la mémoire, du moins.
Voo

1
J'ai visionné toutes les vidéos d'Ivan Goddard sur millcomputing.com (unité centrale de traitement / ceinture, très similaire à VLIW). Cette revendication particulière est un thème central et ses implications ne sont évidentes que lorsque vous arrivez à la vidéo de sécurité. C'est une architecture POC en simulation, mais ce n'est probablement pas la seule architecture avec cette propriété.
Rob

1
Ah ça l'explique. D'après mon expérience (et je serai le premier à admettre que je ne suis pas le secteur à la loupe), il existe de nombreuses architectures simulées et rares sont celles qui répondent à leurs revendications dès que la situation se dégage, c'est-à-dire sur du matériel réel. Bien que l'idée sous-jacente puisse être intéressante dans tous les cas - pas la première fois que ce processeur particulier a été mentionné. Si jamais vous trouvez une architecture existante qui possède cette propriété, je serais vraiment intéressé.
Voo

1
BTW, voici plus de ressources sur le débat que vous avez mentionné: en.wikipedia.org/wiki/Tanenbaum%E2%80%93Torvalds_debate
Jonathan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.