суботу, 4 червня 2016 р.

Розповіді про операційні системи від Таненбаума

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

Отож, Ендрю Таненбаум, "Сучасні операційні системи" ("Modern Operating Systems"). 

В принципі, автор окремого представлення не потребує -- живий класик комп'ютерних наук. Згадаю лише, що крім авторства ряду класичних підручників (операційні системи, комп'ютерні мережі, тощо) та якісно нового способу викладати теорію ОС, для реалізації якого було написано POSIX-сумісну ОС MINIX, він має відношення і до виникнення ядра GNU/Linux (*) -- Лінус приступив до роботи якраз під впливом книги та самої MINIX, якою скористатися не міг із ліцензійних міркувань -- тоді такої халяви із безліччю хороших та доступних інструментів, як зараз, не було. Детальніше про нього див, наприклад, вікі: "Ендрю Стюарт Таненбаум".
(*) Правильна назва саме така. "Linux" стосується ядра, розробленого Лінусом Торвальдом, а решта інструментів, що "утворюють" повноцінну операційну систему, походять із проекту GNU.
На жаль, українського перекладу поки не існує, мова йтиме про російський переклад та оригінальне англійське видання.



Читав цю книгу дещо незвично, одночасно три видання -- цікавив ряд питань, які розглядалися в старіших виданнях, але викинутих із нових:
  • "2-е издание", 2002 -- за англомовним виданням 2001 року 
  • "3-е издание", 2010 -- за англомовним виданням 2008 року 
  • "4-е издание", 2015 -- за англомовним виданням 2014 року
Коментар кумедний до 4-го російського видання: "12+ (В соответствии с Федеральным законом от 29 декабря 2010 г. № 436-ФЗ.)", маленьким дітям не давати. :-)
Як бачите, мова справді про сучасні операційні системи. (В комп'ютерному світі слова типу "сучасні", "передові", "продуктивні", "швидкі" старіють та починають викликати сміх дуже швидко).

Останнє, на даний момент, видання -- четверте, дещо відрізняється. У нього тепер два автори, Таненбаум Е. і Бос Х. (Andrew S. Tanenbaum and Herbert Bos), де другого автора представляють як спеціаліста по безпеці UNIX та мережах. У вступі описано багато інших людей, що брали участь в написанні (звичайно, подяка висловлюється і багатьом іншим -- редакторам, помічникам, родині, перераховую лише тих, про кого сказано, що вони долучилися до безпосереднього написання тексту):
  • Едуард Бюньон, (Edouard Bugnion), один із засновників компанії VMware -- матеріали по VMware. 
  • Ада Гавриловска (Ada Gavrilovska) -- автор глави про Linux.
  • Розділ цієї ж глави про Андроїд написано Діаною Хакборн (Dianne Hackborn) з Гугла. 
  • Глава про Windows оновлена Дейвом Пробертом (Dave Probert) з Microsoft.
Виклад нижче, якщо не сказано іншого, стосуватиметься саме четвертого видання.

Вміст 

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

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

Кожна глава завершується пунктом про відповідні актуальні дослідження, короткий підсумок розглянутого та задачі для засвоєння. Доволі творчі чи нетривіальні задачі іноді. Особливо цікаво порівнювати списки літератури різних видань книги -- наочно видно, як змінюються актуальні теми з часом. Іноді на 180 градусів.:-)

Крім того, в кінці книги дано анотований список додаткової літератури до кожної глави -- на додачу до списку посилань  та цитат, використаних в тексті.


"Глава 1. Введение"

Розглядається кілька важливих загальних питань.

По перше, що таке операційна система (ОС) взагалі:
  • Концепція розширеної машини: "Операционная система превращает уродливое аппаратное обеспечение в красивые абстракции", див. рис. 1.2. 
  • Задача керування ресурсами машини та надання доступу до них
  • Деякі ОС реалізовують розмежування різні процеси та різних користувачі. 
Коротко розповідається про історію ОС -- від рудиментарних, на зовсім ранніх машинах, через системи пакетної обробки, багатозадачні ОС, системи розподілу часу до модних зараз "Хмарних обчислень". Розглянуто класичну MULTICS, (обов'язково почитайте хоча б текст на wiki, див. також її фан-сайт!), її відносини із UNIX, та зв'язок the UNIX (маючи на увазі конкуретне сімейство та торгову марку) із її нащадками, включаючи FreeBSD, Linux, Android та навчальну ОС MINIX автора. Зауважте, що ідеї, закладені в MULTICS, зараз знову дуже модні, в реінкарнації хмарних обчислень. Приділено увагу й іншим гілкам розвитку операційних систем: ОС персональних комп'ютерів, починаючи із CP/M, через DOS, 16-бітні Windows та Windows 9x, до Windows NT, відомі зараз під під іменами 2000/XP/Vista/7/8/10 і т.д.; ОС портативних пристроїв [1, 2, 3]; вбудовуваним ОС, ОС реального часу та ОС сенсорних вузлів.

По друге, з якими апаратними засобами ОС доводиться мати справу. Розглянуто:
  • Особливості організації процесорів -- такі фундаментальні поняття, як лічильник команд, стек, слово стану, конвеєр, суперскалярність, переривання, багатопроцесорні/багатоядерні системи. 
  • Пам'ять, її ієрархія (регістри процесора -- кеш -- оперативна пам'ять -- магнітні диски -- магнітні ленти/оптичні диски), трюки збільшення продуктивності, потреба у яких спричинена величезним сучасним (2-2.5 порядки) відставанням  швидкодії пам'яті від швидкодії процесорів (кеші всілякі), ROM/EEPROM.
  • Особливості дискової пам'яті, зокрема, труднощі, викликані наявністю рухомих частина та необхідністю маніпулювати блоками головок. 
  • Пристрої вводу-виводу їх класи, різновиди, особливості. 
  • Шини -- способи з'єднання між собою різних частин комп'ютера.

