Архітектура операційної системи
Будь-яка складна система повинна мати зрозумілу і раціональну структуру, тобто розділятися на частині — модулі, що мають цілком закінчене функціональне призначення з чітко обговореними правилами взаємодії. Ясне розуміння ролі кожного окремого модуля істотно спрощує роботу з модифікації і розвитку системи. Навпаки, складну систему без чіткої структури частіше простіше розробити заново, ніж модернізувати.
Функціональна складність операційної системи неминуче приводить до складності її архітектури, під якою розуміють структурну організацію ОС на основі різних програмних модулів. За звичай до складу ОС входять щовиконавчі модулі й об'єктні модулі стандартних для даної ОС форматів, бібліотеки різних типів, модулі вихідного тексту програм, програмні модулі спеціального формату (наприклад, завантажник ОС, драйвери введення.виведення), конфігураційні файли, файли документації, модулі довідкової системи і т.д.
Більшість сучасних операційних систем являють собою добре структуровані модульні системи, здатні до розвитку, розширення і переносу на нові платформи. Якої-небудь єдиної архітектури ОС не існує, але існують універсальні підходи до структурування ОС.
Ядро і допоміжні модулі ОС
Найбільш загальним підходом до структуризації операційної системи є поділ усіх її модулів на дві групи:
ядро — модулі, що виконують основні функції ОС;
модулі, що виконують допоміжні функції ОС.
Модулі ядра виконують такі базові функції ОС, як керування процесами, пам'яттю, пристроями введення.виводу і т.п. Ядро складає серцевину операційної системи, без нього ОС є цілком непрацездатною і не зможе виконати жодну зі своїх функцій.
До складу ядра входять функції, що вирішують внутрішньосистемні задачі організації обчислювального процесу, такі як переключення контекстів, завантаження/вивантаження сторінок оперативної пам’яті, обробка переривань. Ці функції недоступні для застосувань (ужитків). Інший клас функцій ядра служить для підтримки застосувань (ужитків), створюючи для них так зване прикладне програмне середовище. Застосування (ужитки) можуть звертатися до ядра з запитами — системними викликами — для виконання тих чи інших дій, наприклад для відкриття і читання файлу, виводу графічної інформації на дисплей, одержання системного часу і т.д. Функції ядра, що можуть викликатися застосуваннями (ужитками), утворять інтерфейс прикладного програмування — API (Application Program Interface)..
Функції, виконувані модулями ядра, є найбільше часто використовуваними функціями операційної системи, тому швидкість їхнього виконання визначає продуктивність усієї системи в цілому. Для забезпечення високої швидкості роботи ОС усі модулі ядра або велика їхня частина постійно знаходяться в оперативній пам'яті, тобто є резидентними.
Ядро є рушійною силою всіх обчислювальних процесів операційної системи, і крах ядра рівносильний краху всієї системи. Тому розробники операційної системи приділяють особливу увагу надійності кодів ядра, у результаті процес їхнього налагодження може розтягуватися на багато місяців.
Звичайне ядро оформляється у вигляді програмного модуля деякого спеціального формату, що відрізняється від формату користувальницьких застосувань (ужитків).
Слід зазначити, що термін «ядро» у різних ОС трактується по-різному. Одним з визначальних властивостей ядра є робота в привілейованому режимі. Це питання буде розглянуте у наступному розділі.
Інші модулі ОС виконують дуже корисні, але менш обов'язкові функції. Наприклад, до таких допоміжних модулів можуть бути віднесені програми архівування даних, дефрагментація диска, текстового редактора. Допоміжні модулі ОС оформляються або у вигляді ужитків (застосувань), або у вигляді бібліотек процедур.
Оскільки деякі компоненти ОС оформлені як звичайні застосування (ужитки), тобто у вигляді модулів, що виконуються, стандартного для даної ОС формату, то часто буває дуже складно провести чітку грань між операційною системою і додатками (рис. 3.1).
Рішення про те, чи є яка-небудь програма частиною ОС чи ні, приймає виробник ОС. Серед багатьох факторів, здатних вплинути на це рішення, немаловажними є перспективи того, чи буде програма мати масовий попит у потенційних користувачів даної ОС.
Деяка програма може існувати визначений час як користувацьке застосування (ужиток), а потім стати частиною ОС, чи навпаки. Яскравим прикладом такої зміни статусу програми є Web-браузер компанії Microsoft, що спочатку поставлявся як окреме застосування (ужиток), потім став частиною операційних систем Windows NT 4.0 і Windows 95/98, а сьогодні існує велика імовірність того, що за рішенням суду цей браузер знову перетвориться в самостійний продукт.

