Глобальна таблиця дескрипторівГлобальна таблиця дескрипторів або GDT (англ. Global Descriptor Table) — одна з найважливіших структур даних в комп'ютерній архітектурі x86. Ця структура допомагає керувати доступом до пам'яті та її захистом. Введена разом із процесором Intel 80286, вона відіграє ключову роль у визначенні сегментів пам'яті та їхніх атрибутів: базової адреси, розміру та різних допоміжних атрибутів, таких як права доступу, права на виконання чи на запис та ін.[1] Хоча сучасні 64-бітні системи рідко покладаються на сегментацію, GDT залишається необхідним компонентом для запуску 64-бітного режиму роботи процесора та керування певними завданнями системного рівня. ОписКожен доступ до пам'яті, що виконується x86 процесором, завжди проходить через сегмент. На процесорі 80386 і пізніших моделях, завдяки 32-бітним зміщенням та обмеженням сегментів, можливо зробити так, щоб сегменти охоплювали всю адресовану пам'ять, що робить сегментно-відносну адресацію прозорою для користувача. Щоб посилатися на сегмент, програма повинна використовувати його індекс всередині GDT або LDT. Такий індекс називається селектором сегментів (або селектором). Для використання селектор необхідно завантажити в сегментний регістр. Окрім машинних інструкцій, які дозволяють встановлювати/отримувати позицію GDT та таблиці дескрипторів переривань (IDT) у пам'яті, кожна машинна інструкція, що звертається до пам'яті, має неявний сегментний регістр, іноді два. У більшості випадків цей сегментний регістр можна перезаписати, додавши префікс сегмента перед інструкцією. GDT таблиця визначає доступ до різних сегментів, тим самим ізолюючи пам'ять різних прикладних програм одну від одної та відділяючи її від пам'яті ядра операційної системи. Структура GDT використовується в основному у захищеному режимі (більш просунутий режим процесора, який дозволяє захист пам'яті та контроль доступу), в цьому режимі вона визначає:
Кожен запис у GDT має довжину 8 (у 32-бітних системах) або 16 байт (у 64-бітних) і містить дескриптор сегмента, тобто запис, котрий визначає властивості одного сегмента пам'яті. Кожен дескриптор містить атрибути бази, розміру, та прав доступу, чим забезпечується коректна робота з пам'яттю. Таблиця GDT може містити від 1 до 8192 дескрипторів і обов'язково починається з нульового дескриптора, звернення до якого викликає виняток «Загальна помилка захисту» (англ. General protection fault), чим забезпечується захист від звернення до пам'яті з використанням неініціалізованого сегментного регістру, тобто такого, в який не було завантажено селектор. Формат кожного дескриптора склався історично і має наступну структуру[1]:
![]() Завантаження селектора у сегментний регістр зчитує запис GDT або LDT під час його завантаження та кешує властивості сегмента в прихованому регістрі. Таке завантаження селектора сегмента семантично схоже з присвоєнням значення адреси цьому регістру, як це часто робиться у реальному режимі процесора. Однак у захищеному режимі роботи процесора таке присвоєння насправді використовує селектор сегмента — спеціальне значення, по суті індекс у таблиці GDT[a], що вказує процесору, який запис GDT використовувати. Потім процесор завантажує цей дескриптор у регістр сегмента, який містить як видимі, так і приховані метадані про сегмент. ; завантаження GDT, котра розміщена за адресою gdt_desc
lgdt fword ptr [gdt_desc]
; завантаження у сегментний регістр DS посилання на 1-й елемент в GDT
mov ax, 8
mov ds, ax
GDT у 64-бітній версіїУ 64-бітному режимі сегментація здебільшого вимкнена: усі бази сегментів розглядаються як нульові, а обмеження ігноруються, створюючи «плоский» (англ. flat) адресний простір. Однак, GDT все ще повинен визначати системні дескриптори, такі як сегмент стану завдання (TSS). Два сегментні регістри, FS та GS, залишаються активними та часто використовуються операційними системами для зберігання локальних потоків або даних, специфічних для процесу (наприклад, локальний TLS-блок потоку виконання у Windows або gs_base у Linux).[1] Примітно, що Windows застосовує суворі заходи захисту GDT: спроби підмінити або змінити GDT у 64-розрядних версіях призведуть до збою системи.[3] Таблиця локальних дескрипторівТаблиця GDT визначає загальносистемні сегменти; водночас в системі може існувати таблиця локальних дескрипторів (англ. LDT), котра визначатиме сегменти, які є приватними для одного процесу. Історично операційні системи використовували LDT для розділення пам'яті кожної програми на приватні області, особливо до введення механізму підкачування сторінок в процесорі Intel 80386. Після поширення ОС захищеного режиму, таблиці LDT застаріли, але все ще можуть з'являтися для сумісності з 16-розрядними або старішими 32-розрядними програмами (наприклад, програмами DOS або OS/2). LDT визначається окремим записом у GDT та може містити до 8192 дескрипторів сегментів.[2] Історія та сучасне використанняУ ранніх системах x86 (таких як 80286) сегментація за допомогою GDT та LDT була критично важливою для реалізації багатозадачності та ізоляції пам'яті. Кожен процес мав власну LDT, тоді як GDT містив глобальні визначення. Система могла автоматично перемикати поточний LDT під час зміни завдань, що робило ізоляцію на основі сегментів ефективною.[b]. З появою системи віртуальної пам'яті Підкачування сторінок на процесорі 80386, операційні системи почали використовувати сторінкову віртуальну пам'ять замість сегментної. Підкачування дозволяє детальне управління пам'яттю фрагментами по 4 КБ та спрощує спільний доступ до пам'яті або її захист. В результаті, сучасні операційні системи, такі як Windows, Linux та macOS, використовують модель «плоскої пам'яті», де всі сегменти коду та даних охоплюють весь адресний простір. Однак, GDT все ще бере участь в ініціалізації системи, обробці переривань та визначенні спеціальних структур, таких як покажчик TSS та LDT.[1] Застарілі режими або режими сумісності (наприклад, виконання 16-бітного коду DOS або OS/2) можуть все ще активно використовувати сегментацію. У таких випадках можна використовувати техніку, відому як мозаїчне розбиття LDT, де LDT заповнюється дескрипторами, які відображають блоки пам'яті фіксованого розміру (наприклад, по 64 КБ кожен), щоб забезпечити покриття для застарілих програм. Ще одним прикладом специфічного використання GDT є Unreal mode — незвичний режим роботи процесора, де через використання недокументованої можливості процесора у 16-бітному реальному режимі програмам стає доступна пам'ять поза стандартним лімітом в 1 МБ (аж до 4 ГБ). Посилання
Джерела
|
Portal di Ensiklopedia Dunia