Далі, дано огляд основних концепцій операційних систем. Процеси, адресні простори, файли, питання безпеки, оболонки для взаємодії із користувачами, системні виклики, їх роль та організацію, як в підході POSIX так і Windows API. (Як я часто люблю повторювати на заняттях, простір "великих" ОС зараз ділиться на два світи, "конфедерація" POSIX та Windows.)

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

Розглянуто підходи до структури ОС: монолітні, багаторівневі, мікроядерні, клієнт-серверна модель (організації ОС), екзоядра.
Слід зауважити, що автор -- послідовний прихильник мікроядерної архітектури. MINIX 3 -- наочний приклад суміщення мінімального мікроядра із клієнт-серверною архітектурою. Ядро містить тільки найнеобхідніше, а все решта, включаючи драйвера, крім драйвера таймер, знаходяться на користувацькому рівні, для взаємодії покладаючись на клієнт-серверну модель. В результаті, вдається досягнути величезної живучості ОС -- відмова більшості драйверів не шкодить решті системи, а то й допускає їх перезапуск без перешкод для нормальної роботи прикладних програм. Якщо коротко, такий підхід має свої плюси -- простоту завдяки модульності, спрощення досягнення надійності, завдяки згаданій простоті, живучість завдяки винесенню всього, що можна, за межі ядра; та свої мінуси, в першу чергу -- повільність, в порівнянні  із підходом, де драйвери "живуть" в ядрі, через додаткові рівні абстракції та необхідність частих перемикань контексту.
Згадуються і віртуальні машини -- як їх перша реінкарнація на великих машинах, типу VM/370, так і "повторне відкриття", цитуючи автора, в світі, який виріс із персональних комп'ютерів (той, що почався із IBM PC 5150, із машинами епохи CP/M в ролі ранніх предків та нелюбимими кузенами від Apple тієї епохи). Розказано про труднощі віртуалізації x86 -- він просто не пристосований для того, щоб робити це ефективно (не задовольняє необхідним теоремам щодо організації системи команд), та розроблені технології обходження його недоліків. Вводиться поняття гіпервізора першого типу, (схожого на ті, що в VM/370) -- який працює на залізі, надаючи всім гостьовим ОС віртуальну машину та гіпервізора другого типу, який працює під котроюсь ОС, дозволяючи з-під неї запускати інші гостьові ОС (але щодо слів "працює під" див. "Відступ про спіральний розвиток" нижче та відповідну главу про VMWare).

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

Решта глав присвячені більше детальному розгляду кожної із згаданих в першій главі тем. З приводу цієї глави див. також "Leaky abstraction" і посилання там.

"Глава 2.   Процессы и потоки"

Певне, найважливіше поняття ОС. Спосіб один реальний процесор "розмножити", надавши можливість псевдопаралельно виконувати на ньому різні програми. (Про різницю між програмою та процесом теж говориться.)

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

Розказано про два підходи до створення процесів -- пара fork/exec в UNIX та єдиний CreateProcess у Windows (правда, слово spawn жодного разу не згадується) та способи їх завершення. Згадується поняття ієрархії процесів, утворені батьківським процесом, його дочірніми, дочірніми дочірніх і т.д, характерну для POSIX-систем (у Windows процеси більш рівноправні). Вводиться фундаментальне поняття про стани процесу -- готовий до виконання, активний, заблокований. Активний процес виконується, заблокований очікує, наприклад, на завершення операції вводу-виводу, готовий до виконання було зупинено, щоб передати процесор іншому процесу, але він здатен почати виконуватися в будь-який момент. 

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

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

Розповідається про міжпроцесну (InterProcess Communication -- IPC) взаємодію, способи її реалізації, використання та проблеми, які в процесі виникають, зокрема -- конкуренцію потоків. Ознайомлюється із засобами боротьби з проблемами потоків, такі як критичні секції, взаємовиключення (мютекси), активне очікування, монітори, команди класу TSL — Test and Set Lock, (без яких неможливо реалізувати більшість примітивів синхронізації, але завдяки яким без цих примітивів іноді можна обійтися -- те, що називають lock-free програмування), семафори, бар'єри пам'яті, тощо. Також розглянуто проблеми, які виникають в процесі використання цих засобів, типу інверсії пріоритетів та задачі філософів, які обідають чи задачі постачальник-споживач. Взагалі, всім цим проблемам присвячена окрема глава -- "Взаємоблокування".

Згадується про фьютекси (fast user space mutex) Linux та "волокна" --- fibers Windows як приклад потоків простору користувача. Дано огляд бібліотеки PThreads -- POSIX threads та засобів Win API для роботи з потоками.

Описано альтернативу до взаємодії потоків через спільну пам'ять (із всіма проблемами синхронізації, з цим пов'язаними) -- обмін повідомленнями.