Рис. 3.1. Нечіткість границі між ОС і застосуваннями (ужитками)
Допоміжні модулі ОС за звичай підрозділяються на наступні групи:
утиліти — програми, що вирішують окремі задачі керування і супроводи комп'ютерної системи, такі, наприклад, як програми стиску дисків, архивирования даних;
системні програми обробки — текстові або графічні редактори, компілятори, компоновщики, відлагоджувачі;
програми надання користувачу додаткових послуг — спеціальний варіант користувальницького інтерфейсу, калькулятор і навіть гра;
бібліотеки процедур різного призначення, що спрощують розробку застосувань (ужитків), наприклад бібліотека математичних функцій, функцій введення/виводу і т.д.
Як і звичайні застосування (ужитки), для виконання своїх задач утиліти, що обробляють програми і бібліотеки ОС, звертаються до функцій ядра за допомогою системних викликів (рис. 3.2).
Поділ операційної системи на ядро і модулі-застосування забезпечує легку розширюваність ОС, Щоб додати нову высокорівневу функцію, досить розробити нове застосування (ужиток), і при цьому не потрібно модифікувати відповідальні функції, що утворять ядро системи. Однак внесення змін у функції ядра може виявитися набагато складніше, і складність ця залежить від структурної організації самого ядра. У деяких випадках кожне виправлення ядра може зажадати його повної перекомпіляції.
Рис. 3.2. Взаємодія між ядром і допоміжними модулями ОС
Модулі ОС, оформлені у виді утиліт, системних обробних програм і бібліотек, звичайно завантажуються в оперативну пам'ять тільки на час виконання своїх функцій, тобто є транзитними. Постійно в оперативній пам'яті розташовуються лише найнеобхідніші коди ОС, що складають її ядро. Така організація ОС заощаджує оперативну пам'ять комп'ютера.
Важливою властивістю архітектури ОС, заснованої на ядрі, є можливість захисту кодів і даних операційної системи за рахунок виконання функцій ядра в привілейованому режимі.
Ядро в привілейованому режимі
Для надійного керування ходом виконання застосувань операційна система повинна мати стосовно них визначені привілеї. Інакше некоректно працююче застосування може втрутитися в роботу ОС і, наприклад, зруйнувати частина її кодів. Усі зусилля розробників операційної системи виявляться даремними, якщо їхні рішення втілені в незахищені від застосувань модулі системи, якими б елегантними й ефективними ці рішення ні були. Операційна система повинна мати виняткові повноваження також для того, щоб відігравати роль арбітра в “суперечці” застосувань за ресурси комп'ютера в мультипрограмному режимі. Жодне застосування не повинно мати можливості без відому ОС одержувати додаткову область пам'яті, займати процесор довше дозволеного операційною системою периоду часу, безпосередньо керувати спільно використовуваними зовнішніми пристроями.
Забезпечити привілей операційній системі неможливо без спеціальних засобів апаратної підтримки. Апаратура комп'ютера повинна підтримувати як мінімум два режими роботи — користувальницький режим (user mode) і привілейований режим, що також називають режимом ядра (kernel mode), чи режимом супервізора (supervisor mode). Мається на увазі, що операційна система або деякі її частини працюють у привілейованому режимі, а застосування — у користувальницькому режимі.
Оскільки ядро виконує всі основні функції ОС, тому найчастіше саме ядро стає тією частиною ОС, що працює в привілейованому режимі (рис. 3.3). Іноді ця властивість — робота в привілейованому режимі — служить основним визначенням поняття «ядро».

