Теорія операційної системи

:: Меню ::

Головна
Представлення даних в обчислювальних системах
Машинні мови
Завантаження програм
Управління оперативною пам'яттю
Сегментна і сторінкова віртуальна пам'ять
Комп'ютер і зовнішні події
Паралелізм з точки зору програміста
Реалізація багатозадачності на однопроцесорних комп'ютерах  
Зовнішні пристрої
Драйвери зовнішніх пристроїв
Файлові системи
Безпека
Огляд архітектури сучасних ОС

:: Друзі ::

Карта сайту
 

:: Статистика ::

 

 

 

 

 

Монолітні системи і системи з мікроядром

 

Не бивет монолітних програм, бувають погано структуровані
Репліка з семінару з ООП

Ходова частина танка працює в екстремальних умовах і насилу піддається модернізації
Репліка в ехоконференциі RU.WEAPON мережі
ФІДО

Виконуючи системний виклик, призначена для користувача програма передає управління ядру. З поняттям ядра — комплексу програм, що виконуються в привілейованому (системному) режимі процесора, — ми вже стикалися в разд. Системи з базовою віртуальною адресацією і главі 5 . Практично у всіх сучасних системах ядром є єдиний процес — єдиний адресний простір. Але організація взаємодії між нитками цього процесу в різних системах влаштована по-різному.
Три основні групи ниток, що виконуються в режимі ядра, — це, по-перше, обробники переривань, по-друге — обробники системних викликів з боку призначених для користувача процесів і, по-третє, — нитки, виконуючі різні внутрішні по відношенню до системи роботи, наприклад, управління дисковим кешем. У документації фірми Sun нитки цих трьох груп в ядрі Solaris називаються, відповідно, що виконуються у контексті переривання (interrupt context) у призначеному для користувача контексті (user context) і у контексті ядра (kernel context або контексті системи) [docs.sun.com 805-7378-10].
Далі ми називатимемо останні дві категорії ниток, відповідно, призначеними для користувача і системними, хоча і ті, та інші виконують системний код в системному адресному просторі.
Обробники переривань завжди є особливою статтею — система практично ніколи не має контролю над тим, коли виникають зовнішні події, зате практично завжди зобов'язана обробляти ці події у міру їх появи. Тому обробники переривань отримують управління з потреби.
В той же час, порядок здобуття управління призначеними для користувача і системними нитками у ряді ситуацій знаходиться під контролем системи. Планіровшик є частиною ядра і модулі системи вольні включати його і вимикати в міру необхідності. Практично завжди його вимикають на час роботи обробника переривання, але деякі системи роблять це і при активізації інших ниток ядра.
Повне виключення планувальника на час роботи ядра фактично означає що система не реалізує усередині ядра витісняючої багатозадачності. Системні і призначені для користувача нитки в цьому випадку є співпрограмами а не нитками в повному розумінні цього слова.
Ця архітектура, звана монолітним ядромприваблива приблизно тим же, чим приваблива кооперативна багатозадачність на призначеному для користувача рівні: будь-який модуль ядра може втратити управління лише в двох випадках — при виконання обробника переривання або за власною ініціативою. Завдяки цьому розробник модуля може не турбуватися про критичні секції і інші малоприємні аспекти доступу до даних, що розділяються (окрім, зрозуміло, випадків, коли розділяє дані з обробником переривання).
Платити за ці переваги доводиться значними складнощами при перенесенні системи на багатопроцесорні машини і неможливістю реалізувати режим реального часу. Дійсно, код ядра, написаний з розрахунку на кооперативну багатозадачність, не може бути реєнтерабельним, тому така система в той час, коли виконується якась з її ниток, не може обробляти системні виклики. Отже, вона не може мати призначених для користувача процесів з пріоритетом вище, ніж в ниток ядра — а саме такі процеси потрібні для підтримки додатків реального часу.

Примітка
Ті з читачів, КТО будь-коли намагався реалізувати обробку апаратних переривань під Ms/dr DOS, мають бути добре знайомі з цією проблемою. Всупереч хакреському фольклору, нереєнтерабельність ядра DOS пов'язана зовсім не з переустановленням покажчика стека при вході в обробник переривання 21h, а саме з тим, що ядро працює з даними, що розділяються, але не надає власних засобів для того, що взаємовиключає доступу до них.