Багато уваги приділено плануванню виконання потоків. Розглянуто різні алгоритми із їхніми сферами застосування (системи пакетної обробки, інтерактивні системи, системи реального часу, тощо), плюсами та мінусами (швидкість реакції системи, загальна продуктивність, шанси виконуватися для всіх процесів/потоків, і т.д і т.п.). Описуються ускладнення всієї цієї кухні, коли одиниці планування (потоки/процеси, в залежності від ідеології) починають взаємодіяти між собою чи з вводом-виводом (приклад 1: потоку, який був заблокований через очікування вводу-виводу, варто надати процесор, як тільки дані для нього будуть готові -- з одного боку, це може збільшити продуктивність цілої системи, дозволяючи обмеженим швидкістю вводу-виводу потокам працювати із максимальною можливою швидкістю, не заважаючи при тому процесам, обмеженим швидкістю процесора, з іншого -- не змушувати користувачів, що працюють із інтерактивними процесами, терпіти постійні затримки, приклад 2: коли один потік чекає на мютекс, заблокований іншим потоком, часто розумно цьому потоку дати трохи більше часу, щоб він швидше звільнив мютекс). Переказувати більш детально не буду, але дуже повчальний розділ, із багатьма неочевидними висновками.

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

"Глава 3.  Управление памятью"

Ще одна критично важлива тема. Керування важливе для всіх рівнів ієрархії пам'яті, ця глава розглядає лише оперативну, решта видів (крім апаратних кешів процесора) -- дискову, на магнітних лентах, тощо, розглянуто в наступних главах (хи-хи, а про кеш див. "What Every Programmer Should Know About Memory" Ulrich Drepper).

Історично виникло багато підходів до керування оперативною пам'яттю. Відсутність явного керування взагалі, фіксована карта пам'яті, типу тієї, що була в CP/M, мінімальне керування типу доступного в DOS 2.0+, у всіх випадках -- без можливості зупинити зловмисний чи помилковий код від доступу куди б він не захотів. (Автор наводить і значно фундаментальніші історичні приклади). Варіанти апаратного розмежування, потреба в яких виникла для реалізації багатозадачності та можливості одночасного використання багатьма користувачами (кожен із яких аж ніяк не хоче абсолютно довіряти іншим/не заслуговує абсолютної довіри інших) -- сегментація, сторінкова організація. Паралельно розглянуто проблеми релокації коду витіснення процесів (як цілих) та організації віртуальної пам'яті.

Вводиться поняття адресного простору -- множини адрес, доступних процесу. Розділення між MMU -- Memory Management Unit та MPU -- Memory Protection Unit.

