Чому для ядра Linux 15+ мільйонів рядків коду? [зачинено]


109

Який зміст цієї монолітної бази коду?

Я розумію підтримку архітектури процесора, безпеку та віртуалізацію, але не можу собі уявити, що це більше 600 000 рядків.

Які історичні та поточні причини драйверів включені до бази коду ядра?

Чи містять ці 15+ мільйонів рядків кожен драйвер для будь-якого обладнання? Якщо так, то тоді виникає питання, чому драйвери вбудовані в ядро, а не окремі пакети, які автоматично виявляються та встановлюються з ідентифікаторів обладнання?

Чи розмір бази коду є проблемою для пристроїв з обмеженою пам’яттю або обмеженою пам’яттю?

Здається, було б роздуто розмір ядра для обмежених простором пристроїв ARM, якби все, що було вбудовано. Чи дуже багато рядків вибито препроцесором? Назвіть мене божевільним, але я не можу уявити, що машина потребує стільки логіки, щоб виконувати те, що я розумію, це ролі ядра.

Чи є докази того, що розмір буде проблемою через 50+ років через його, здавалося б, постійно зростаючого характеру?

У тому числі драйвери означають, що вона зростатиме в міру виготовлення обладнання.

EDIT : Для тих, хто думає, що це природа ядер, після деяких досліджень я зрозумів, що це не завжди. Ядро не потрібно , щоб цей великий, так як Карнегі Меллона мікроядра Mach було вказано в якості прикладу «зазвичай під 10000 рядків коду»


9
Ще в 2012 році він мав понад 5 мільйонів ліній лише для водіїв. 1,9 мільйонів ліній для підтримки різних архітектур процесорів. Більше інформації h-online.com/open/features/…
steve

11
Так, я зашифрував компілятор, лексичний аналізатор і генератор байтових кодів для мови, і це було повним плюс рекурсії, і це не зайняло 10 000 рядків.
Джонатан

5
(подивився на це зараз, це було близько 2700 рядків)
Джонатан

4
Вам слід завантажити та налаштувати, make menuconfigщоб побачити, яку частину коду можна ввімкнути / вимкнути до створення.
Кейсі

6
@JonathanLeaders: Я здійснив створення повних компіляторів для LISP-подібних мов менше ніж у 100 рядках із тестовими програмами, що надають Mandelbrots. Завжди залежить.
phresnel

Відповіді:


43

Драйвери підтримуються в ядрі, тому коли зміна ядра вимагає глобального пошуку і заміни (або зміни в пошуку і руці) для всіх користувачів функції, це робить людина, яка вносить зміни. Оновлення вашого драйвера людьми, які вносять зміни API - це дуже приємна перевага, замість того, щоб робити це самостійно, коли він не компілюється на більш недавнє ядро.

Альтернативою (що трапляється з драйверами, які підтримуються поза деревом), є те, що патч повинен бути синхронізований його технічними працівниками, щоб не відставати від будь-яких змін.

Швидкий пошук викликав дискусію з приводу розробки драйверів проти дерев .

Спосіб підтримки Linux в основному полягає в тому, щоб зберігати все в основному репо. Побудова невеликих збитих ядер підтримується параметрами config для управління #ifdefs. Таким чином, ви можете абсолютно створити крихітні зведені ядра, які складають лише крихітну частину коду в цілому репо.

Широке використання Linux у вбудованих системах призвело до кращої підтримки виходу з матеріалів, ніж у Linux років, коли дерево вихідного ядра було меншим. Супер мінімальне 4.0 ядро, ймовірно, менше, ніж супер мінімальне ядро ​​2.4.0.


4
Тепер ЦЕ має сенс для мене, чому логічно мати весь код разом, це економить людино-години за рахунок комп’ютерних ресурсів та надмірних залежностей.
Джонатан

8
@JonathanLeaders: так, це дозволяє уникнути біт-гнилі для водіїв із не дуже активним обслуговуванням. Можливо, також корисно мати весь код драйвера при розгляді основних змін. Пошук на всіх абонентах якогось внутрішнього API може виявити драйвер, який використовує його таким чином, про який ви не думали, що може вплинути на зміни, про які ви думали.
Пітер Кордес

1
@JonathanLeaders надходять на xd, ніби ці додаткові рядки займають значно більше місця, в сучасних вимірах встановлення його на ПК.
Junaga

