Мене цікавить різниця між Highmem і Lowmem:
- Чому існує така диференціація?
- Що ми отримуємо, роблячи це?
- Які особливості має кожен?
Мене цікавить різниця між Highmem і Lowmem:
Відповіді:
У 32-розрядної архітектурі діапазон адресного простору для адреси RAM становить:
0x00000000 - 0xffffffff
або 4'294'967'295
(4 ГБ).
Ядро Linux розбиває на 3/1 (може також 2/2 або 1/3 1 ) на простір користувачів (висока пам'ять) та простір ядра (низька пам'ять) відповідно.
Діапазон простору користувача:
0x00000000 - 0xbfffffff
Кожен щойно створений користувальницький процес отримує адресу (діапазон) всередині цієї області. Користувацькі процеси, як правило, не довіряють, а тому заборонено отримувати доступ до простору ядра. Далі, вони вважаються невідкладними, як правило, ядро намагається відкласти розподіл пам'яті на ці процеси.
Діапазон простору ядра:
0xc0000000 - 0xffffffff
Ядро обробляє тут свою адресу (діапазон). Ядро може безпосередньо отримувати доступ до цих 1 ГБ адрес (ну, не повних 1 Гб, є 128 Мб, зарезервоване для доступу до високої пам'яті).
Процеси, породжені в просторі ядра, є надійними, терміновими та передбачають відсутність помилок, запит на пам'ять обробляється миттєво.
Кожен процес ядра також може отримати доступ до діапазону простору користувача, якщо цього бажає. І щоб досягти цього, ядро відображає адресу з простору користувача (висока пам'ять) до свого простору ядра (низька пам'ять), згадані вище 128 Мб спеціально зарезервовані для цього.
1 Чи розділення дорівнює 3/1, 2/2 або 1/3, керується CONFIG_VMSPLIT_...
опцією; ви, ймовірно, можете перевірити, /boot/config*
щоб побачити, який варіант був обраний для вашого ядра.
Перша посилання, на яку слід звернутися, - це драйвери пристроїв Linux (доступні як в Інтернеті, так і в книжковій формі), особливо глава 15, в якій є розділ на цю тему.
В ідеальному світі кожен системний компонент міг би зіставити всю пам'ять, до якої він коли-небудь потребує доступу. Це стосується процесів в Linux та більшості операційних систем: 32-бітний процес може отримати доступ лише трохи менше 2 ^ 32 байтів віртуальної пам’яті (насправді близько 3 ГБ у типовій 32-розрядної архітектурі Linux). Ядро стає важким, якому потрібно мати можливість відобразити повну пам'ять процесу, системний виклик якого він виконує, плюс всю фізичну пам'ять, а також будь-який інший апарат, нанесений на карту пам'яті.
Отже, коли 32-бітовому ядру потрібно зіставити більше 4 ГБ пам’яті, воно повинно бути складено з високою підтримкою пам’яті. Висока пам'ять - це пам'ять, яка не відображається постійно в адресному просторі ядра. (Низька пам'ять - це навпаки: вона завжди відображається на карті, тому ви можете отримати доступ до неї в ядрі, просто відстеживши покажчик.)
Коли ви отримуєте доступ до високої пам’яті з коду ядра, вам потрібно зателефонувати kmap
спочатку, щоб отримати вказівник зі структури даних сторінки ( struct page
). Виклик kmap
працює, незалежно від того, стоїть вона у великій або низькій пам'яті. Також є kmap_atomic
додаткові обмеження, але він є більш ефективним для багатопроцесорних машин, оскільки він використовує більш дрібнозернисту блокування. Отриманий вказівник kmap
- це ресурс: він використовує адресний простір. Після завершення роботи ви повинні зателефонувати kunmap
(або kunmap_atomic
), щоб звільнити цей ресурс; тоді вказівник більше не дійсний, і до вмісту сторінки не можна отримати доступ, поки ви kmap
знову не зателефонуєте .
Це стосується ядра Linux; Я не впевнений, як будь-яке ядро Unix обробляє це.
Висока пам'ять - це сегмент пам'яті, до якого можуть бути адресовані користувацькі простори. Він не може торкнутися низької пам'яті.
Низька пам'ять - це сегмент пам'яті, до якого ядро Linux може безпосередньо звертатися. Якщо ядро повинно отримати доступ до високої пам'яті, воно має спершу відобразити його у власному адресному просторі.
Нещодавно було введено виправлення, яке дозволяє контролювати, де знаходиться сегмент. Компроміс полягає в тому, що ви можете забирати адресну пам'ять далеко від користувальницького простору, щоб ядро могло мати більше пам’яті, яку йому не потрібно проводити картування перед використанням.
Додаткові ресурси:
HIGHMEM - це діапазон пам’яті ядра, але це НЕ пам'ять, до якої ви отримуєте доступ, але це місце, де ви ставите те, до чого хочете отримати доступ.
Типова карта 32-бітної віртуальної пам'яті Linux виглядає так:
0x00000000-0xbfffffff: користувацький процес (3 Гб)
0xc0000000-0xffffffff: простір ядра (1 Гб)
(Вектор, що стосується процесора, і все, що тут ігнорується).
Linux розділяє простір ядра 1 ГБ на 2 частини, LOWMEM та HIGHMEM. Розділення змінюються від установки до установки.
Якщо установка вибирає, скажімо, 512 МБ-512 МБ для пам'яті НИЗКОГО та ВИСОКОГО, 512 МБ LOWMEM (0xc0000000-0xdfffffff) статично відображається на час завантаження ядра; зазвичай для цього використовується перше стільки байтів фізичної пам'яті, щоб віртуальні та фізичні адреси в цьому діапазоні мали постійне зміщення, скажімо, 0xc0000000.
З іншого боку, останній 512 Мб (HIGHMEM) не має статичного відображення (хоча ви можете залишити сторінки напівзміненими, відображеними там, але це потрібно зробити явно у вашому коді драйвера). Натомість сторінки тут тимчасово відображаються та не мапуються, щоб віртуальні та фізичні адреси в цьому діапазоні не мали послідовного відображення. Типове використання HIGHMEM включає одноразові буфери даних.
Багато людей сказали, що низька пам'ять призначена для операційної системи. Зазвичай це правда, але цього не повинно бути. Висока пам'ять і низька пам'ять - це лише дві частини простору пам’яті, але в системі Linux низька пам’ять призначена лише для ядра, а велика пам’ять - для процесів користувача.
Відповідно до "Книги динозаврів (концепції операційної системи)", ми можемо розмістити операційну систему як в низькій пам'яті, так і у високій пам'яті. Основним фактором, що впливає на це рішення, є розташування вектора переривання. Оскільки вектор переривання часто знаходиться в недостатній кількості пам'яті, програмісти зазвичай також розміщують операційну систему в низькій пам'яті.