Як завжди, багато уваги приділено особливостям реалізації керування пам'яті в ОС -- організації вільної пам'яттю (бітові масиви, зв'язні списки), своппінгом (витісненням), "маніпуляцій" із віртуальною пам'яттю (таблиці сторінок, обернені таблиці -- доволі незвична концепція для тих, хто працював із x86, Translation Lookaside Buffer --- TLB).

Так як сторінкова організація віртуальної пам'яті є дуже важливою в сучасних системах, детально розглянуто різноманітні алгоритми витіснення та підкачки сторінок. Ідеальний алгоритм побудувати не можна -- не можливо передбачити, як кожна програма виконуватиметься (*). Однак, можна його змоделювати -- запустити програму в симуляторі, взнати, які сторінки їй будуть потрібні, і наступного разу запустити її, вчасно надаючи все їй потрібне. Таке моделювання дозволяє побачити ідеальний результат і порівняти, наскільки конкретні алгоритми наближаються до нього.
(*) Згадалася на диво дурацька дискусія із колегою, на загал -- цілком талановитим, грамотним та адекватним. "От чому не напишуть ідеальний оптимізатор для компілятора?!" І ніякі аргументи, що це NP-повна задача, із відповідною тривалістю, навіть сама по собі -- для того ж набору даних, що дані і залізо бувають різні -- із різними вимогами оптимізації, що, в кінці кінців, критерії оптимізації бувають різні -- "котрий вираз, \(a^2+2ab+b^2\) чи \((a+b)^2\) вважати оптимальнішим?", не діяли: "Ні, ідеальний все рівно можна створити, потім тільки покращувати для нової апаратури" і все... При чому, примітивним стьобом це не було.
За детальним списком розглянутих алгоритмів -- див. відповідну главу.

Розглянуто також спільне використання сторінок різними процесами, скажімо, щоб не витрачати фізичну пам'ять на декілька копії однієї і тієї ж програми чи динамічної бібліотеки та відображення файлів на пам'ять. Звертається увага на потребу в можливості фіксувати сторінки за фізичними адресами, скажімо, для потреб DMA.

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

"Глава 4.  Файловые системы"

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

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

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

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

Так як файли можуть належати різним користувачам, важливим є можливість розмежування доступу.

Завершуючи першу частину глави, присвячену "користувацькій" стороні файлів, розповідається про системні виклики для операцій із файлами --- відкривання, знищення, читання, запис, маніпуляція директоріями, правами доступу, блокуванням (під час спільного доступу), тощо. Розповідається про символьні та жорсткі посилання (лінки) на файли.

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

В цій главі розглянуто декілька конкретних прикладів: FAT, ФС UNIX V7, файлові системи оптичних дисків (ISO 9660 і розширення, Rock Ridge та Joliet). Крім того, в главі, присвяченій Linux, детально розбирається ext2fs/ext32f, а в главі про Windows -- NTFS.

В другому виданні описувалася також файлова система CP/M -- примітивна, зате дуже проста і наочна.

"Глава 5.  Ввод и вывод информации"

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

Як вже згадувалося, основна лінія такого поділу -- блочні та символьні пристрої. Різниця між ними у тому, що обмін із першими відбувається пакетами, блоками фіксованого розміру (зазвичай між 512 і 65 536 байт) та можливістю адресації блоків, а з другі, символьні, отримують або повертають потік символів. Звичайно, класифікація ця дещо умовна, з купою граничних випадків -- магнітна лента допускає пошук блоків, однак це неймовірно повільна процедура, екрани із відображенням на пам'ять та сенсорні екрани теж погано вписуються в модель символьного пристрою, а таймери не належить ні до тих ні до інших. При тому, пристрої відрізняють і в швидкостях обміну -- від десятків байт в секунду для клавіатури, до 600+Мб/с для цілком доступних в побуті SATA3 дисків та USB 3.0 пристроїв, 985 Мб/с на один канал  PCIe 3.0 і до багатьох гігабіт в мережах технології SONET.

Пристрій традиційно ділять на дві частини (класичне комп'ютерне "розділяй і володарюй") -- контролер, який надає менш-більш стандартизований інтерфейс ( SATA, SCSI, USB і т.д.) та власне достатньо низькорівневий пристрій, кожен із своїми нюансами.

Одна із популярних схем організації вводу-виводу -- відображення пристроїв на пам'ять. При чому, воно може відбуватися як в адресний простір разом із звичайною RAM, так і в окремому просторі (типу портів вводу-виводу x86). Щоб не займати процесор дріб'язковим керуванням вводом-виводом, використовується DMA -- Direct Memory Access, ідея якого, грубо кажучи, в тому, що процесор наказує спеціальному контролеру DMA -- "береш дані звідси, кладеш там, завершиш -- повідомиш (перериванням)". Прямий доступ до пам'яті має свої плюси та мінуси, які теж розглянуто у відповідних розділах. Розглянуто такі важливі ідеї як синхронний (процес чекає на завершення) та асинхронний (процес продовжує, інформується про завершення за допомогою переривань, сигналів і т.д.) ввід-вивід і буферизацію, що дозволяє мінімізувати вплив непередбачуваності чи "інертності" пристроїв та збільшити загальну продуктивність системи. 

Одна з основних ролей ОС -- абстрагування всього того зоопарку пристроїв у кілька простих концепцій, з якими працюватиме прикладне програмне забезпечення. Файли та спеціальні файли, розглянуті раніше -- приклади таких абстракцій. Для вирішення цієї задачі ОС користується спеціальними модулями -- драйверами, які розробляються для конкретної апаратури, "уніфікуючи" роботу з нею, і можуть компонуватися із ядром ОС як статично (старіші версії UNIX), так і динамічно (DOS, Windows, Linux, більшість інших сучасних UNIX).

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

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

Нарешті, відносно коротко описано безпосередній інтерфейс користувача -- клавіатури, мишки, дисплеї та системне програмне забезпечення, що із ними працює, від текстових терміналів до засобів побудови GUI -- X Windows та Win32 API.

Коротко зачіпаються і додаткові важливі теми -- енергозбереження, шрифти, Plug and play, тощо.

"Глава 6. Взаимоблокировка"

Ця глава -- остання із фундаментальних. Присвячена змаганням між потоками виконання та проблемами, цими змаганнями створені, (про них також йшла мова в главі два). Разомі з другою, глава, обов'язкова до прочитання навіть глибоко-прикладним програмістам!

Розглянуто можливі сценарії взаємоблокувань (deadlock, livelock, starvation, etc), необхідні та достатні умови їх виникнення методики їх моделювання і аналізу, способи їм протистояти у різних ситуаціях, з відповідним аналізом плюсів та мінусів.

"Глава 7. Виртуализация и облако"

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

Детальний розгляд на прикладі гіпервізорів та інших програмних засобів VMware. 

"Глава 8. Многопроцессорные системы"

Тактова частота "на халяву" рости перестала, відповідно, програми перестали ставати "кращими" просто із перебігом часу.  Але закон Мура все ще виконується -- кількість транзисторів росте справно, лише замість зростання тактової частоти почала зростати кількість ядер. І задача багатопроцесорного програмування (як підвиду паралельного) гостро постала й перед "звичайними" програмістами. При тому багатопроцесорні системи ніде не зникли, як і розподілені обчислення. Різниця між багатоядерними та багатопроцесорними системами відносно невелика -- зазвичай вони бачать одну і ту ж пам'ять. Хоча, часто, різні фізичні блоки пам'яті доступні процесорам із різною швидкістю -- кожен процесор має свій блок, до якого під'єднується безпосередньо, маючи швидкий доступ, до інших блоків доступ отримує через "їх" процесори. Процес автоматизований, прозорий для програміста, але він забирає час. Називається ця технологія NUMA --- Nonuniform Memory Access. Розподілені системи, зазвичай -- окремі комп'ютери, із своєю пам'яттю та процесорами, зв'язані між собою тими чи іншими комунікаційними засобами, мережами. Щоб мало не здалося, ядра/процесори можуть бути ще й гетерогенними (наприклад, звичайний x86-64 багатоядерний/багатопроцесорний комп'ютер із обчислювальною відеокартою, котра надає декілька сотень простих обчислювальних ядер зовсім іншої архітектури). Розглянуто ідею RPC -- Remote Procedure Call, як більш високорівневу, в порівнянні із простим обміном даними та "Middleware" -- прошарок, який об'єднує рознесені комп'ютери в (менш-більш) єдину систему. (На жаль, розділ про GRID із третього видання було викинуто.)

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


"Глава 9. Безопасность"

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

Сформульовано вимоги щодо безпеки -- конфіденційність, цілісність, доступність. Розглянуто типові загрози, що можуть загрожувати системам як ззовні так і зсередини: віруси, троянці, черв'яки, помилки в програмному забезпеченні, як прикладному, так і системному. Вводяться поняття доменів захисту та принципів їх реалізації в ОС (користувачі та групи, три тріади прав доступу rwx, ACL -- Access Control Lists, списки можливостей). Показано, що таємним каналам витікання важливої інформації складно протистояти -- подумайте, як можна завадити передачі окремих бітів, загальмовуючи систему для передачі зловмиснику 1 і даючи нормально працювати якийсь квант часу, для 0. Взагалі, цілий розділ глави присвячений типовим способам атаки на безпеку, (від переповнень буфера до інсайдерських атак), засобам їм протистояти (від боротьби із помилками програмування та засобів зменшення шкоди, таких як рандомізація адресного простору до брандмауері, антивірусів та криптографічного підписування довіреного коду), засобам обходу засобів захисту і т.д і т.п. (Все ж, тут класична задача броні та снаряду). Розглянуто ізоляцію підозрілого чи потенційно ненадійного коду -- пісочниці, віртуальні машини, безпека Java.

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

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

Історія із шпигунським програмним забезпеченням від Sony.


"Глава 10. Изучение конкретных примеров: Unix, Linux и Android"

У другому виданні ця глава містила тільки слово Unix, хоча основна увага вже змістилася на Linux. В четвертому додано Android.

Розповідь про конкретні реалізації -- Linux та UNIX-системи, всього, описаного вище. Історія розвитку, стандартизація -- POSIX, виникнення MINIX та Linux. Внутрішня будова -- від драйверів до оболонки, що взаємодіє із користувачем. Командний рядок (bash і компанія), X-Windows. Будова ядра, модулі та драйвери. Реалізація процесів та потоків, демони (фонові процеси), сигнали, системні виклики керування процесами та потоками, планувальники процесів/потоків Linux, засоби синхронізації. Завантаження Linux.  Керування пам'яттю -- як реалізація, так і користувацькі системні виклики. Організація віртуальної пам'яті та підкачки. Ідеологія та реалізація вводу виводу і роботи з мережею (яка має свої нюанси в порівнянні із іншими засобами вводу-виводу), відповідні системні виклики. Файлова система Unix та Linux, віртуальні файлові системи, реалізація та системні виклики. Організація ФС ext2 та її варіанти із журналюванням -- ext3 та ext4, суперблоки, індексні вузли (i-nodes), каталоги, керування вільним місцем, перевірка на цілісність, розмежування доступу, тощо. Спеціальна файлова система /proc, для безпосереднього доступу до пристроїв та інформації з ядра. Мережева файлова система NFS із нюансами її роботи та способом реалізації. Безпека в Linux із всім стандартним комплектом.

Окремо вартує уваги розділ глави про Android. Це ніби і Linux, але використовується він дуже нетрадиційним способом. Причина -- в нетипових задачах. З одного боку, портативні пристрої повинні жорстко економити енергію. З іншого, традиційна система безпеки ОС налаштована захищати одного користувача від інших, але робота в Інтернет змушує запускати потенційно ненадійні/зловмисні програми, скачані з різноманітних джерел. Тому на перший план виходить захист користувача "від самого себе". Поміж характерних особливостей -- відсутність підкачки пам'яті та орієнтація на прикладні програми, написані на Java (в своїй реалізації, Dalvik). Поміж іншого, вводяться поняття активностей (activity) та служб (services), намірів, отримувачів та постачальників контенту (receivers та content providers) за допомогою яких можна компонувати різні прикладні програми та можливості, ними надані, розказано про відповідну спеціалізовану реалізацію взаємодії, Binder IPC. Розглянуто модель безпеки та нюанси її реалізації, зокрема, способи використання процесів Linux.


"Глава 11. Изучение конкретных примеров: Windows 8"

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

Як би там не було, спробую. Як і в главі про Linux, починається виклад із історії -- DOS, 16-бітні Windows, гібридні 16/32 бітні (*), незалежно написані NT, ядро яких і зараз сидить в Windows 2000/XP/Vista/7/8.
(*) Мова як про Windows 3.11, так і про Windows 9x. Технологічний розрив між якими був помітно меншим, ніж зазвичай вважається -- див., наприклад, Эндрю Шульман, "Неофициальная Windows 95", 1995 року. Щоправда, тепер кумедно читати як автор дещо зверхньо ганить Windows NT, протиставляючи його "сірість та зниделість" "яскравому Windows 95". :-)

З того приводу, в більшості місць, де пише "Windows 8.1 робить так-то", слід розуміти, що не тільки виключно 8.1 так робить, а просто Windows із ядром NT так робить, часто аж по 4.0, а то й раніше. Хоча, є важливі винятки!

Розказано про структуру ОС, ядро, інтерфейси програмування (як Native API, так і рекомендовані до використання програмістами Win32/64 API), служби, сучасні (modern) програми -- ті, що поверх WinRT і WinFX API та "традиційні", що користуються Win API, вже відмерлі POSIX та OS/2 підсистеми.

Крім традиційного комплекту: процесів, потоків, (включаючи волокна -- fibers, як потоки прикладного рівня, про які ядро нічого не знає), синхронізації,  керування пам'яттю, кешування, і взагалі ідеології вводу виводу, драйверів, системи безпеки, розглянуто також специфічні для Windows, засоби -- такі, як реєстр. Вводиться відповідна термінологія -- HAL (Hardware Abstraction Level), RPC, DPC (Deferred Procedure Call), APC (Asynchronous Procedure Call), диспетчери та рівні виконання, і т.д.

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

Розказано про структуру та організацію файлової системи -- NTFS, де всі елементи, включаючи MFT (Master File Table) самі по собі є файлами. (Взагалі, дуже добре продумана система, певне краща із користувацьких, із якими я працював, хоча ерудиції та ширини кругозору для фахового порівняння із серверними конкурентами мені бракує.)

"Глава 12. Разработка операционных систем"

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

Хіба що зацитую: "Не скрывай мощь" -- бавлячись в абстракції, не варто ховати прості/зручні/високоефективні способи щось зробити на даній платформі.

Крім того, у автора є окрема, більш спеціалізована книга на цю тему, "Операционные системы. Разработка и реализация", Таненбаум Э.,Вудхалл А., про яку трішки -- в наступному розділі.

"Глава 13. Библиография"

Дуже важливий розділ. Книжок із відповідними ключовими словами, багато. Але відрізнити хороші отак, a priori, важко.

Зацитую декілька прикладів:

  • Silberschatz et al., Operating System Concepts, 9th ed. "Общее руководство по операционным системам. В нем обсуждаются процессы, вопросы управления памятью, управление хранением данных, распределенные системы и защита. Рассматриваются два конкретных примера: Linux и Windows 7"
  • Stallings, Operating Systems, 7th ed. "Еще один учебник по операционным системам. В нем описываются все традицион-ные темы, а также включено небольшое количество материала по распределенным системам."
  • Arpaci-Dusseau and Arpaci-Dusseau, Operating Systems: Three Easy Pieces. "Вся первая часть этой книги посвящена вопросам виртуализации центрального процессора и совместному использованию. Приятной особенностью этой книги (кроме того, что в сети можно найти ее бесплатную версию) является то, что в ней не только дается представление о концепциях технологий обработки и планирова-ния, но и довольно подробно рассматриваются API-функции и такие системные вызовы, как fork и exec."
  • Andrews and Schneider, Concepts and Notations for Concurrent Programming. "Учебный и обзорный материал по процессам и межпроцессному взаимодействию, в котором среди прочего описываются активное ожидание, семафоры, мониторы, передача сообщений и другие технологии. В этой статье также показывается, как эти понятия встроены в различные языки программирования."
  • Ben-Ari, Principles of Concurrent Programming. "Эта небольшая книга полностью посвящена проблемам межпроцессного взаимо-действия. Среди прочих тем в отдельных главах обсуждаются взаимные исключе-ния, семафоры, мониторы и задача обедающих философов, актуальность которой с годами не снижается."
  • Silberschatz et al., Applied Operating System Concepts, 9th ed. "Главы с 3-й по 6-ю посвящены процессам и межпроцессному взаимодействию, включая планирование, критические области, семафоры, мониторы и классические проблемы межпроцессного взаимодействия. Главы 10–12 посвящены аппаратуре хранения информации и файловым системам. В них среди прочего можно найти описания операций с файлами, методов доступа, каталогов и вопросов реализации."
  • Coffman et al., System Deadlocks. "Эта книга представляет собой краткое введение во взаимоблокировки. В ней рассказывается о причинах их возникновения и способах предотвращения или обнаружения"
  • Shub, A Unified Treatment of Deadlock. "Этот краткий учебный курс сводит воедино причины возникновения взаимобло-кировок и пути решения этих проблем"
  • Portnoy, Virtualization Essentials "Легкое введение в виртуализацию. В книге рассматриваются контекст (включая взаимоотношения между виртуализацией и облаком) и различные решения (с уклоном в сторону VMware)."
  • Dubois et al., Synchronization, Coherence, and Event Ordering in Multiprocessors. "Учебная статья по вопросам синхронизации в мультипроцессорных системах с общей памятью. Однако некоторые идеи в равной степени применимы также к однопроцессорным системам и системам с распределенной памятью."
  • Geer, For Programmers, Multicore Chips Mean Multiple Challenges. "Многопроцессорные чипы являются реальностью, и этот факт не зависит от желания программистов. Поскольку они к этому не готовы, программирование таких чипов ставит множество проблем, от выбора правильного инструментария до разбиения задач на этапы и тестирования результатов."
І багато-багато інших!

"Операционные системы. Разработка и реализация"

В принципі, вважати цю книгу повністю незалежною не зовсім правильно. Вона, на перший погляд, являє собою лаконічний, більш сфокусований, переказ того ж, що й в "Сучасних ОС", але кожна глава, крім першої --- "Процеси", "Ввід-вивід", "Керування пам'яттю", "Файлові системи", підкріплена конкретними прикладами із MINIX-3, системи, попередні версії якої, MINIX 1 та 2, були розроблені якраз для навчання. (Третя змістила акцент на надійності, але не стала суттєво складнішою від того -- ядро все ще містить лише трішки більше десятка тисяч рядків). Правда, читати її без консультацій із кодом -- неефективно!


Різниця між виданнями

Кожне наступне видання щось викидає, в основному -- застаріле, (файлова система CP/M) або те, що не виправдало сподівань (Jini), щоб звільнити місце для нового, більш актуального. (Правда, чому наш улюблений GRID випав із 4-го видання -- загадка...)

Дрібний курйоз. В 2 і 3 виданнях, у списку додаткової літератури, про Silberschatz et al., "Operating System Concepts" сказано, що не зрозуміло, до чого на обкладинці динозаври, а в четвертому, що вони символізують древність рішень, які лежать в основі сучасних ОС. :-)

Взагалі, третє видання читається помітно приємніше, ніж друге. Формулювання більш вивірені, приклади акуратніші -- більш опуклі і з меншою кількістю несуттєвих технічних подробиць. Виняток -- глава про Windows мені в 2-му йшла легше, але, як писав вище, напевне це пов'язано із моєю некомпетентністю. Особливої стилістичної відмінності між 3 і 4 не зауважив.

Друге видання формально пише про UNIX, але, фактично, більшість конкретики -- про Linux (хоча є й інші приклади).

У третьому є окрема глава про мультимедійні операційні системи. (Всілякі там відеохостинги та сервери кабельного телебачення). Матеріал видався доволі вузькоспеціалізованим, але повчальним. Для зменшення розміру, в четвертому ця глава не входить в друкований текст, доступна на сайті. Також, є сторіночка-підрозділ про GRID.

Друге -- трішки більше розповідає про давні системи, зокрема -- файлову систему CP/M, примітивну, зате просту.

Маю спокусу купити перше (в Інтернеті не знайшлося, але на Амазоні -- лічені долари), 1992 року, в епоху DOS, а також перше "Операционные системы. Разработка и реализация", де було описано MINIX на 8088/8086 та почитати чисто для історичної перспективи.Якщо хтось захотів би подарувати -- пишіть. ;-)