3
@Junaga: ти розумієш, що Linux дуже портативний і масштабований, правда? Витрата 1 Мб постійно використовуваної пам'яті ядра у вбудованій системі 32 Мб - це велика справа. Розмір вихідного коду не важливий, але скомпільований двійковий розмір все ще важливий. Пам’ять ядра не підключається до сторінки, тому навіть не змінюючи місця, ви не можете її повернути.
Пітер Кордес

1
@Rolf: Він великий, але це не спагетті. Наразі він досить добре зорієнтований без двосторонньої залежності між основним кодом та драйверами. Драйвери можна залишити, не порушуючи ядро ​​ядра. Коли внутрішня функція або API відремонтована, тому драйвери повинні використовувати її по-різному, драйвери можуть потребувати змін, але це нормально для рефакторингу.
Пітер Кордес

79

За даними Cloc проти 3,13, Linux становить близько 12 мільйонів рядків коду.

  • 7 мільйонів LOC у водіях /
  • 2 мільйони LOC в арці /
  • лише 139 тис. LOC в ядрі /

lsmod | wc на моєму ноутбуці Debian показано 158 модулів, завантажених під час виконання, тому динамічне завантаження модулів - це добре використаний спосіб підтримки апаратного забезпечення.

Надійна система конфігурації (наприклад make menuconfig) використовується для вибору коду для компіляції (і більше для вашого пункту, який код не компілювати). Вбудовані системи визначають власний .configфайл лише за допомогою апаратної підтримки, про яку вони дбають (включаючи підтримку апаратного забезпечення, вбудованого в ядро ​​або як модулі для завантаження).


2
find /lib/modules/$(uname -r)/ -name '*.ko' | wcкаже трохи більше 3000. І FWIW, це Debian , "універсальна операційна система", яка забезпечує повну операційну систему, яка повинна працювати на будь-якому сучасному комп'ютері, побудованому навколо ядра Linux.
drewbenn

3
підрахунок модулів недостатньо, багато можливо, вбудований по конфігурації
Алекс

5
Я думаю, що з цього можна зробити висновок, що ядро ​​Linux є масивним, оскільки воно підтримує всілякі конфігурації пристроїв, а не тому, що це надзвичайно складно. Ми бачимо, що дуже мало 15-метрових ліній фактично використовується. Хоча, як майже всі речі, це може бути надмірно складним, принаймні ми можемо спати вночі, знаючи, що це в межах розуму
Джонатан

2
@JonathanLeaders: Так - і як і модулі для дивних пристроїв, існують модулі для незрозумілих файлових систем, мережевих протоколів тощо ...
psmears

6
@JonathanLeader Я пам’ятаю, коли Linux запускався - навіть змусити інсталятора працювати (якщо він навіть мав інсталятор!) Був величезним болем - все ще є деякі дистрибутиви, де потрібно вибрати драйвер миші вручну. Здійснення таких речей, як мережеві роботи або, не дай Бог, X-window, працювати, було обрядом проходження. Під час моєї першої установки Red Hat мені довелося написати власний графічний драйвер, оскільки в ньому було лише три (!) Драйвери. Якщо основна робота за замовчуванням є ознакою зрілості - і, очевидно, ви можете дозволити собі набагато більше налаштувань на вбудованій системі, де є лише кілька комбінацій HW.
Луань

67

Для всіх, хто цікавиться, ось розбивка лінійки для дзеркала 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сприяє великій кількості лінійних рахунків.


19
Це цікаво. Ще цікавішими є потенційно слабкі місця в коді, де роздратовані програмісти:grep -Pir "\x66\x75\x63\x6b" /usr/src/linux/ | wc -l
jimmij

4
@jimmij '\ x73 \ x68 \ x69 \ x74' може бути більш поширеним у відповідності до цього новаторського (якщо трохи датованого) дослідження .
Нік Т

3
Випадковий факт: папка, яка ближче до 600 000 LOC, що оцінюється ОП, є документацією.
Davidmh

1
./documentationмає понад 500 000 рядків коду? ....що?
C_B

2
@C_B @Davidmh Я думаю, що це прямий wcпідрахунок, який має перевагу бути простішим у визначенні, ніж "рядки коду" :)
drewbenn

43

