web-dev-qa-db-fra.com

Pourquoi le noyau Linux compte-t-il plus de 15 millions de lignes de code?

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 ne peux pas imaginer qu'il s'agisse de plus de 600 000 lignes.

Quelles sont les raisons historiques et actuelles pour lesquelles les pilotes sont inclus dans la base de code du noyau?

Ces plus de 15 millions de lignes incluent-elles chaque pilote pour chaque élément matériel? Si c'est le cas, cela soulève alors la question: pourquoi les pilotes sont-ils intégrés dans le noyau et non des packages séparés qui sont détectés automatiquement et installés à partir des ID matériels?

La taille de la base de code est-elle un problème pour les appareils à stockage limité ou à mémoire limitée?

Il semble que cela gonflerait la taille du noyau pour les périphériques à espace limité ARM si tout cela était intégré. Est-ce que beaucoup de lignes sont éliminées par le préprocesseur? Appelez-moi fou, mais je ne peux pas imaginer un machine qui a besoin de beaucoup de logique pour exécuter ce que je comprends, ce sont les rôles d'un noyau.

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

L'inclusion de pilotes signifie qu'il augmentera à mesure que le matériel sera fabriqué.

[~ # ~] 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 . Il n'est pas nécessaire qu'un noyau soit aussi volumineux, car microkernel Mach de Carnegie Mellon était répertorié comme un exemple `` généralement sous 10 000 lignes de code ''

111
Jonathan

Les pilotes sont maintenus dans le noyau, donc quand un changement de noyau nécessite une recherche et remplacement globale (ou recherche et modification manuelle) pour tous les utilisateurs d'une fonction, cela est fait par la personne qui effectue le changement. La mise à jour de votre pilote par des personnes effectuant des changements d'API est un très bel avantage, au lieu d'avoir à le faire vous-même lorsqu'il ne compile pas sur un noyau plus récent.

L'alternative (ce qui se produit pour les pilotes maintenus hors de l'arborescence) est que le correctif doit être resynchronisé par ses responsables pour suivre les modifications.

Une recherche rapide s'est révélée n débat sur le développement de pilotes dans/contre-arbre .

La façon dont Linux est maintenu consiste principalement à garder tout dans le référentiel principal. La construction de petits noyaux dépouillés est prise en charge par des options de configuration pour contrôler #ifdefs. Vous pouvez donc absolument créer de minuscules noyaux dépouillés qui ne compilent qu'une infime partie du code dans l'ensemble du référentiel.

L'utilisation extensive de Linux dans les systèmes embarqués a conduit à une meilleure prise en charge de la suppression de choses que Linux avait des années plus tôt lorsque l'arborescence des sources du noyau était plus petite. Un noyau 4.0 super-minimal est probablement plus petit qu'un noyau 2.4.0 super-minimal.

46
Peter Cordes

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

  • 7 millions de LOC en conducteurs /
  • 2 millions de LOC en Arch /
  • seulement 139 000 LOC dans le noyau /

lsmod | wc sur mon ordinateur portable Debian affiche 158 modules chargés au moment de l'exécution, donc le chargement dynamique de modules est un moyen bien utilisé de supporter le matériel.

Le système de configuration robuste (par exemple make menuconfig) est utilisé pour sélectionner le code à compiler (et plus à votre propos, quel code à pas compiler). Les systèmes embarqués définissent leur propre .config fichier avec juste le support matériel dont ils se soucient (y compris le support matériel intégré au noyau ou en tant que modules chargeables).

79
user4443

Pour toute personne curieuse, voici la répartition du nombre de lignes 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
=============================================

drivers contribue à un lot du linecount.

68
user3276552

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 +? SO QUOI? 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 points montrent que vous ne respectez pas ce qui se passe quand il est construit et utilisé.

  • 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. Certains sont expérimentaux, certains sont anciens, certains ne sont tout simplement pas nécessaires pour tous les systèmes. Regardez /boot/config-$(uname -r) (sur Ubuntu) dans make menuconfig et vous verrez juste combien est exclu.

    Et c'est une distribution de bureau à cible variable. La configuration d'un système embarqué n'apporterait que les éléments dont il 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, ces 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 à moins que vous ne fassiez une construction personnalisée pour un travail matériel discret (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, le système vous permettra de charger exactement 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 de tête du page Wikipedia vous lié mettrait en évidence qu'ils sont conçus d'une manière complètement différente.

    Les pilotes Linux sont internalisés (principalement sous forme de modules chargés dynamiquement), pas l'espace 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 comprenez pas. Si vous souhaitez déployer Linux sur du matériel discret (par exemple, aérospatial, TiVo, tablette, etc.) , vous le configurez pour créer uniquement les pilotes dont vous avez besoin . Vous pouvez faire de même sur votre bureau avec make localmodconfig. Vous vous retrouvez avec une toute petite génération de noyau à usage unique avec une flexibilité nulle.

Pour les distributions comme Ubuntu, un seul package noyau de 40 Mo est acceptable. Non, frottez cela, c'est en fait préférable au scénario d'archivage et de téléchargement massif qui consisterait à conserver plus de 4000 modules flottants en tant que packages. Il utilise moins d'espace disque pour eux, plus facile à empaqueter au moment de la compilation, plus facile à stocker et est meilleur pour leurs utilisateurs (qui ont un système qui fonctionne).

L'avenir ne semble pas non plus être un problème. Le taux d'amélioration de la vitesse du processeur, de la densité/tarification du disque et de la bande passante semble beaucoup plus rapide que la croissance du noyau. Un package de noyau de 200 Mo en 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.

44
Oli

Linux tinyconfig compiled sources line countgraphique à bulles tinyconfig svg (violon)

Script Shell pour créer le json à partir de la construction du noyau, utilisez avec http://bl.ocks.org/mbostock/4063269


Modifier : il s'est avéré que unifdef a une certaine limitation (-I est ignoré et -include non pris en charge, ce dernier est utilisé pour inclure l'en-tête de configuration généré) à ce stade en utilisant cat ne change pas grand-chose:

274692 total # (was 274686)

script et procédure mis à jour.


À côté des pilotes, Arch, etc., il y a beaucoup de code conditionnel compilé ou non selon la configuration choisie, du code pas nécessairement dans des modules chargés dynamiques mais construit dans le noyau.

Donc, téléchargé sources linux-4.1.6 , choisi le tinyconfig, il n'active pas les modules et honnêtement, je ne sais pas ce qu'il permet ou ce qu'un utilisateur peut le faire à l'exécution, de toute façon, configurez 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 des fichiers cachés appelés *.cmd avec la ligne de commande utilisée également pour construire .o fichiers, pour traiter ces fichiers et extraire la cible et les dépendances copier script.sh ci-dessous et utilisez-le avec trouver:

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

cela crée une copie pour chaque dépendance de la cible .o nommé .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

. h en-têtes (nettoyé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
19
Alex

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

Nous avons eu des modules comme compromis pendant un bon moment. Et il continue avec des choses comme DPDK (déplacement de plus de fonctionnalités de mise en réseau hors du noyau). Plus il y a de cœurs ajoutés, plus il est important d'éviter le verrouillage; donc plus de choses se déplaceront dans l'espace utilisateur et le noyau rétrécira.

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

9
Rob