Коментарі


Стилі авторів. Одна із причин, чому я на початку перерахував авторів окремих частин, наступна. Виклад у книжці  симпатичний -- дружелюбний щодо ідей, технологій, конкретних продуктів та їх авторів, однак, при тому, критичний і дещо іронічний. Книзі це йде на користь -- кожна ідея, кожна реалізація, як би не були в неї закохані автори (не говорячи вже про "шлюб за розрахунком", коли хвалити змушує, чи, хай, спонукає, корпоративна політика), має свої плюси, мінуси, геніальні прозріння і невчасно розпізнані дурні концепції. Однак, в трьох місцях тон раптом стає іншим. Дещо солодкомовним та пафосним. "Продукт <...> был предназначен главным образом для разработчиков и IT-профессионалов", "Впервые IT-администратор получил возможность", "Осуществить мощную поддержку приложений, являющихся собственностью сторонних разработчиков, с помощью надежного и стабильного API", "упростив восприятие приложений пользователями до такой степени", "Модель ввода-вывода мощная и гибкая". Нічого страшного чи, тим більше, поганого, в тому немає. В кінці кінців, як би там не було, все ще не дотягує до рекламних проспектів. Але явно не в дусі решти книги. Здогадайтеся, що це за три місця були? Правильно, розповідь про VMware, Android i Windows. Особливо воно налякало в главі про Windows -- там проявлялося найбільш виразно і довго, думав, ціла глава така буде. Але після вступу ситуація виправилася -- до звичного, в міру іронічного, тону. Зауважу, що абзац вище -- лише мої особисті враження, YMMV.

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

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

