it-swarm-ru.tech

Что такое высокая и низкая память в Linux?

Меня интересует разница между Highmem и Lowmem:

  1. Почему существует такая дифференциация?
  2. Что мы получаем от этого?
  3. Какие функции есть у каждого?
94
Sen

В 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* чтобы увидеть, какая опция была выбрана для вашего ядра.

70
wag

Первое упоминание: Драйверы устройств Linux (доступно как онлайн, так и в виде книги), в частности глава 15 , в котором есть раздел на эту тему.

В идеальном мире каждый системный компонент сможет отобразить всю память, к которой ему когда-либо понадобится доступ. И это относится к процессам в Linux и большинстве операционных систем: 32-разрядный процесс может получить доступ только к чуть менее 2 ^ 32 байтов виртуальной памяти (фактически около 3 ГБ в типичной 32-разрядной архитектуре Linux). Это становится трудным для ядра, которое должно иметь возможность отображать полную память процесса, системный вызов которого он выполняет, плюс всю физическую память плюс любое другое отображаемое в памяти аппаратное устройство.

Поэтому, когда 32-разрядному ядру необходимо отобразить более 4 ГБ памяти, оно должно быть скомпилировано с поддержкой высокой памяти. Высокая память - это память, которая не отображается постоянно в адресном пространстве ядра. (Недостаточно памяти наоборот: она всегда отображается, поэтому вы можете получить к ней доступ в ядре, просто разыменовав указатель.)

Когда вы обращаетесь к большой памяти из кода ядра, вам сначала нужно вызвать kmap, чтобы получить указатель из структуры данных страницы (struct page). Вызов kmap работает независимо от того, находится ли страница в большом или низком объеме памяти. Есть также kmap_atomic, который добавил ограничения, но более эффективен на многопроцессорных машинах, потому что он использует более тонкую блокировку. Указатель, полученный через kmap, является ресурсом: он использует адресное пространство. Как только вы закончили с этим, вы должны вызвать kunmap (или kunmap_atomic) освободить этот ресурс; тогда указатель больше не действителен, и содержимое страницы не может быть доступно, пока вы не вызовете kmap снова.

28
Gilles 'SO- stop being evil'

Это относится к ядру Linux; Я не уверен, как любое ядро ​​Unix справляется с этим.

Большая память - это сегмент памяти, к которому могут обращаться программы пользовательского пространства. Это не может коснуться малой памяти.

Недостаток памяти - это сегмент памяти, к которому ядро ​​Linux может обращаться напрямую. Если ядро ​​должно получить доступ к High Memory, оно должно сначала отобразить его в своем собственном адресном пространстве.

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

Дополнительные ресурсы:

17
Shawn J. Goff

HIGHMEM - это область памяти ядра, но это НЕ память, к которой вы обращаетесь, а место, куда вы помещаете то, что хотите получить.

Типичная 32-битная карта виртуальной памяти Linux выглядит так:

  • 0x00000000-0xbfffffff: пользовательский процесс (3 ГБ)

  • 0xc0000000-0xffffffff: пространство ядра (1 ГБ)

(Вектор, специфичный для процессора, и все остальное здесь игнорируется).

Linux разделяет пространство ядра в 1 ГБ на 2 части, LOWMEM и HIGHMEM. Разделение варьируется от установки к установке.

Если установка выбирает, скажем, 512 МБ-512 МБ для НИЗКОГО и ВЫСОКОГО мемов, то 512 МБ LOWMEM (0xc0000000-0xdfffffff) статически отображается во время загрузки ядра; обычно для этого используются первые столько байтов физической памяти, чтобы виртуальные и физические адреса в этом диапазоне имели постоянное смещение, скажем, 0xc0000000.

С другой стороны, последние 512 МБ (HIGHMEM) не имеют статического сопоставления (хотя вы можете оставить там полупостоянное отображение страниц, но вы должны сделать это явно в коде вашего драйвера). Вместо этого страницы временно отображаются и не отображаются здесь, так что виртуальные и физические адреса в этом диапазоне не имеют согласованного отображения. Типичное использование HIGHMEM включает одноразовые буферы данных.

4
hiro

Насколько я помню, "High Memory" используется для пространства приложения, а "Low Memory" для ядра.

Преимущество заключается в том, что приложения (пользовательского пространства) не могут получить доступ к памяти пространства ядра.

3
Gert

Многие люди говорят, что нехватка памяти для операционной системы. Обычно это так, но не обязательно. Большой объем памяти и низкий объем памяти - это только две части пространства памяти, но в системе Linux низкий объем памяти предназначен только для ядра, а высокий - для пользовательских процессов.

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

0
Zheng Gao