Рис . 3.3 Архітектура ОС з ядром в привілейованному режимі
Застосування ставляться в підлегле положення за рахунок заборони виконання в користувацькому режимі деяких критичних команд, зв'язаних з переключенням процесора з задачі на задачу, керуванням пристроями введення/виводу, доступом до механізмів розподілу і захисту пам'яті. Виконання деяких інструкцій у користувацькому режимі забороняється безумовно (очевидно, що до таких інструкцій відноситься інструкція переходу в привілейований режим), тоді як інші забороняється виконувати тільки за певних умов. Наприклад, інструкції введення/виводу можуть бути заборонені застосуванням при доступі до контролера твердого диска, що зберігає дані, загальні для ОС і всіх застосувань, але дозволені при доступі до послідовного порту, що виділений у монопольне володіння для визначеного застосування. Важливо, що умови дозволу виконання критичних інструкцій знаходяться під повним контролем ОС і цей контроль забезпечується за рахунок набору інструкцій, безумовно заборонених для користувальницького режиму.
Аналогічним чином забезпечуються привілеї ОС при доступі до пам'яті. Наприклад, виконання інструкції доступу до пам'яті для застосування дозволяється, якщо інструкція звертається до області пам'яті, відведеної даному застосуванню операційною системою, і забороняється при звертанні до областей пам'яті, що їх займає ОС чи іншими застосування. Повний контроль ОС над доступом до пам'яті досягається за рахунок того, що інструкція або інструкції конфигурування механізмів захисту пам'яті (наприклад, зміни ключів захисту пам'яті в мейнфреймах IBM чи покажчика таблиці дескрипторів пам'яті в процесорах Pentium) дозволяється виконувати тільки в привілейованому режимі.
Дуже важливо, що механізми захисту пам'яті використовуються операційною системою не тільки для захисту своїх областей пам'яті від застосувань, але і для захисту областей пам'яті, виділених ОС якому-небудь застосуванню, від інших застосувань. Говорять, що кожне застосування працює у своєму адресному просторі. Ця властивість дозволяє локалізувати некоректно працююче застосування у власній області пам'яті, так що його помилки не роблять впливу на інші застосування й операційну систему.
Між кількістю рівнів привілеїв, реалізованих апаратно, і кількістю рівнів привілеїв, підтримуваних ОС, немає прямої відповідності. Так, на базі чотирьох рівнів, забезпечуваних процесорами компанії Intel, операційна система OS/2 будує трехуровневую систему привілеїв, а операційні системи Windows NT, UNIX і деякі інші обмежуються дворівневою системою.
З іншого боку, якщо апаратура підтримує хоча б два рівні привілеїв, то ОС може на цій основі створити програмним способом як завгодно розвинуту систему захисту.
Ця система може, наприклад, підтримувати кілька рівнів привілеїв, що утворять ієрархію. Наявність декількох рівнів привілеїв дозволяє більш тонко розподіляти повноваження як між модулями операційної системи, так і між самими застосуваннями. Поява усередині операційної системи більш привілейованих і менш привілейованих частин дозволяє підвищити стійкість ОС до внутрішніх помилок програмних кодів, тому що такі помилки будуть поширюватися тільки усередині модулів з визначеним рівнем привілеїв. Диференціація привілеїв у середовищі прикладних модулів дозволяє будувати складні прикладні комплекси, у яких частина більш привілейованих модулів може, наприклад, одержувати доступ до даних менш привілейованим модулів і керувати їх виконанням.
На основі двох режимів привілеїв процесора ОС може побудувати складну систему індивідуального захисту ресурсів, прикладом якої є типова система захисту файлів і каталогів. Така система дозволяє задати для будь-якого користувача визначені права доступу до кожного з файлів і каталогів.
Підвищення стійкості операційної системи, що забезпечується переходом ядра в привілейований режим, досягається за рахунок деякого уповільнення виконання системних викликів. Системний виклик привілейованого ядра ініціює переключення процесора з користувацького режиму в привілейований, а при поверненні до застосування — переключення з привілейованого режиму в користувальницький (рис.. 3.4). В усіх типах процесорів через додаткові подвійні затримки перехід на процедуру зі зміною режиму виконується повільніше, ніж виклик процедури без зміни режиму.

Рис. 3.4. Зміна режимів при виконанні системного виклику до привілейованого ядра.
Архітектура ОС, заснована на привілейованому ядрі і застосуваннях користувацького режиму, стала, власне кажучи, класичною. Її використовують багато популярних операційних систем, у тому числі численні версії UNIX, VAX VMS, IBM OS/390, OS/2, і з визначеними модифікаціями — Windows NT.
У деяких випадках розробники0 ОС відступають від цього класичного варіанту архітектури, організовуючи роботу ядра і застосувань у тому самому режимі. Так, відома спеціалізована операційна система NetWare компанії Novell використовує привілейований режим процесорів Intel x86/ Pentium як для роботи ядра, так і для роботи своїх специфічних застосувань —завантажувальних NLM-модулів (NetWare Loadable Modult) (рис. 3.5). При такій побудові ОС звертання модулів до ядра виконуються швидше, тому що немає переключення режимів, однак при цьому відсутній надійний апаратний захист пам'яті, що займаються модулями ОС, від некоректно працюючого застосування. Розробникі NetWare пішли на таке потенційне зниження надійності своєї операційної системи, оскільки обмежений набір її спеціалізованих застосувань дозволяє компенсувати цей архітектурний недолік за рахунок ретельного налагодження кожного застосування.