Версії Windows. Друге видання пише про Windows 2000, третє -- про Windows Vista, четверте про Windows 8.1. Але, насправді, виклад менш-більш один і той же. Ядро те саме, тому, в більшості випадків, слова "Windows 8.1 робить так-то" означають не те, що от саме 8.1 так робить, а просто Windows із ядром NT так робить, часто аж по 4.0, а то й раніше. Хоча, звичайно, про якісно нові особливості -- модульність та UAC в Vista, модернові аплікації (вони ж сучасні застосунки, вони ж modern applications) Windows 8, теж розповідається. Що цікаво, дві найпопулярніші версії, Windows XP та Windows 7, ні разу не потрапили в заголовки глав різних видань книги -- чи то вона так вдало виходила, чи що...

Стосовно і версій і опечаток, четверте видання, ближче до кінця, регулярно замість Windows 8 каже Widnows Vista. :-)


Резюме

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

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

Взагалі, такі книги дуже важливі. Хоча б для того, щоб розуміти, з одного боку, комп'ютерний світ дуже великий та різноманітний -- не завершується на продуктах Microsoft чи Apple, з іншого -- постійний потік "найновіших", "найсучасніших", "унікальних", "неповторних" і "вперше", на ринку обчислювальних пристроїв -- серверів, комп'ютерів, планшетів, смартфонів, в значній мірі -- просто брижі на поверхні великого океану. Але, верхній шар глазурі постійно радикально оновлюється, звичайно -- треба ж видимість прогресу створювати. (Ribbon bar-b згадуючи, див. опис реакції на вікі, щоб я тут не лаявся. :-)

