Skip to main content
LibreTexts - Ukrayinska

4.2: Організація операційної системи

  • Page ID
    34550
    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)

    Операційна система приблизно організована, як на малюнку нижче.

    Малюнок 4.1. Операційна система. Організація ядра. Процеси ядра працює в прямому ефірі в просторі користувача, і ядро спілкується як безпосередньо з апаратним забезпеченням, так і через драйвери.

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

    Подібно до того, як ядро абстрагує апаратне забезпечення для призначених для користувача програм, драйвери абстрактні апаратні засоби до ядра. Наприклад, існує багато різних типів графічних карт, кожна з яких має дещо різні функції. Поки ядро експортує API, люди, які мають доступ до специфікацій обладнання, можуть писати драйвери для реалізації цього API. Таким чином ядро може отримати доступ до багатьох різних типів обладнання.

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

    Одна дискусія, яка часто виникає навколо операційних систем, полягає в тому, чи має ядро бути мікроядром або монолітним.

    Монолітний підхід є найбільш поширеним, як прийнято більшість поширених Unixes (наприклад, Linux). У цій моделі ядро привілейованого ядра є великим, містить драйвери обладнання, елементи керування доступом до файлової системи, перевірку дозволів і такі служби, як Network File System (NFS).

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

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

    Хоча це звучить як найбільш очевидна ідея, проблема повертається двома основними питаннями

    1. Продуктивність знижується. Розмова між багатьма різними компонентами може знизити продуктивність.
    2. Це трохи складніше для програміста.

    Обидва ці критичні зауваження виникають тому, що для збереження поділу між компонентами більшість мікроядер реалізуються за допомогою системи передачі повідомлень, зазвичай називають міжпроцесним зв'язком або IPC. Спілкування між окремими компонентами відбувається за допомогою дискретних повідомлень, які повинні бути об'єднані, надіслані до іншого компонента, відокремлені, експлуатуються, повторно об'єднані та відправлені назад, а потім знову відокремлені, щоб отримати результат.

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

    У монолітному ядрі виклики між компонентами - це прості виклики функцій, з якими знайомі всі програмісти.

    Немає остаточної відповіді щодо того, яка найкраща організація, і вона розпочала багато аргументів як в академічних, так і в неакадемічних колах. Сподіваємось, коли ви дізнаєтеся більше про операційні системи, ви зможете скласти свій власний розум!

    Ядро Linux реалізує модульну систему, де драйвери можуть завантажуватися в запущене ядро «на льоту» в міру необхідності. Це добре тим, що драйвери, що становлять значну частину коду операційної системи, не завантажуються для пристроїв, яких немає в системі. Той, хто хоче зробити найбільш загальне ядро можливим (тобто працює на багатьох різних апаратних засобах, таких як RedHat або Debian), може включати більшість драйверів як модулі, які завантажуються лише в тому випадку, якщо система, на якій він працює, має доступне обладнання.

    Однак модулі завантажуються безпосередньо в привілейоване ядро і працюють на тому ж рівні привілеїв, що і решта ядра, тому система як і раніше вважається монолітним ядром.

    Тісно пов'язане з ядром концепція віртуалізації апаратних засобів. Сучасні комп'ютери дуже потужні, і часто корисно не розглядати їх як одну цілу систему, а розділити один фізичний комп'ютер вгору на окремі «віртуальні» машини. Кожна з цих віртуальних машин шукає всі наміри та цілі як повністю окрему машину, хоча фізично всі вони знаходяться в одній коробці, в одному місці.

    Малюнок 4.2. Операційна система. Деякі різні методи віртуалізації.

    Це може бути організовано різними способами. У найпростішому випадку невеликий монітор віртуальної машини може працювати безпосередньо на апаратному забезпеченні і забезпечувати інтерфейс гостьових операційних систем, що працюють зверху. Цей ВММ часто називають гіпервізором (від слова «супервізор») [10]. Насправді операційна система зверху може не мати уявлення про те, що гіпервізор взагалі є, оскільки гіпервізор представляє те, що здається повноцінною системою. Він перехоплює операції між гостьовою операційною системою та обладнанням і представляє лише підмножину системних ресурсів для кожного.

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

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

    Нарешті, у вас може виникнути ситуація, коли програма, що працює поверх існуючої операційної системи, представляє віртуалізовану систему (включаючи процесор, пам'ять, BIOS, диск тощо), на якій може працювати звичайна операційна система. Додаток перетворює запити на апаратне забезпечення через базове обладнання через існуючу операційну систему. Це схоже на те, як працює VMware. Цей підхід має багато накладних витрат, оскільки процес подачі заявки повинен емулювати цілу систему та конвертувати все на запити від основної операційної системи. Однак це дозволяє емулювати зовсім іншу архітектуру разом, оскільки ви можете динамічно переводити інструкції з одного типу процесора на інший (як це робить система Rosetta з програмним забезпеченням Apple, яке перейшло від процесора PowerPC до процесорів на базі Intel).

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

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

    Це забезпечує чудову продуктивність, оскільки монітор віртуальної машини не повинен контролювати кожну операцію, щоб побачити, чи безпечна вона, але може чекати, поки процесор не повідомить про те, що сталося щось небезпечне.

    Це відступ, але цікавий недолік безпеки, що стосується віртуалізованих машин. Якщо розбиття системи не статичне, а досить динамічне, виникає потенційна проблема безпеки.

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

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

    Коли один займає великий обсяг пам'яті, є менш доступним для іншого. Якщо обидва відстежують максимальні виділення, можна передати трохи інформації. Скажімо, вони укладають пакт, щоб перевіряти кожну секунду, якщо вони можуть виділити цю велику кількість пам'яті. Якщо мета може, то вважається двійковим 0, а якщо не може (інша машина має всю пам'ять), то вважається двійковим 1. Швидкість передачі даних в один біт в секунду не вражає, але інформація тече.

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

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

    Як обговорювалося раніше, простір користувача є непривілейованим. Користувальницькі програми можуть робити лише обмежений спектр речей, і ніколи не повинні мати можливість аварійно завершити роботу інших програм, навіть якщо вони самі аварійно завершуються.


    [10] Насправді гіпервізор має багато спільного з мікро-ядром; обидва прагнуть бути невеликими шарами, щоб безпечно представити апаратне забезпечення шарам над ним.