Втім, якщо нам не потрібний реальний час і перед нами не коштує завдання забезпечити рівномірний розподіл системних ниток між процесорами симетрично багатопроцесорної машини, монолітне ядро цілком прийнятно. Більшість систем сімейств Unix (фактично, всі широко поширені системи цього сімейства, окрім System V R4) і Win32, Os/2 і ряд інших систем спільного призначення більш менш успішно її використовують.
Альтернативною монолітним ядрам є мікроядро. Мікроядерні системи реалізують витісняючу багатозадачність не лише між призначеними для користувача процесами, але і між нитками ядра.

Мікроядро QNX
Класична реалізація мікроядра, QNX, складається з витісняючого планувальника і примітивів гармонійної міжпоточної взаємодії, засобів для обміну повідомленнями send і receive. Ці примітиви, звичайно ж, самі по собі не можуть бути реалізовані реєнтерабельним чином, проте вони прості, містять дуже мало коди, виконуються швидко, і на час їх виконання система просто забороняє переривання.
Всі останні модулі системи з точки зору мікроядра представляють соб повністю рівноцінні нитки. Те, що деякі з цих ниток виконую в призначеному для користувача, а інші — в привілейованому режимі доступу мікc" ядру абсолютно нецікаво і не впливає на їх пріоритет і клас планіровані QNX розроблявся для додатків реального часу, у тому числі і лл використання у вбудовуваних мікропроцесорних системах; але, благодап компактності і фантастичній продуктивності, ця ОС інколи заменяв системи спільного призначення. Мікроядро QNX дійсно заслуговує на звання мікро, оскільки займає всього 12 кілобайт коди і повністю входить в кеш першого рівня навіть старих процесорів архітектури х86. Всі останні модулі ядра — драйвери зовнішніх пристроїв, файлових систем, мережевих протоколів, імітація API систем сімейства Unix — динамічно завантажуються і вивантажуються і не є обов'язковими (якщо, звичайно, додаток не вимагає сервісів, що надаються цими модулями). Завдяки цьому ОС може використовуватися у вбудовуваних застосуваннях з вельми невеликим об'ємом ПЗП.

Мікроядро трансп'ютера
Іншим прикладом класичного мікроядра є трансп'ютер. Мікропрограмний реалізоване мікроядро трансп'ютера містить планувальник з двома рівнями пріоритету і засобу для передачі даних по лінкам.