З іншого боку, через намагання охопити чим-більше концепцій, книга дуже загальна, скласти враження, як воно все працює разом -- майже неможливо.  Однак, див. "Операционные системы. Разработка и реализация". :-)

Трапилася мені в процесі написання цього тексту книга строго протилежного призначення -- опис створення простої ОС для х86: "The little book about OS development", Erik Helin, Adam Renberg.

На жаль, засмутила відсутність розгляду, хоча б -- побіжного, інших важливих систем -- OS/360 і нащадків (про неї хоча б розгорнуто згадується), OS/2, BeOS, Symbian, Blackberry OS, ОС від Apple, як старішу "самобутню" Mac OS, так і актуальні зараз Mac OS X на базі BSD та iOS, та ту ж AmigoOS, чий планувальник один час був неперевершеним, тощо. Зрозуміло, чому його немає -- вони, в кращому випадку, (крім продуктів Apple), не є особливо актуальними, і не є особливо фундаментальними, а книга і так величезна. Але шкода. Ще, із побажань, хотілося б більш ясну главу про Windows. Хоча, повторюся, може просто мені кваліфікації бракує...

Російські 3-тє і 4-те видання, на жаль (в цілях економії?) список посилань (не плутати із списком додаткової літератури) з друкованого видання викинули, кажучи "шукайте на сайті". Це заважало. Не сильно, але достатньо, щоб дратувати.

