Лекції "Системне програмування"

1. Лекція 1 Створення ОС Windows. Структура ОС Windows

Створення ОС Windows. Структура ОС Windows

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

Мал. 1.1. Шари програмного забезпечення комп'ютерної системи

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

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

Коротка історія створення ОС Windows

Перша версія ряду операційних систем - ОС Windows NT з'явилася в 1993 р Короткий історичний екскурс дозволяє пояснити ряд її особливостей і відмінностей.

Найбільш важливі моменти еволюції операційних систем

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

  • Впровадження захисних механізмів. Захист пам'яті дозволяє ізолювати конкуруючі призначені для користувача програми один від одного, а поява привілейованих і непривілейованих команд - проконтролювати доступ до розподілу ресурсів.
  • Реалізація переривань, оповіщають ОС про що відбулися асинхронних події, наприклад, про завершення операції введення-виведення.
  • Підтримка сукупності системних викликів для організації інтерфейсу між прикладною програмою і ОС.
  • Реалізація дисципліни планування для організації черги з програм в пам'яті і виділення процесора одній з програм.
  • Забезпечення можливості збереження з подальшим відновленням вмісту регістрів і структур даних, необхідних для виконання програми, при перемиканні процесора з однієї програми на іншу.
  • Реалізація стратегії управління пам'яттю - щоб упорядкувати процеси розміщення, заміщення і вибірки інформації з пам'яті.
  • • Організація зберігання інформації на зовнішніх носіях у вигляді файлів і забезпечення доступу до конкретного файлу тільки окремим категоріям користувачів.
  • • Забезпечення програм засобами комунікації та синхронізації.

Архітектурні особливості операційних систем.

В даний час переважна більшість операційних систем має так званий монолітний дизайн.

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

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

 

Сучасна тенденція в розробці операційних систем полягає в перенесенні значної частини системного коду на рівень користувача і одночасної мінімізації ядра. Йдеться про підхід до побудови ядра, яку називають мікроядерною архітектурою (microkernel architecture) операційної системи, коли більшість її складових є самостійними програмами. У цьому випадку взаємодія між ними забезпечує спеціальний модуль ядра, званий мікроядром. Мікроядро працює в привілейованому режимі і забезпечує взаємодію між програмами, планування використання процесора, первинну обробку переривань, операції введення-виведення і базове управління пам'яттю. Інші компоненти взаємодіють шляхом обміну повідомленнями в рамках архітектури клієнт-сервер (Мал. 1.2).


Мал. 1.2. Реалізація моделі клієнт-сервер в рамках мікроядерної архітектури

Створення ОС Windows

Операційні системи корпорації Microsoft можна умовно розділити на три групи:

• MS-DOS і MS-DOS + Windows 3.1,

• так звані споживчі (consumer) версії Windows (Windows 95/98 / Me)

• і лінія ОС, які ведуть свій початок від Windows NT (Windows NT / 2000 / XP / Vista/...).

Однозадачна 16-розрядна ОС MS-DOS була випущена на початку 80-х років і потім широко застосовувалася на комп'ютерах з процесором x86. Спочатку MS-DOS була досить примітивна (деградація ОС), її оболонка займалася, головним чином, обробкою командного рядка, але в наступні версії було внесено багато покращень, запозичених, головним чином, з ОС Unix.

Потім під впливом успіхів дружнього графічного інтерфейсу корпорації Apple для комп'ютерів Macintosh була розроблена система Windows. Особливо широкого поширення набули версії Windows 3.0, 3.1 і 3.11.

Спочатку це була не самостійна ОС, а скоріше багатозадачна (з витісняючою багатозадачностюі) графічна оболонка MS-DOS, яка контролювала комп'ютер і файлову систему.

У 1995 р була випущена 32-розрядна ОС Windows 95, де була реалізована витісняюча багатозадачність. ОС Windows95 включала великий обсяг 16-розрядного коду, головним чином для забезпечення наступності з додатками MS-DOS. 16-розрядний код був присутній і в наступних версіях цієї серії Windows 98 і Windows Me. Іншою проблемою даної версії Windows, багато в чому обумовленої тією ж причиною, була нереентерабельність значної частини коду ядра. Так, якщо один з потоків був зайнятий модифікацією даних в ядрі, інший потік, щоб не отримати ці дані в суперечливому стані, змушений був чекати, тобто не міг скористатися системними сервісами. Це, найчастіше, зводило нанівець переваги багатозадачності.