На сьогодні відповіді виглядають так: "так багато коду", і ніхто не вирішує питання найбільш логічною відповіддю: 15M +? І ЩО? Що стосується 15М рядків вихідного коду з ціною риби? Що робить це таким немислимим?

Linux очевидно робить багато. Багато більше, ніж будь-що інше ... Але деякі ваші пункти показують, що ви не поважаєте те, що відбувається під час його побудови та використання.

  • Не все складено. Система збирання ядра дозволяє швидко визначити конфігурації, які вибирають набори вихідного коду. Деякі експериментальні, деякі старі, деякі просто не потрібні для кожної системи. Подивіться на /boot/config-$(uname -r)(на Ubuntu) в, make menuconfigі ви побачите, скільки виключено.

    І це розподіл настільних пристроїв із змінною цільою. Конфігурація вбудованої системи втягуватиме лише те, що їй потрібно.

  • Не все вбудовано. У моїй конфігурації більшість функцій ядра будуються як модулі:

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

    Щоб було зрозуміло, все це може бути вбудованим ... Так само, як їх можна було роздрукувати і зробити у гігантський паперовий сендвіч. Це було б не має сенсу, якщо ви не робили спеціальну збірку для дискретної апаратної роботи (у такому випадку ви вже обмежили б кількість цих елементів).

  • Модулі динамічно завантажуються. Навіть коли система має тисячі модулів, доступних їй, система дозволить вам завантажувати лише потрібні речі. Порівняйте результати:

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

    Майже нічого не завантажено.

  • Мікрохвилі - це не одне і те ж. Всього за 10 секунд, переглядаючи провідне зображення на пов’язану Вами сторінку Вікіпедії, було б виділено, що вони розроблені зовсім по-іншому.

    Драйвери Linux - це інтерналізовані (здебільшого динамічно завантажені модулі), а не користувацький простір, а файлові системи аналогічно внутрішні. Чому це гірше, ніж використання зовнішніх драйверів? Чому мікро-краще для обчислень загального призначення?


У коментарях знову підкреслюється, що ви цього не отримуєте. Якщо ви хочете розгорнути Linux на дискретному обладнанні (наприклад, аерокосмічному просторі, TiVo, планшеті тощо), ви налаштуєте його на створення лише необхідних драйверів . Ви можете зробити те ж саме на робочому столі за допомогою make localmodconfig. Ви закінчуєте крихітну цільову побудову ядра з нульовою гнучкістю.

Для таких дистрибутивів, як Ubuntu, прийнятний єдиний пакет ядра 40 МБ. Ні, скрутуйте це, що насправді кращим є сценарій масового архівування та завантаження, який би зберігав 4000+ плаваючих модулів як пакетів. Він використовує менше дискового простору для них, простіше пакувати під час компіляції, простіше зберігати та краще для користувачів (у яких система працює просто).

Майбутнє теж не є проблемою. Швидкість швидкості процесора, щільність диска / ціна та поліпшення пропускної здатності здаються набагато швидшими, ніж зростання ядра. Пакет ядра в 200 МБ за 10 років не був би кінцем, якби світ.

Це також не дорога в одну сторону. Код вилучається, якщо він не підтримується.


2
Турбота в основному стосується вбудованих систем. Як показує, у вас 4000 модулів, які не використовуються у вашій власній системі. У деяких невеликих робототехнічних або космічних програмах (ЧИТАЙТЕ: не обчислення загального призначення) це було б неприйнятним відходом.
Джонатан

2
@JonathanLeaders Я думаю, ви можете їх безпечно видалити. Під час встановлення на робочий стіл вони знаходяться на випадок, якщо ви раптом підключите щось до порту usb або зміните конфігурацію обладнання тощо.
Дідьє А.

1
Так, саме. Я все ще дивуюсь припущенням на кшталт "ви можете підключити USB-пристрій у будь-який час, тому нам потрібно 15м рядків коду", записані на рівні ядра , а не на рівні дистрибутива, оскільки Linux використовується в телефоні та інших вбудовані пристрої. Ну, я гадаю, що дистрибутив справді списує список. Я б просто вважав, що підтримка підключення повинна бути додатковою, а не віднімаючою, тобто дистрибутив буде своєрідним "відключенням" до неї, додаючи джерела пакета, на відміну від вбудованих конфігурацій ARM, що ядерця дорівнює одному відсотковій частині його поточного розміру
Джонатан