Відступ про спіральний розвиток


Автор часто наголошує про спіраль історії -- кожна нова технологія проходить приблизно ті ж кола розвитку.
  • Як от, спочатку великі машини (мейнфрейми) рухалися від однокористувацьких, через пакетну обробку до багатокористувацьких, із складними засобами керування, розподілу та захисту ресурсів (наприклад, різних видів пам'яті), а потім і до віртуалізації -- запуску багатьох ОС на тому ж залізі. 
  • Потім ту ж дорогу повторили міні-комп'ютери, далі -- персональні комп'ютери. Згадайте їх розвиток. Частина читачів цього тексту цілком ще може його пам'ятати в деталях: від 8-бітних персоналок із CP/M та 16-бітного 8086/8088 із DOS, через першу спробу організації засобів розмежування та захисту -- 286, значно більш повноцінні інструменти для цього в 386, (не втримаюся від самореклами, див. мою серію "захищений режим", з якої даний блог почався), по апаратну підтримку віртуалізації в сучасних моделях процесорів сімейства x86.  
  • Зараз її повторюють портативні пристрої -- планшети, смартфони. До віртуальної пам'яті вони ще "не доросли", і мають технічно вимушену тенденцію дещо опиратися багатозадачності -- не даючи, по замовчуванню, працювати задачам в фоні (якщо вони про це спеціально не попросили), для економії електроенергії, але велика частина тієї ж спіралі вже можна відстежити.

Навіть послідовні видання книги це демонструють -- мультипроцесорні системи розглядаються в першому, пропадають із другого, але потім знову повертаються.

Такі глобальні приклади важливі. А я хотів би розповісти про значно більш технічний, який трапився в процесі прочитання.

Кожна програма, яка хоче скористатися перевагами захищеного режиму, будь це гра, написана із використанням DPMI чи Widows 10, повинна підтримувати ряд системних таблиць -- GDT, IDT, таблиці сторінок, тощо. Звичайно, вона аж ніяк не хоче очікувати, що паралельно цими ж, фундаментальними для роботи процесора, таблицями, маніпулюватиме ще хтось. Але як подружити дві такі програми? Саме така задача постала під час спроб зробити DOS багатозадачним. Я вже писав рецензію на книжку, присвячену цим проблемам, "Extending DOS". Один із перших систематичних способів її вирішення був VCPI. Ідея полягала в тому, що якщо програми домовляться про кілька поступок (класу -- надавати три селектора в GDT для потреб VCPI, акуратно поводитися в перших 4Мб адресного простору, тощо), то можна надавати їм процесор по черзі, практично повністю переключаючи контекст процесора (всі ті таблиці), так, щоб кожна із них була переконана, що вона має повний контроль над комп'ютером. Щоправда, для цього частину звичних операцій програми повинні були виконувати, звертаючись не до апаратних засобів (типу регістра CR0) безпосередньо, а викликом функцій, наданих VCPI-сервером.

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

Минав час. Виникло бажання запускати кілька ОС на одному і тому ж залізі. Але кожна ОС вважає, що залізом керує тільки вона. Ситуація нічого не нагадує? З'явилися віртуалізатори, які емулювали виконання коду, обманюючи ОС -- переконуючи, що вона працює на реальному залізі, та паравіртуалізатори, які робили майже те саме, але вимагали від ОС, замість безпосереднього звертання до ряду апаратних засобів (типу системних регістрів процесора та системних таблиці), викликати функції паравіртуалізатора (або мінімальні їх "заглушки", якщо ОС працює на самоті). Але це ще таке -- як то кажуть, кожну комп'ютерну проблему можна вирішити, додавши ще один рівень абстракції.
Цитуючи вікіпедію: "A famous aphorism of David Wheeler reads: All problems in computer science can be solved by another level of indirection [Beautiful Code: Chapter 17. Another Level of Indirection]; this is often deliberately mis-quoted with "abstraction" substituted for "indirection". It is also sometimes misattributed to Butler Lampson. Kevlin Henney's corollary to this is, "...except for the problem of too many layers of indirection."" (Посилання на книжку "Beautiful Code" якраз використовує неправильне авторство, але то таке.)
Читаємо, в книзі, якій цей пост присвячено, як  функціонує гіпервізор VMware (VMware  Hosted Architecture):
  • В просторі користувача запускається інтерфейс, VMX.
  • Паралельно використовується невеликий драйвер VMX, задача якого -- надати доступ до режиму ядра.
  • VMM -- Virtual Machine Monitor, найважливіша частина, отримує керування від драйвера, але не працює в контексті операційної системи, займається перемиканням всіх системних контекстів процесора. 
 Зацитую:
VMware Workstation выглядит так, будто запускается поверх существующей операци-онной системы, и, фактически ее компонент VMX запускается как процесс этой опе-рационной системы. Но VMM работает на системном уровне, имея полный контроль над оборудованием и не испытывая никакой зависимости от основной операционной системы. [...] VMM при запуске (в правой половине рисунка) проводит переконфигурацию оборудования, обрабатывает все прерывания и исключения ввода-вывода и поэтому безопасным способом временно удаляет основную операционную систему из своей виртуальной памяти. Например, размещение таблицы прерываний настраивается внутри VMM путем назначения регистру IDTR нового адреса. И наоборот, когда работает основная
операционная система (левая половина рисунка), VMM и его виртуальная машина
точно так же удаляются из ее виртуальной памяти.
Повторюся, нічого не нагадує? :-)



На цьому --
Дякую за увагу!

Немає коментарів:

Дописати коментар