Мікроядро Unix Svr4
Інші системи мікроядерної архітектури, наприклад Unix System \/ Release 4.x (на цьому ядрі побудовані такі ОС, як Sun Solaris, SCO Unixware, SGI Irix), надають ниткам ядра значно більше примітивів межпроцессного взаємодії — зокрема, мутекси. Ядро в цих систем в результаті виходить не таким вже "мікро", але нашому визначенню це жодним чином не протіворечит.
Поважно підкреслити, що приведене визначення не має відношення до ряду інших критеріїв, які інколи (наприклад, в дискусіях в публічних комп'ютерних мережах, а нерідко і в публікаціях в більш менш серйозних журналах) помилково приймають за обов'язкові ознаки мікроядерної архітектури. Частково ця плутанина, можливо, створювалася цілеспрямовано, бо в середині 90-х "мікроядро" стало популярним маркетинговим слоганом, і постачальникам багатьох ОС монолітної або еклектичної архітектури захотілося отримати свою долю вигоди від виниклого галасу.
Спосіб збірки ядра (динамічне або статичне пов'язання ядра з додатковими модулями) і можливість динамічного завантаження і вивантаження модулів без перезавантаження системи до мікроядерності не мають жодного відношення. Цілком мікроядерна SCO Unixware за умовчанням пропонує збирати ядро в єдиний завантажувальний файл /stand/unix (хоча, втім, і підтримує динамічне завантаження модулів). Навпаки, не те, що монолітна, а кооперативно багатозадачна Novell Netware чудовим чином уміє загружав і вивантажувати на ходу будь-які модулі, у тому числі і драйвери пристроїв (вивантажувати, зрозуміло, лише за умови, що модуль ніким не використовується).
Один з коріння цих помилок полягає в тому, що в більшості інших контекстів антонімом "монолітній" архітектурі вважається архітектура модульна. Таким чином, будь-яка ознака, що свідчить про те, що ядро ОС має модульну структуру, вважається ознакою мікроядерності. В даному випадку, проте, дихотомія "монолітность/мікроядерность" говорить не про наявність або відсутність в ядрі більш менш автономних модулів або підсистем, а про принципи взаємодії між цими модулями або підсистемами або, точніше, про один аспект цієї взаємодії: про те, що в монолітних ядрах взаємодія відбувається синхронно або переважно синхронно, а в мікроядрі — асихронно.
Зовсім вже наївно було б відмовляти Solaris в праві називатися мікроядерним на тій підставі, що файл /kernel/genunix в цієї системи має розмір близько 900 кілобайт. Адже, окрім власне мікроядра — планувальника ниток і примітивів взаємодії між ними — цей файл містить також диспетчер системних викликів, систему динамічного підвантаження інших модулів ядра (див. разд. Завантаження самою ОС) і ряд інших обов'язкових підсистем.

Мікроядро концептуальне дуже привабливо, але пред'являє до розробників модулів ядра відомі вимоги. Наприклад, в документі [docs.sun.com 805-7378-10] основне з цих вимог — не забувати про те, що ядро Solaris багатопотокове, і будь-яка з ниток ядра може бути у будь-який момент витиснена [практично будь-який] іншою ниткою — висловлюється на другій сторінці, а виводам, які з цього виходять, присвячена ціла глава.
При розробці системи з нуля це само по собі не представляє проблеми, але якщо ми хотіли б забезпечити сумісність з драйверами зовнішніх пристроїв і іншими модулями ядра попередніх версій ОС...
З матеріалу попередньої глави легко зрозуміти, що код, розрахований на роботу в однопоточній середі або середі кооперативної багатозадачності, при перенесенні в багатопотокову середу потребує значної переробки, а нерідко і в тому, що перепроектувало. Таким чином, сделать з монолітної (нехай навіть модульною) системи мікроядерну практично неможливо.
Слід враховувати, що вимога підтримки багатопроцесорних машин Або додатків реального часу часто пред'являється до розробників через багато років після того, як були прийняті архітектурні рішення. про цю ситуацію розробники часто не переходять на мікроядерну архітектуру повністю, а створюють архітектуру гібридну (або, якщо застосувати більш естетський термін, еклектичну).
Дійсно, як говорилося раніше, в чистому мікроядрі взаємодії Відбуваються асихронно, а в чистому монолітному ядрі — синхронно.
Якщо деякі з взаємодій відбуваються асихронно (що наприклад, в багатопроцесорній машині), то ми можемо сказати, що система частково мікроядерна. Якщо ж деякі з взаємодій обов'язково синхронні, ми, напевно, вимушені будемо визнати, що цаї система частково монолітна, як би дивно це не звучало.
Залежно від того, якого роду взаємодії переважають, ми може збудувати цілий спектр більш менш монолітної (і, навпаки, більш або менш мікроядерних) архітектури. На практиці, більшість сучасних ОС спільного призначення мають гібридну архітектуру, яка не є мікроядерною, і в той же час не може бути класифікована як монолітна. Багато з архітектури і, в усякому разі, багато хто з ключових принципів взаємодії між модулями сучасних операційних систем був розроблений ще до того, як з'явилося само слово "мікроядро". При цьому деякі з цих взаємодій мають синхронний, а деякі — особлива взаємодія з драйверами зовнішніх пристроїв — асинхронний характер.
У багато сучасних ОС широко застосовується взаємодія драйверів з останньою системою за допомогою черг запитів (або подій). Така взаємодія частково стирає відмінності між синхронною і повністю асинхронною міжмодульною взаємодією.

 

:: Реклама ::

 

:: Посилання ::


 

 

 


Copyright © Kivik, 2017