Рис. 3.5. Спрощена архітектура операційної системи NetWare
В одному режимі працюють також ядро і додатки тих операційних систем, що розроблені для процесорів, що взагалі не підтримують привілейованого режиму роботи. Найбільш популярним процесором такого типу був процесор Intel 8088/86, що послужив основою для персональних комп'ютерів компанії IBM. Операційна система MS-DOS, розроблена компанією Microsoft для цих комп'ютерів, складалася з двох модулів msdos.sys і io.sys, що складали ядро системи (хоча назва “ядро” для цих модулів не вживалося, по своїй суті вони ним були), до яких з системними викликами зверталися командний інтерпретатор command.com, системні утиліти і застосування. Архітектура MS-DOS відповідає архітектурі ОС, приведеної на рис. 3.2. Некоректно написані застосування цілком могли зруйнувати основні модулі MS-DOS, що іноді і відбувалося, але область використання MS-DOS (і багатьох подібних їй ранніх операційних систем для персональних комп'ютерів, таких як MSX, СР/М) і не пред'являла високих вимог до надійності ОС.
Поява в більш пізніх версіях процесорів Intel (починаючи з 80286) можливості роботи в привілейованому режимі не було використано розроблювачами MS-DOS. Ця ОС завжди працює на процесорах даного типу в так званому реальному режимі, у якому эмулюється процесор 8086/88. Не слід вважати, що реальний режим є синонімом користувакого режиму, а привілейований режим — його альтернативою. Реальний режим був реалізований тільки для сумісності пізніх моделей процесорів з ранньою моделлю 8086/88 і альтернативою йому є захищений режим роботи процесора, у якому стають доступними всі особливості процесорів пізніх моделей, у тому числі і робота на одному з чотирьох рівнів привілеїв.
Багатошарова структура ОС
Обчислювальну систему, що працює під керуванням ОС на основі ядра, можна розглядати як систему, що складається з трьох ієрархічно розташованих шарів: нижній шар утворить апаратура, проміжний — ядро, а утиліти, що обробляють програми і застосування, складають верхній шар системи (рис. 3.6). Шарувату структуру обчислювальної системи прийнято зображати у виді системи концентричних кіл, ілюструючи той факт, що кожен шар може взаємодіяти тільки із суміжними шарами. Дійсно, при такій організації ОС застосування не можуть безпосередньо взаємодіяти з апаратурою, а тільки через шар ядра.

Рис. 3.6. Тришарова схема обчислювальної системи.
Багатошаровий підхід є універсальним і ефективним способом декомпозиції складних систем будь-якого типу, у тому числі і програмних. Кожен з шарів обслуговує вищестоячий шар, виконуючи для нього деякий набір функцій, які утворюють міжшаровий інтерфейс.
Така організація системи має багато переваг, адже вона суттєво спрощує модернізацію системи, оскільки дозволяє міняти модулі всередині шару без необхідності проводити будь-які зміни в інших шарах, якщо при цьому міжшараві інтерфейси залишаються недоторканими.
Поскільки ядро являє собою складний багатофункціональний комплекс, то багатошаровий підхід, як правиило, розповсюджується і на структуру ядра. Ядро може складатися з наступних шарів:
Засобу апаратної підтримки ОС. Дотепер про операційну систему говорилося як про комплекс програм, але, частина функцій ОС може виконуватися й апаратними засобами. Тому іноді можна зустріти визначення операційної системи як сукупності програмних і апаратних засобів, що і відображено на рис. 3.8. До операційної системи відносять, природно, не всі апаратні пристрої комп'ютера, а тільки засоби апаратної підтримки ОС, тобто ті, котрі прямо беруть участь в організації обчислювальних процесів: засоби підтримки привілейованого режиму, систему переривань, засоби переключення контекстів процесів, засоби захисту областей пам'яті і т.п.
Машинно-залежні компоненти ОС. Цей шар утворять програмні модулі, у яких відображається специфіка апаратної платформи комп'ютера. В ідеалі цей шар цілком екранує шари ядра, що розсташовані вище від особливостей апаратури. Це дозволяє розробляти верхні шари на основі машинно-незалежних модулів, що існують у єдиному екземплярі для всіх типів апаратних платформ, підтримуваних даною ОС. Прикладом шару, що екранує, може служити шар HAL (Hardware Abstraction Layer) операційної системи Windows NT.
Базові механізми ядра. Цей шар виконує найбільш примітивні операції ядра, такі як програмне переключення контекстів процесів, диспетчеризацію переривань, переміщення сторінок з пам'яті на диск і назад і т.п. Модулі даного шару не приймають рішень про розподіл ресурсів — вони тільки відпрацьовують прийняті «нагорі» рішення, що і дає привід називати їх виконавчими механізмами для модулів верхніх шарів. Наприклад, рішення про те, що в даний момент потрібно перервати виконання поточного процесу А и почати виконання процесу В, приймається менеджером процесів на вищому шарі, а шару базових механізмів передається тільки директива про те, що потрібно виконати переключення з контексту поточного процесу на контекст процесу В.
Менеджери ресурсів. Цей шар складається з потужних функціональних модулів, що реалізують стратегічні задачі по керуванню основними ресурсами обчислювальної системи. Як правило, на даному шарі працюють менеджери (інколи їх називають диспетчерами) процесів, введення/виведення, файлової системи й оперативної пам'яті. Розбивка на менеджери може бути і трохи іншим, наприклад менеджер файлової системи іноді поєднують з менеджером введення/виведення, а функції керування доступом користувачів до системи в цілому і її окремих об'єктів доручають окремому менеджеру безпеки. Кожний з менеджерів веде облік вільних і використовуваних ресурсів визначеного типу і планує їхній розподіл відповідно до запитів застосувань. Наприклад, менеджер віртуальної пам'яті удравляє переміщенням сторінок з оперативної пам'яті на диск і назад. Менеджер повинен відслідковувати інтенсивність звертань до сторінок, час перебування їх у пам'яті, стани процесів, що використовують дані, і багато інших параметрів, на підставі яких він час від часу приймає рішення про те, які сторінки необхідно вивантажити і які — завантажити. Для виконання прийнятих рішень менеджер звертається до нижчележачого шару базових механізмів із запитами про завантаження (вивантаження) конкретних сторінок. Усередині шару чи менеджерів існують тісні взаємні зв'язки, що відбивають той факт, що для виконання процесу потрібний доступ одночасно до декількох ресурсів — процесору, області пам'яті, можливо, до визначеного файлу або пристрою вводу/виводу. Наприклад, при створенні процесу менеджер процесів звертається до менеджера пам'яті, що повинен виділити процесу визначену область пам'яті для його кодів і даних.
Інтерфейс системних викликів. Цей шар є самим верхнім шаром ядра і взаємодіє безпосередньо з застосуваннями і системними утилітами, утворюючи прикладний програмний інтерфейс операційної системи. Функції API (Aplication Program Interface), що обслуговують системні виклики, надають доступ до ресурсів системи в зручній і компактній формі, без вказівки деталей їхнього фізичного розташування. Наприклад, в операційній системі UNIX за допомогою системного виклику fd = open("/doc/a.txt", O_RDONLY) застосування відкриває файл a.txt, що зберігається в каталозі /doc, а за допомогою системного виклику read(fd, buffer, count) читає з цього файлу в область свого адресного простору, що має ім'я buffer, деяку кількість байт. Для здійснення таких комплексних дій системні виклики звертаються по допомогу до функцій шару менеджерів ресурсів, причому для виконання одного системного виклику може знадобитися кілька таких звертань.

Рис. 3.8. Багатошарова структура ядра ОС.
Наведена розбивка ядра ОС на шари є досить умовною. У реальній системі кількість шарів і розподіл функцій між ними може бути й іншим. У системах, призначених для апаратних платформ одного типу, наприклад ОС NetWare, шар машинно-залежних модулів звичайно не виділяється зливаючись з шаром базових механізмів і частково з шаром менеджерів ресурсів. Незавжди оформляються в окремий шар базові механізми-в цьому випадку менеджери ресурсів не тільки планують використання ресурсів, але й самостійно реалізують свої плани.
Можлива й протилежна картина, коли ядро складається з великої кількості шарів. Наприклад менеджери ресурсів, складаючи визначений шар ядра, можуть самі мати багатошарову структуру. Насамперед це відноситься до менеджера вводу/виводу, нижній шар якого складають драйвери пристроїв, наприклад драйвери жорсткого диску, або драйвери мережевого адаптера, а верхні шари – драйвери файлових системи або протоколів мережевих служб, що мають справу з логічною організацією інформації.
Вибір кількості шарів ядра є непростим питанням: збільшення шарів веде до сповільнення роботи за рахунок додаткових накладних витрат міжшарової взаємодії, а зменшення числа шарів зменшує розширюваність і логічність системи. Як правило ОС, які пройшли довгий шлях еволюційного розвитку, наприклад багато версій UNIX мають невпорядковане ядро з невеликою кількістю чітко виділених шарів,, а порівняно “молода” ОС Windows NT, поділяє ядро на велику кількість шарів і їх взаємодія формалізована більше.