Версія цієї відповіді з приємним TOC та більше змісту .
Я виправлю будь-яку повідомлення про помилку. Якщо ви хочете внести великі зміни або додати відсутній аспект, зробіть їх за власними відповідями, щоб отримати заслужену репутацію. Незначні редагування можна об’єднати безпосередньо в.
Зразок коду
Мінімальний приклад: https://github.com/cirosantilli/x86-bare-metal-examples/blob/5c672f73884a487414b3e21bd9e579c67cd77621/paging.S
Як і все інше в програмуванні, єдиний спосіб зрозуміти це - грати з мінімальними прикладами.
Що робить цю "важку" тему тим, що мінімальний приклад великий, тому що вам потрібно створити власну маленьку ОС.
Інструкція Intel
Хоча це неможливо зрозуміти, не маючи на увазі приклади, спробуйте ознайомитись з посібниками якомога швидше.
Корпорація Intel описує підкачки у Посібнику із програмування системного програмування, том 3, том 3 - 325384-056US, вересень 2015 року Розділ 4 " ".
Особливо цікавим є малюнок 4-4 "Формати записів CR3 та структури підкачки з 32-розрядною підкачкою", де наводяться ключові структури даних.
MMU
Підкачка здійснюється блоком керування пам'яттю (MMU), частиною ЦП. Як і багато інших (наприклад, співпроцесор x87 , APIC ), раніше це було окремим чіпом, який згодом був інтегрований в центральний процесор. Але цей термін все ще використовується.
Загальні факти
Логічні адреси - це адреси пам'яті, що використовуються у "звичайному" коді земельної ділянки користувача (наприклад, вміст rsi
вmov eax, [rsi]
).
Спочатку сегментація перетворює їх у лінійні адреси, а потім підкачка, а потім перетворює лінійні адреси у фізичні адреси.
(logical) ------------------> (linear) ------------> (physical)
segmentation paging
Здебільшого ми можемо сприймати фізичні адреси як індексацію фактичних комірок апаратної пам'яті оперативної пам'яті, але це не на 100% вірно через:
Підкачка доступна лише в захищеному режимі. Використання підкачки у захищеному режимі є необов’язковим. Виклик сторінки відбувається, якщо PG
трохиcr0
реєстру.
Пейджинг проти сегментації
Однією з основних відмінностей між пейджингом та сегментацією є те, що:
- підкачка розділяє оперативну пам'ять на однакові за розміром фрагменти, що називаються сторінками
- сегментація розбиває пам'ять на шматки довільних розмірів
Це головна перевага пейджингової сторінки, оскільки шматки однакового розміру роблять речі більш керованими.
Підкачка сторінок стала настільки популярнішою, що підтримка сегментації була скасована в x86-64 в 64-розрядному режимі - основному режимі роботи нового програмного забезпечення, де воно існує лише в режимі сумісності, який імітує IA32.
Застосування
Підкачка використовується для реалізації процесів віртуального адресного простору в сучасній ОС. За допомогою віртуальних адрес ОС може вмістити два або більше одночасних процесів в одній ОЗУ таким чином, щоб:
- обидві програми не повинні нічого знати про іншу
- пам'ять обох програм може зростати і зменшуватися за потреби
- перемикання між програмами відбувається дуже швидко
- одна програма ніколи не може отримати доступ до пам'яті іншого процесу
Підкачка сторінок історично з’явилася після сегментації і значною мірою замінила її для впровадження віртуальної пам'яті в сучасних ОС, таких як Linux, оскільки простіше керувати фіксованими шматками пам'яті сторінок замість сегментів змінної довжини.
Апаратне впровадження
Як і сегментація в захищеному режимі (де зміна реєстру сегментів викликає навантаження з GDT або LDT), апаратне забезпечення пейджингового зв'язку використовує структури даних у пам'яті для виконання своєї роботи (таблиці сторінок, каталоги сторінок тощо).
Формат цих структур даних фіксується апаратним забезпеченням , але операційна система повинна правильно налаштувати та керувати цими структурами даних в оперативній пам'яті та повідомити апаратному забезпеченню, де їх знайти (черезcr3
).
Деякі інші архітектури залишають підкачку сторінок майже повністю в руках програмного забезпечення, тому пропуск TLB запускає функцію, що постачається з ОС, для проходження таблиць сторінок та вставки нового відображення в TLB. Це залишає форматів таблиць сторінок для вибору ОС, але робить малоймовірним, що апаратне забезпечення може перекривати прогулянки сторінок із невпорядкованим виконанням інших інструкцій, як це може зробити x86 .
Приклад: спрощена однорівнева система підкачки
Це приклад того, як підкачка працює на спрощеній версії архітектури x86 для реалізації простору віртуальної пам'яті.
Таблиці сторінок
ОС може дати їм такі таблиці сторінок:
Таблиця сторінок, надана ОС 1 процесу 1:
RAM location physical address present
----------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0x00000 1
PT1 + 2 * L 0x00003 1
PT1 + 3 * L 0
... ...
PT1 + 0xFFFFF * L 0x00005 1
Таблиця сторінок, надана ОС 2 процесу 2:
RAM location physical address present
----------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000B 1
PT2 + 2 * L 0
PT2 + 3 * L 0x00003 1
... ... ...
PT2 + 0xFFFFF * L 0x00004 1
Де:
PT1
і PT2
: початкове положення таблиць 1 і 2 на оперативній пам'яті
Приклади значень: 0x00000000
, 0x12345678
і т.д.
Саме ОС визначає ці значення.
L
: довжина запису таблиці сторінок.
present
: означає, що сторінка присутня в пам'яті.
Таблиці сторінок розташовані в оперативній пам'яті. Наприклад, вони можуть бути розташовані як:
--------------> 0xFFFFFFFF
--------------> PT1 + 0xFFFFF * L
Page Table 1
--------------> PT1
--------------> PT2 + 0xFFFFF * L
Page Table 2
--------------> PT2
--------------> 0x0
Початкові розташування в оперативній пам'яті для обох таблиць сторінок є довільними та контролюються ОС. Від ОС залежить, щоб вони не збігались!
Кожен процес не може безпосередньо торкатися будь-яких таблиць сторінок, хоча він може надсилати запити до ОС, які спричиняють модифікацію таблиць сторінок, наприклад, запит на більші сегменти стека або купи.
Сторінка - це фрагмент розміром 4 КБ (12 бітів), а оскільки адреси мають 32 біти, для ідентифікації кожної сторінки потрібно лише 20 бітів (20 + 12 = 32, отже, 5 символів у шістнадцятковій позначці). Це значення фіксується обладнанням.
Записи таблиці сторінок
Таблиця сторінок - це ... таблиця записів таблиці сторінок!
Точний формат записів у таблиці визначається обладнанням .
У цьому спрощеному прикладі записи таблиці сторінок містять лише два поля:
bits function
----- -----------------------------------------
20 physical address of the start of the page
1 present flag
так що в цьому прикладі дизайнери апаратного забезпечення могли вибрати L = 21
.
Більшість записів таблиці реальних сторінок мають інші поля.
Було б недоцільно вирівнювати речі на 21 біт, оскільки пам’ять адресується байтами, а не бітами. Отже, навіть у цьому випадку потрібні лише 21 біт, дизайнери апаратного забезпечення, мабуть, вирішать L = 32
зробити доступ швидшим і просто зарезервують біти, що залишилися, для подальшого використання. Фактичне значення для L
x86 становить 32 біти.
Переклад адреси в однорівневій схемі
Після того, як ОС налаштувала таблиці сторінок, переклад адрес між лінійною та фізичною адресами здійснюється апаратним забезпеченням .
Коли ОС хоче , щоб активізувати процес 1, встановлює , cr3
щоб PT1
, початок таблиці для одного процесу.
Якщо Процес 1 хоче отримати доступ до лінійної адреси 0x00000001
, апаратна схема підкачки автоматично робить для ОС наступне:
розділити лінійну адресу на дві частини:
| page (20 bits) | offset (12 bits) |
Отже, у цьому випадку ми мали б:
- сторінка = 0x00000
- зміщення = 0x001
загляньте в таблицю сторінок 1, оскільки cr3
вказує на неї.
шукати запис, 0x00000
тому що це частина сторінки.
Апаратне знає, що цей запис знаходиться за адресою оперативної пам'яті PT1 + 0 * L = PT1
.
оскільки він присутній, доступ є дійсним
по таблиці сторінок, розташування номера сторінки 0x00000
знаходиться 0x00001 * 4K = 0x00001000
.
щоб знайти остаточну фізичну адресу, нам просто потрібно додати зміщення:
00001 000
+ 00000 001
-----------
00001 001
тому що 00001
це фізична адреса сторінки, яку шукають у таблиці, і 001
є зміщенням.
Як вказує назва, до зміщення завжди додається просто фізична адреса сторінки.
потім апаратне забезпечення отримує пам’ять у цьому фізичному місці.
Таким же чином для процесу 1 відбудуться такі переклади:
linear physical
--------- ---------
00000 002 00001 002
00000 003 00001 003
00000 FFF 00001 FFF
00001 000 00000 000
00001 001 00000 001
00001 FFF 00000 FFF
00002 000 00002 000
FFFFF 000 00005 000
Наприклад, при зверненні до адреси 00001000
частина сторінки 00001
апаратне забезпечення знає, що запис таблиці сторінок знаходиться за адресою оперативної пам'яті: PT1 + 1 * L
(1
через частину сторінки), і саме там вона її буде шукати.
Коли ОС хоче перейти на процес 2, все, що їй потрібно зробити, це cr3
вказати на сторінку 2. Це все так просто!
Тепер для процесу 2 відбудуться такі переклади:
linear physical
--------- ---------
00000 002 00001 002
00000 003 00001 003
00000 FFF 00001 FFF
00001 000 00000 000
00001 001 00000 001
00001 FFF 00000 FFF
00003 000 00003 000
FFFFF 000 00004 000
Одна і та ж лінійна адреса перекладається на різні фізичні адреси для різних процесів , залежно лише від значення всередині cr3
.
Таким чином кожна програма може очікувати, що її дані почнуться в 0
і закінчаться о FFFFFFFF
, не турбуючись про точні фізичні адреси.
Помилка сторінки
Що робити, якщо Процес 1 намагається отримати доступ до адреси всередині сторінки, якої немає?
Апаратне забезпечення повідомляє програмне забезпечення через виняток помилки сторінки.
Тоді, як правило, ОС повинна зареєструвати обробник винятків, щоб вирішити, що потрібно зробити.
Можливо, доступ до сторінки, якої немає в таблиці, є помилкою програмування:
int is[1];
is[2] = 1;
але можуть бути випадки, коли це прийнятно, наприклад у Linux, коли:
програма хоче збільшити свій стек.
Він просто намагається отримати доступ до певного байта в заданому можливому діапазоні, і якщо ОС задоволена, вона додає цю сторінку до адресного простору процесу.
сторінку було замінено на диск.
ОС повинна буде виконати певну роботу за процесами назад, щоб повернути сторінку в оперативну пам’ять.
ОС може виявити, що це так, виходячи із вмісту решти запису таблиці сторінок, оскільки, якщо даний прапорець чіткий, інші записи запису таблиці сторінок повністю залишаються для ОС до того, що вона хоче.
Наприклад, у Linux, коли присутній = 0:
якщо всі поля запису таблиці сторінок дорівнюють 0, недійсна адреса.
в іншому випадку сторінка була замінена на диск, і фактичні значення цих полів кодують позицію сторінки на диску.
У будь-якому випадку, ОС повинна знати, за якою адресою згенеровано Помилку сторінки, щоб мати змогу вирішити проблему. Ось чому приємні розробники IA32 встановлюють значення cr2
для цієї адреси щоразу, коли відбувається помилка сторінки. Тоді обробник винятків може просто переглянути, cr2
щоб отримати адресу.
Спрощення
Спрощення реальності, які полегшують розуміння цього прикладу:
усі справжні пейджингові схеми використовують багаторівневу пейджингову інформацію для економії місця, але це показало просту однорівневу схему.
таблиці сторінок містили лише два поля: 20-бітову адресу та 1-бітний присутній прапор.
Таблиці реальних сторінок містять загалом 12 полів, а отже, інші функції, які були пропущені.
Приклад: багаторівнева схема підкачки
Проблема однорівневої схеми підкачки полягає в тому, що вона займе занадто багато оперативної пам'яті: 4G / 4K = 1M записів на процес. Якщо кожен запис має 4 байти, це зробить 4 мільйони на процес , що занадто багато навіть для настільного комп’ютера: ps -A | wc -l
говорить, що зараз я запускаю 244 процеси, тож це займе близько 1 ГБ моєї оперативної пам’яті!
З цієї причини розробники x86 вирішили використовувати багаторівневу схему, яка зменшує використання оперативної пам'яті.
Недоліком цієї системи є те, що вона має трохи більший час доступу.
У простій 3-рівневій системі пейджингового виклику, що використовується для 32-розрядних процесорів без PAE, 32 біти адреси поділяються таким чином:
| directory (10 bits) | table (10 bits) | offset (12 bits) |
Кожен процес повинен мати один і лише один пов'язаний з ним каталог сторінок, тому він буде містити щонайменше 2^10 = 1K
записи каталогів сторінок, набагато кращі, ніж мінімум 1 М, необхідний для однорівневої схеми.
Таблиці сторінок розподіляються лише за потребою ОС. У кожній таблиці 2^10 = 1K
сторінок є записи в каталозі сторінок
Каталоги сторінок містять ... записи каталогів сторінок! Записи каталогу сторінок є однаковими із записами таблиць сторінок, за винятком того, що вони вказують на адреси оперативної пам'яті таблиць сторінок замість фізичних адрес таблиць . Оскільки ці адреси мають ширину лише 20 біт, таблиці сторінок повинні бути на початку сторінок розміром 4 КБ.
cr3
тепер вказує на розташування в оперативній пам'яті каталогу сторінок поточного процесу замість таблиць сторінок.
Записи таблиць сторінок взагалі не змінюються за однорівневою схемою.
Таблиці сторінок змінюються від однорівневої схеми, оскільки:
- кожен процес може мати до 1 тис. таблиць сторінок, по одній на запис каталогу сторінки.
- кожна таблиця сторінок містить рівно 1K записів замість 1M записів.
Причиною використання 10 бітів на перших двох рівнях (а не, скажімо, 12 | 8 | 12
) є те, що кожен запис таблиці сторінок має 4 байти. Тоді 2 ^ 10 записів каталогів сторінок та таблиць сторінок добре помістяться на сторінки розміром 4 Кб. Це означає, що для цього швидше та простіше розподіляти та звільняти сторінки.
Переклад адреси в багаторівневій схемі
Каталог сторінок, переданий ОС на процес 1:
RAM location physical address present
--------------- ----------------- --------
PD1 + 0 * L 0x10000 1
PD1 + 1 * L 0
PD1 + 2 * L 0x80000 1
PD1 + 3 * L 0
... ...
PD1 + 0x3FF * L 0
Таблиці сторінок, надані для обробки 1 ОС на PT1 = 0x10000000
( 0x10000
* 4K):
RAM location physical address present
--------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0
PT1 + 2 * L 0x0000D 1
... ...
PT1 + 0x3FF * L 0x00005 1
Таблиці сторінок, надані для обробки 1 ОС на PT2 = 0x80000000
( 0x80000
* 4K):
RAM location physical address present
--------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000C 1
PT2 + 2 * L 0
... ...
PT2 + 0x3FF * L 0x00003 1
де:
PD1
: початкове положення каталогу сторінок процесу 1 в оперативній пам'яті.
PT1
і PT2
: початкове положення таблиці сторінок 1 і таблиці сторінок 2 для процесу 1 в оперативній пам'яті.
Отже, у цьому прикладі каталог сторінок і таблиця сторінок можуть зберігатися в оперативній пам'яті приблизно так:
----------------> 0xFFFFFFFF
----------------> PT2 + 0x3FF * L
Page Table 1
----------------> PT2
----------------> PD1 + 0x3FF * L
Page Directory 1
----------------> PD1
----------------> PT1 + 0x3FF * L
Page Table 2
----------------> PT1
----------------> 0x0
Давайте перекладемо лінійну адресу 0x00801004
поетапно.
Ми вважаємо, що cr3 = PD1
, тобто вказує на щойно описаний каталог сторінок.
У двійковій формі лінійна адреса:
0 0 8 0 1 0 0 4
0000 0000 1000 0000 0001 0000 0000 0100
Групування як 10 | 10 | 12
дає:
0000000010 0000000001 000000000100
0x2 0x1 0x4
що дає:
- запис каталогу каталогу сторінок = 0x2
- запис таблиці сторінок = 0x1
- зміщення = 0x4
Тож апаратне забезпечення шукає запис 2 каталогу сторінки.
Таблиця каталогів сторінок говорить, що таблиця сторінок знаходиться за адресою 0x80000 * 4K = 0x80000000
. Це перший доступ до оперативної пам'яті в процесі.
Оскільки запис таблиці сторінок є 0x1
, апаратне забезпечення переглядає запис 1 таблиці сторінок за адресою 0x80000000
, який повідомляє, що фізична сторінка знаходиться за адресою 0x0000C * 4K = 0x0000C000
. Це другий доступ до оперативної пам'яті в процесі.
Нарешті, апаратне забезпечення підкачки додає зміщення, і кінцевою адресою є 0x0000C004
.
Інші приклади перекладених адрес:
linear 10 10 12 split physical
-------- --------------- ----------
00000001 000 000 001 00001001
00001001 000 001 001 page fault
003FF001 000 3FF 001 00005001
00400000 001 000 000 page fault
00800001 002 000 001 0000A001
00801008 002 001 008 0000C008
00802008 002 002 008 page fault
00B00001 003 000 000 page fault
Помилки сторінки трапляються, якщо немає або каталогу каталогу сторінок, або запису таблиці сторінок.
Якщо ОС хоче запустити інший процес одночасно, вона надасть другому процесу окремий каталог сторінок і зв’яже цей каталог з окремими таблицями сторінок.
64-розрядні архітектури
64 біти все ще занадто багато адреси для поточних розмірів оперативної пам'яті, тому більшість архітектур використовуватимуть менше бітів.
x86_64 використовує 48 біт (256 ТБ), а PAE застарілого режиму вже дозволяє 52-бітові адреси (4 ПіБ).
12 із цих 48 бітів вже зарезервовано для зсуву, що залишає 36 бітів.
Якщо взяти підхід на 2 рівні, найкращим розділенням буде два 18-бітових рівня.
Але це означало б, що каталог сторінок містив би 2^18 = 256K
записи, які забирали б занадто багато оперативної пам'яті: близько до однорівневого підкачки для 32-розрядних архітектур!
Тому 64-розрядні архітектури створюють ще більше рівнів сторінки, зазвичай 3 або 4.
x86_64 використовує 4 рівні в 9 | 9 | 9 | 12
схемі, так що верхній рівень займає лише 2^9
записи вищого рівня.
PAE
Розширення фізичної адреси.
З 32 бітами можна вирішити лише 4 ГБ оперативної пам'яті.
Це стало обмеженням для великих серверів, тому Intel представила механізм PAE для Pentium Pro.
Щоб усунути проблему, Intel додала 4 нові адресні рядки, щоб можна було звернутись до 64 Гб.
Структура таблиці сторінок також змінюється, якщо PAE увімкнено. Точний спосіб його зміни залежить від того, увімкнено чи вимкнено PSE.
PAE вмикається та вимикається через PAE
біт cr4
.
Навіть якщо загальна адресаційна пам’ять становить 64 Гб, окремі процеси все одно можуть використовувати лише до 4 Гб. Однак ОС може розміщувати різні процеси на різних фрагментах по 4 Гб.
PSE
Розширення розміру сторінки.
Дозволяє розмір сторінок 4M (або 2M, якщо ввімкнено PAE) замість 4K.
PSE вмикається і вимикається через PAE
біт cr4
.
Схеми таблиць сторінок PAE та PSE
Якщо активні PAE та PSE, використовуються різні схеми рівня підкачки:
відсутність PAE та PSE: 10 | 10 | 12
немає PAE і PSE: 10 | 22
.
22 - зміщення на сторінці 4 Мб, оскільки 22 біти адресують 4 Мб.
PAE і відсутність PSE: 2 | 9 | 9 | 12
Причиною дизайну, чому 9 використовується двічі замість 10, є те, що тепер записи більше не вміщуються в 32 біти, які всі заповнюються 20 бітами адреси та 12 значущими або зарезервованими бітами прапора.
Причина полягає в тому, що 20 біт вже недостатньо для подання адреси таблиць сторінок: 24 біти тепер потрібні через 4 додаткові дроти, додані до процесора.
Тому дизайнери вирішили збільшити розмір входу до 64 біт, і, щоб вони помістилися в односторінкову таблицю, необхідно зменшити кількість записів до 2 ^ 9 замість 2 ^ 10.
Початковий 2 - це новий рівень сторінки, який називається Таблиця покажчиків каталогів сторінок (PDPT), оскільки він вказує на каталоги сторінок і заповнює 32-бітну лінійну адресу. PDPT також мають ширину 64 біти.
cr3
тепер вказує на PDPT, які повинні мати на перших чотирьох 4 Гб пам'яті і вирівняні на 32-бітові кратні для ефективного вирішення. Це означає, що тепер cr3
має 27 значущих бітів замість 20: 2 ^ 5 для 32 кратних * 2 ^ 27 для заповнення 2 ^ 32 перших 4 Гб.
PAE та PSE: 2 | 9 | 21
Дизайнери вирішили залишити 9-бітне поле, щоб воно вмістилося на одній сторінці.
Це залишає 23 біти. Залишаючи 2 для PDPT, щоб підтримувати рівномірність справи з корпусом PAE без PSE, залишається 21 для компенсації, що означає, що сторінки мають ширину 2M замість 4M.
TLB
Буфер перекладу підсилювача перекладу (TLB) - це кеш для адрес підкачки.
Оскільки це кеш-пам’ять, він поділяє багато питань дизайну кеш-пам'яті процесора, таких як рівень асоціативності.
Цей розділ повинен описувати спрощений повністю асоціативний TLB з 4 окремими адресами. Зауважте, що, як і інші кеші, реальні TLB зазвичай не є повністю асоціативними.
Основна операція
Після того, як відбувається трансляція між лінійною та фізичною адресою, вона зберігається в TLB. Наприклад, TLB із 4 записів починається у такому стані:
valid linear physical
------ ------- ---------
> 0 00000 00000
0 00000 00000
0 00000 00000
0 00000 00000
>
Вказує на поточну запис , яку необхідно замінити.
і після того, як лінійна адреса сторінки 00003
переведена на фізичну адресу 00005
, TLB стає:
valid linear physical
------ ------- ---------
1 00003 00005
> 0 00000 00000
0 00000 00000
0 00000 00000
і після другого перекладу 00007
на 00009
це стає:
valid linear physical
------ ------- ---------
1 00003 00005
1 00007 00009
> 0 00000 00000
0 00000 00000
Тепер, якщо 00003
потрібно перекласти ще раз, апарат спочатку шукає TLB і знаходить його адресу за допомогою одного доступу до оперативної пам'яті 00003 --> 00005
.
Звичайно, 00000
це не в TLB, оскільки жоден дійсний запис не містить 00000
як ключ.
Політика заміни
Коли заповнюється TLB, старі адреси перезаписуються. Як і для кеш-пам'яті процесора, політика заміни є потенційно складною операцією, але простою та обґрунтованою евристикою є видалення найменш нещодавно використовуваного запису (LRU).
З LRU, починаючи зі стану:
valid linear physical
------ ------- ---------
> 1 00003 00005
1 00007 00009
1 00009 00001
1 0000B 00003
додавання 0000D -> 0000A
дасть:
valid linear physical
------ ------- ---------
1 0000D 0000A
> 1 00007 00009
1 00009 00001
1 0000B 00003
КАМ
Використання TLB робить переклад швидшим, оскільки початковий переклад займає один доступ на рівень TLB , що означає 2 на простій 32-бітовій схемі, але 3 або 4 на 64-бітній архітектурі.
TLB, як правило, реалізується як дорогий тип оперативної пам'яті, що називається адресною до вмісту пам'яттю (CAM). CAM реалізує асоціативну карту на апаратному забезпеченні, тобто структуру, яка отримує ключ (лінійну адресу), отримує значення.
Зіставлення також можуть бути реалізовані на адресах оперативної пам'яті, але для зіставлення CAM може знадобитися набагато менше записів, ніж відображення оперативної пам'яті.
Наприклад, карта, на якій:
- і ключі, і значення мають 20 бітів (у випадку простих схем підкачки)
- щонайбільше потрібно зберігати 4 значення
може зберігатися в TLB з 4 записами:
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
FFFFF 00000
Однак, щоб реалізувати це за допомогою оперативної пам'яті, було б потрібно мати 2 ^ 20 адрес :
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
... (from 00011 to FFFFE)
FFFFF 00000
що було б навіть дорожче, ніж використання TLB.
Недійсні записи
При cr3
зміні всі записи TLB втрачають силу, оскільки буде використана нова таблиця сторінок для нового процесу, тому малоймовірно, що будь-який зі старих записів має якесь значення.
X86 також пропонує invlpg
інструкцію, яка явно анулює окремий запис TLB. Інші архітектури пропонують ще більше інструкцій щодо недійсних записів TLB, таких як скасування всіх записів у заданому діапазоні.
Деякі процесори x86 виходять за межі вимог специфікації x86 і забезпечують більшу узгодженість, ніж вона гарантує, між зміною запису таблиці сторінок та її використанням, коли він ще не був кешований у TLB . Очевидно, Windows 9x покладався на це для коректності, але сучасні процесори AMD не забезпечують узгоджених сторінок. Процесори Intel роблять це, хоча для цього їм потрібно виявляти помилкові спекуляції. Скористатися цим - це, мабуть, погана ідея, оскільки, мабуть, багато чого не виграєш, і великий ризик спричинити тонкі проблеми, що залежать від часу, які важко налагодити.
Використання ядра Linux
Ядро Linux широко використовує функції підкачки x86, щоб дозволити швидкі перемикання процесів з невеликою фрагментацією даних.
В v4.2
, загляньте під arch/x86/
:
include/asm/pgtable*
include/asm/page*
mm/pgtable*
mm/page*
Здається, не існує жодних структур, що представляють сторінки, лише макроси: include/asm/page_types.h
це особливо цікаво. Витяг:
#define _PAGE_BIT_PRESENT 0 /* is present */
#define _PAGE_BIT_RW 1 /* writeable */
#define _PAGE_BIT_USER 2 /* userspace addressable */
#define _PAGE_BIT_PWT 3 /* page write through */
arch/x86/include/uapi/asm/processor-flags.h
визначає CR0
, і зокрема PG
бітове положення:
#define X86_CR0_PG_BIT 31 /* Paging */
Бібліографія
Безкоштовно:
rutgers-pxk-416 глава "Управління пам'яттю: конспекти лекцій"
Хороший історичний огляд методів організації пам’яті, що використовувались старшими ОС.
Невільні: