Ядро Linux

Матеріал з Вікі ЦДУ
Перейти до: навігація, пошук

Ядро Linux — ядро UNIX-подібної операційної системи. Розповсюджується під ліцензією GNU General Public License (GPL), і розробляється людьми з усього світу, що дозволило йому стати одним із найвидатніших прикладів відкритого програмного забезпечення[4].

Роботу над Лінукс розпочав Лінус Торвальдс у 1991 році. Тим часом, проект GNU розробив багато компонентів, необхідних для повноцінної вільної операційної системи, але його власне ядро, GNU Hurd було неповним і не було закінченим. Програми проекту GNU та велика кількість людей, що долучилися до розвитку ядра, сприяли його популяризації та створенню повноцінних операційних систем на базі цього ядра, котрі називають дистрибутивами лінукс.

Архітектура

Ядро Linux підтримує багатозадачність, віртуальну пам'ять, динамічні бібліотеки, відкладене завантаження, продуктивну систему управління пам'яттю і багато мережних протоколів.

На сьогоднішній день Linux — монолітне ядро з підтримкою завантажуваних модулів. Драйвери пристроїв і розширення ядра зазвичай запускаються на «кільці 0», з повним доступом до устаткування. На відміну від звичайних монолітних ядер, драйвери пристроїв легко збираються у вигляді модулів і завантажуються або вивантажуються під час роботи системи.

Те, що архітектура Linux не є мікроядерною, викликало дебати між Лінусом Торвальдсом і Ендрю Таненбаумом в конференції comp.os.minix(англ.) в 1992 р.

Структура

Операційну систему можна умовно розділити на два рівні.

На верхньому рівні розташований користувацький простір (простір виконування прикладних програм). Тут виконуються застосунки користувача. Під призначеним для користувача простором розташовується простір ядра. Тут функціонує ядро Linux.

Є також бібліотека GNU C (glibc). Вона надає інтерфейс системних викликів, який забезпечує зв'язок з ядром і дає механізм для переходу від програми, що працює в просторі користувача, до ядра. Це важливо, оскільки ядро і програма користувача розташовуються в різних захищених адресних просторах. При цьому, тоді як кожен процес в просторі користувача має свій власний віртуальний адресний простір, ядро займає один загальний адресний простір.

Ядро Linux можна, у свою чергу, розділити на три великі рівні. Вгорі розташовується інтерфейс системних викликів, який реалізує базові функції, наприклад, читання і запис. Нижче за інтерфейс системних викликів розташовується код ядра, точніше кажучи, незалежний код ядра. Цей код є загальним для всіх процесорних архітектур, підтримуваних Linux. Ще нижче розташовується архітектурно-залежний код, що утворює так званий BSP (Board Support Package — пакет підтримки апаратної платформи). Цей код залежить від процесора і платформи для конкретної архітектури.

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

Властивості ядра Linux

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

З часом ядро Linux стало ефективнішим з погляду використання пам'яті і процесорних ресурсів і набуло виняткової стабільності. Важливий аспект Linux, враховуючи розмір і складність цієї системи — це її переносимість. Linux можна відкомпілювати для величезної кількості різних процесорів і платформ, що мають різні архітектурні обмеження і потреби. Наприклад, Linux може працювати на процесорі як з блоком управління пам'яттю (MMU), так і без MMU. Підтримка процесорів без MMU реалізована у версії ядра uClinux.

Інтерфейс системних викликів

Інтерфейс системних викликів (SCI) — це тонкий рівень, що надає засоби для виклику функцій ядра з простору користувача. Цей інтерфейс може бути архітектурно залежним, навіть в межах одного процесорного сімейства. SCI фактично є службою мультиплексування і демультиплексування виклику функцій. Реалізація SCI міститься в ./linux/kernel, а архітектурно-залежна частина - в ./linux/arch.

Реальна архітектура Linux не цілком слідує "ідеальній" моделі. Наприклад, механізм обробки системних викликів (перехід від простору користувача до простору ядра) може бути різним для різної архітектури. У сучасніших процесорах з архітектурою x86, що мають підтримку інструкцій віртуалізації, цей процес здійснюється ефективніше, ніж в старих процесорах x86, де застосовується традиційний підхід з використанням переривання int 80h.

Керування процесами

Керування процесами сконцентроване на виконанні процесів. У ядрі ці процеси називаються нитями (англ. threads); вони відповідають окремим віртуалізованим об'єктам процесора (код ниті, дані, стек, процесорні регістри). У просторі користувача зазвичай використовується термін процес, хоча в реалізації Linux ці дві концепції (процеси і ниті) не розрізняють. Ядро надає прикладний програмний інтерфейс (API) через SCI для створення нового процесу (породження копії, запуску на виконання, виклику функцій Portable Operating System Interface POSIX), зупинки процесу (kill, exit), взаємодії і синхронізації між процесами (сигнали або механізми POSIX).

Ще одне завдання керування процесами — сумісне використання процесора активними нитями. У ядрі реалізований новаторський алгоритм планувальника, час роботи якого не залежить від числа нитей, що претендують на ресурси процесора. Назва цього планувальника — O(1) — підкреслює, що на диспетчеризацію одної ниті витрачається стільки ж часу, як і на множину нитей. Планувальник O(1) також підтримує симетричні багатопроцесорні конфігурації (SMP).

Керування пам'яттю

Інший важливий ресурс, яким управляє ядро, — це оперативна пам'ять. Для підвищення ефективності, враховуючи механізм роботи апаратних засобів з віртуальною пам'яттю, пам'ять організовується у вигляді так званих сторінок (у більшості архітектури розміром 4 КБ). У Linux є засоби для управління наявною пам'яттю, а також апаратними механізмами для встановлення відповідності між фізичною і віртуальною пам'яттю.

Проте управління пам'яттю — це значно більше, чим просто управління буферами по 4 КБ. Linux надає абстракції над цими 4 КБ буферами, наприклад, механізм розподілу slab allocator. Цей механізм управління базується на 4 КБ буферах, але потім розміщує структури усередині них, стежачи за тим, які сторінки повні, які частково заповнені і які порожні. Це дозволяє динамічно розширювати і скорочувати схему залежно від потреб розміщеної системи.

В умовах наявності великого числа користувачів у пам'яті можливі ситуації, коли вся наявна пам'ять буде вичерпана. У зв'язку з цим сторінки можна видаляти з пам'яті і переносити на диск. Цей процес обміну сторінок між оперативною пам'яттю і жорстким диском називається підкачкою.

Драйвери пристроїв

Переважна більшість початкового коду ядра Linux припадає на драйвери пристроїв, що забезпечують можливість роботи з конкретними апаратними пристроями. У дереві початкових кодів Linux є підкаталог драйверів, в якому, у свою чергу, є підкаталоги для різних типів підтримуваних пристроїв, таких як Bluetooth, I2C, послідовні порти тощо.

Відмінності від Unix

Ядро Linux підтримує динамічне завантаження модулів ядра. Хоча ядро Linux і є монолітним, воно додатково підтримує динамічне завантаження і вивантаження виконуваного коду ядра за потреби Ядро Linux підтримує симетричну багатопроцесорну обробку (SMP). Хоча більшість комерційних варіантів операційної системи Unix зараз підтримують SMP, більшість традиційних реалізацій ОС Unix такої підтримки не мають. Ядро Linux є преемптивним (витісняючим). На відміну від традиційних варіантів ОС Unix, ядро Linux в змозі витіснити завдання, що виконується, навіть якщо це завдання працює в режимі ядра. Серед комерційних реалізацій ОС Unix преемптивне ядро мають тільки операційні системи Solaris і IRIX. У ядрі Linux використовується цікавий підхід для підтримки багатонитевості (multithreading): ниті нічим не відрізняються від звичайних процесів. З погляду ядра всі процеси однакові, просто деякі з них мають спільні ресурси. У ядрі Linux відсутні деякі функції ОС Unix, які вважаються погано реалізованими, як, наприклад, підтримка інтерфейсу STREAMS, або відповідають "недолугим" стандартам. Ядро Linux є повністю відкритим у повному розумінні цього слова. Набір функцій, реалізованих в ядрі Linux, — це результат вільної і відкритої моделі розробки операційної системи Linux. Якщо якась функція ядра вважається несуттєвою або неякісною, то розробники ядра не зобов'язані її реалізувати. В протилежність цьому, внесення змін при розробці ядра Linux займає “елітарну” позицію: зміни повинні вирішувати певну практичну задачу, повинні бути логічними і мати зрозумілу чітку реалізацію. Отже, функції деяких сучасних варіантів ОС Unix, такі як пам'ять ядра із сторінковою реалізацією, не були реалізовані. Незважаючи на наявні відмінності, Linux є операційною системою зі строгим спадкоємством традицій ОС Unix.