5
@JonathanLeaders ви ніколи не запускаєте ядро, налаштоване для робочого столу у вбудованій системі. Наша вбудована система має 13 модулів і видалила всю технічну підтримку, яка нам не потрібна (разом з великою кількістю інших налаштувань). Зупиніть порівнювати Настільні ПК із вбудованими системами. Linux працює добре, оскільки він підтримує все і може бути налаштований так, щоб включати лише те, що вам важливо. І ці модулі 4k справді чудові в настільних системах: коли мій останній ноутбук помер, я просто поклав жорсткий диск у набагато новіший ноутбук, і все просто працювало .
drewbenn

3
Ця іначе гарна / цінна відповідь страждає від явно гнівного та войовничого тону. -1.
TypeIA

19

Linux tinyconfig зібрав кількість рядків джерел графічний міхур tinyconfig svg (скрипка)

скрипт оболонки для створення json із збірки ядра, використовуйте з http://bl.ocks.org/mbostock/4063269


Редагувати : виявилося, unifdefщо деякі обмеження ( -Iігноруються та -includeне підтримуються; останній використовується для включення згенерованого заголовка конфігурації) в цьому пункті, використовуючи catне сильно змінюється:

274692 total # (was 274686)

сценарій та процедура оновлені.


Окрім драйверів, арки тощо, існує багато умовного коду, складеного або не залежно від обраної конфігурації, код не обов'язково в динамічних завантажених модулях, але вбудований в ядро.

Отже, завантаживши джерела linux-4.1.6 , вибрав tinyconfig , він не включає модулі, і я, чесно кажучи, не знаю, що він дозволяє або що користувач може зробити з цим під час виконання, все одно, налаштувати ядро:

# tinyconfig      - Configure the tiniest possible kernel
make tinyconfig

побудував ядро

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

процес збирання ядра залишає приховані файли, викликані *.cmdкомандним рядком, який також використовується для створення .oфайлів, для обробки цих файлів та вилучення цілі та залежностей, скопіюваних script.shнижче, та використання їх з find :

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

це створить копію для кожної залежності .oназваної цілі.o.c

.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 заголовки (очищені)

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 було цікаво працювати над цим, радіючи хто - щось на зразок нього
Alex

9

Про компроміси монолітних ядер публічно обговорювались між Тананбаумом та Торвальдом. Якщо вам не потрібно все переходити в простір користувачів, то інтерфейс до ядра може бути простішим. Якщо ядро ​​монолітне, то воно може бути більш оптимізованим (і більш брудним!) Внутрішньо.

У нас модулі були компромісом досить довгий час. І це продовжується з такими речами, як DPDK (переміщення більшої функціональності мережі з ядра). Чим більше ядер додається, тим важливіше уникати блокування; тож більше речей переміститься в простір користувачів, і ядро ​​зменшиться.

Зауважте, що монолітні ядра - не єдине рішення. У деяких архітектурах межа ядра / користувача не є дорожчою за будь-який інший виклик функції, що робить мікроядра привабливими.


1
"У деяких архітектурах межа ядра / користувача не є дорожчою, ніж будь-який інший виклик функції" - цікаво! Що це за архітектура? Виглядає неймовірно важко, якщо ви принаймні не втратите будь-який захист пам’яті.
Voo

1
Я переглянув усі відео на millcomputing.com Івана Годдарда (mup / belt cpu, дуже схожий на VLIW). Ця особлива претензія є центральною темою, і її наслідки не очевидні, поки ви не перейдете до відеозахисту. Це POC архітектура в симуляції, але це, мабуть, не єдина архітектура з цим властивістю.
Роб

1
Так, це пояснює. З мого досвіду (і я буду першим, хто визнає, що не стежу за галуззю, яка пильно стежить), існує багато модельованих архітектур, і мало хто реалізує свої вимоги, як тільки гума потрапляє на дорогу, тобто їх ставлять на реальному обладнання. Хоча ідея, що стоїть за цим, може бути цікавою у будь-якому випадку - вже не вперше згадується саме про цей процесор. Якщо ви коли-небудь знайдете існуючу архітектуру, яка має цю властивість, я був би дуже зацікавлений.
Voo

1
BTW Ось додаткові ресурси щодо згаданих вами дискусій: en.wikipedia.org/wiki/Tanenbaum%E2%80%93Torvalds_debate
Джонатан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.