ОС Windows NT (New Technology) - нова 32-розрядна ОС, сумісна з попередніми версіями Windows по інтерфейсу. Помітна спадкоємність в системі управління великим адресним простором і саморозміщувані безліччю процесу, в системі пріоритетів звичайних процесів і процесів реального часу, в засобах синхронізації і т.д. Разом з тим Windows NT - це абсолютно новий амбітний проект розробки системи з урахуванням новітніх досягнень в галузі архітектури мікроядра. Перша версія, названа Windows NT 3.1 для відповідності популярної Windows 3.1, була випущена в 1993р Комерційного успіху добилася версія Windows NT 4.0, яка мала графічний інтерфейс Windows 95. На початку 1999р була випущена Windows NT 5.0, перейменована в Windows 2000. Наступна версія цієї ОС даної серії - Windows XP з'явилася в 2001 році, а Windows Server 2003 - в 2003р, далі випущена Windows Vista, раніше відома під кодовим ім'ям Longhorn, - нова версія Windows, яка продовжує лінійку Windows NT.

Мал. 1.3. Порівняння архітектур ОС Windows та VAX/VMS

Можливості системи

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

  • є істинно 32(64)-розрядною, підтримує багатозадачність;
  • працює на різних апаратних архітектурах і має здатність до порівняно легкого переносу на нові апаратні архітектури;
  • підтримує роботу з віртуальною пам'яттю;
  • є повністю реєнтерабельною;
  • добре масштабується в системах із симетричною мультипроцесорної обробкою;
  • є розподіленої обчислювальної платформою, здатною виступати в ролі як клієнта мережі, так і сервера;
  • захищена як від внутрішніх збоїв, так і від зовнішніх деструктивних дій. У додатків немає можливості порушити роботу операційної системи або інших додатків;
  • сумісна, тобто, її призначений для користувача інтерфейс і API сумісні з попередніми версіями Windows і MS-DOS. Вона також вміє взаємодіяти з іншими системами на кшталт UNIX, OS/2 і NetWare;
  • має високу продуктивність незалежно від апаратної платформи;
  • підтримує багатопоточність і об'єктну модель.

Структура ОС Windows

Загальний опис структури

Архітектура ОС, зазнала ряд змін в процесі еволюції. Перші версії системи мали мікроядерний дизайн, заснований на мікроядрі Mach, яке було розроблено в університеті Карнегі-Меллона. Архітектура пізніших версій системи мікроядерною вже не є.

Причина полягає в поступовому подоланні основного недоліку мікроядерних архітектур - додаткових накладних витрат, пов'язаних з передачею повідомлень. На думку фахівців Microsoft, чисто мікроядерний дизайн комерційно невигідний, оскільки неефективний. Тому великий обсяг системного коду, в першу чергу управління системними викликами і екранна графіка, був переміщений з адресного простору користувача в простір ядра і працює в привілейованому режимі. В результаті в ядрі ОС Windows переплетені елементи мікроядерної архітектури та елементи монолітного ядра (комбінована система).

Сьогодні микроядро ОС Windows занадто велике (більше 1 Мб), щоб носити приставку "мікро". Основні компоненти ядра Windows NT розташовуються в пам'яті що витісняється і взаємодіють один з одним шляхом передачі повідомлень, як і належить в мікроядерним операційним системам. У той же час всі компоненти ядра працюють в одному адресному просторі і активно використовують загальні структури даних, що властиво операційним системам з монолітним ядром.

Висока модульність і гнучкість перших версій Windows NT дозволила успішно перенести систему на такі відмінні від Intel платформи, як Alpha (корпорація DEC), Power PC (IBM) і MIPS (Silicon Graphic). Пізніші версії обмежуються підтримкою архітектури Intel x86.

Спрощена схема архітектури, орієнтована на виконання Win32/64-додатків, показана на мал. 1.4.

Мал. 1.4. Спрощена архітектурна схема ОС Windows

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

Завдання рівня абстрагування від устаткування (hardware abstraction layer, HAL) - приховати апаратні відмінності апаратних архітектур для потенційного перенесення системи з однієї платформи на іншу. HAL надає вище лежачим рівнями апаратні пристрої в абстрактному вигляді, вільному від індивідуальних особливостей. Це дозволяє ізолювати ядро, драйвери і виконавчу систему ОС Windows від специфіки обладнання (наприклад, від відмінностей між материнськими платами).

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

Ядро і HAL є апаратно-залежними і написані на мовах Сі та асемблера. Верхні рівні написані на мові Сі та є машинно-незалежними.

Виконавча система (executive) забезпечує управління пам'яттю, процесами і потоками, захист, введення-виведення і взаємодія між процесами. Драйвери пристроїв містять апаратно-залежний код і забезпечують трансляцію користувальницьких викликів в запити, специфічні для конкретних пристроїв. Підсистема підтримки вікон і графіки реалізує функції графічного інтерфейсу користувача (GUI), більш відомі як Win-32-функції модулів USER і GDI

У просторі користувача працюють різноманітні сервіси (аналоги демонів в Unix), керовані диспетчером сервісів і вирішальні системні завдання. Деякі системні процеси (наприклад, обробка входу до системи) диспетчером сервісів не справляються і називаються фіксованими процесами підтримки системи. Призначені для користувача програми (user applications) бувають п'яти типів: Win32, Windows 3.1, MS-DOS, POSIX і OS/2.

 Середовище для виконання призначених для користувача процесів надають три підсистеми оточення: Win32, POSIX і OS/2. Таким чином, призначені для користувача програми не можуть викликати системні виклики ОС Windows безпосередньо, а змушені звертатися до DLL.

Основні компоненти ОС Windows реалізовані в наступних системних файлах, що знаходяться в каталозі system32:

  • ntoskrnl.exe - виконавча система і ядро;
  • ntdll.dll - внутрішні функції підтримки і інтерфейси диспетчера системних сервісів з функціями виконавчої системи;
  • hal.dll - рівень абстрагування від устаткування;
  • win32k.sys - частина підсистеми Win32, що працює в режимі ядра;
  • kernel32.dll, advapi32.dll, user32.dll, gdi32.dll - основні dll підсистеми Win32.

Підсистема Win32

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

Win32 API (Application Programming Interface) - основний інтерфейс програмування в сімействі операційних систем Microsoft Windows. Функції Win32 API, наприклад, CreateProcess() або CreateFile(), - документовані, що викликаються підпрограми, реалізовані Win32 підсистемою.

До складу Win32 підсистеми (див. Мал. 1.4) входять:

  • cерверний процес підсистеми оточення csrss.exe,
  • драйвер режиму ядра Win32k.sys,
  • dll - модулі підсистем (kernel32.dll, advapi32.dll, user32.dll і gdi32.dll), експортують Win32-функції і драйвери графічних пристроїв.

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

Додаток, орієнтоване на використання Win32 API, може працювати практично на всіх версіях Windows, незважаючи на те, що самі системні виклики в різних системах різні (див. Мал. 1.5). Таким шляхом корпорація Microsoft забезпечує спадкоємність своїх операційних систем.

Мал. 1.5. Підтримка єдиного програмного інтерфейсу для різних версій Windows

 

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

 

Мал. 1.6. Різні маршрути виконання викликів Win32 API.

При виклику додатком однієї з Win32-функцій dll-підсистем може виникнути одна з трьох ситуацій (див. Мал. 1.6).

  • Функція повністю виконується всередині даної dll (крок 1).
  • Для виконання функції залучається сервер csrss, для чого йому надсилається повідомлення (крок 2a, за яким зазвичай йдуть кроки 2b і 2c).
  • Даний виклик транслюється в системний сервіс (системний виклик), який зазвичай обробляється в модулі ntdll.dll (кроки 3a і 3b). Наприклад, Win32-функція ReadFile виконується за допомогою недокументовані сервісу NtReadFile.

Деякі функції (наприклад, CreateProcess) вимагають виконання обох останніх пунктів.

У перших версіях ОС Windows практично всі виклики Win32 API виконувалися, слідуючи маршрутом 2 (2a, 2b, 2c). Після того, як значна частина коду системи для збільшення продуктивності була перенесена в ядро (починаючи з Windows NT 4.0), виклики Win32 API, як правило, йдуть безпосередньо за 3-му (3a, 3b) шляху, минаючи підсистему оточення Win32. В даний час лише невелика кількість викликів виконується по довгому 2-му маршруту.

Крім перерахованих, найбільш важливих dll-бібліотек, в системному каталозі system32 є велика кількість інших dll-файлів. В даний час кількість викликів API становить кілька десятків тисяч.

Перелік функцій, що експортуються кожною конкретною dll, можна подивитися за допомогою утиліти depends, що входить в пакет Platform SDK. Так, на мал. 1.7 наведена інформація про структуру бібліотеки kernel32.dll ОС Windows XP, що експортує 949 функцій.

Мал. 1.7. Вікно утиліти depends.exe

Процеси і потоки

Під процесом розуміється контейнер ресурсів, використовуваних потоками.

Процес включає:

  •  закритий адресний простір, в якому розташовуються: код, дані та стеки потоків;
  • список відкритих описувачів (handles) ресурсів;
  • контекст захисту;
  • ідентифікатор процесу.

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