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


92

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

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

@hiro, вы имеете в виду "HIGHMEM" - это "виртуальный адрес ядра", как описано в ldd3. Я согласен. Это сбивает с толку, ldd3 определяет "LOWMEM", "HIGHMEM", также определяет "виртуальный адрес ядра", "логический адрес ядра". они одно и то же, но имеют другое имя. это «красота» программного обеспечения, оно зависит от языка описания.
Стив

Ответы:


69

В 32-разрядной архитектуре диапазон адресного пространства для адресации ОЗУ составляет:

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


Это старо, и я не уверен, что ты здесь. Но я хочу спросить одну вещь: зарезервированные 128 МБ в пространстве ядра (для высокого доступа к памяти), это все ссылки области памяти пользовательского пространства? Итак, процесс ядра может получить доступ к любому пользовательскому пространству, обратившись к этой области, верно?
Амуму

1
Почему это всегда в 1/4? Т.е. почему он не может разделить это на 5/1 или что-то?
mgalgs

Что именно означает «прямой доступ» здесь? Я имею в виду, не доступ к самому ядру через механизм виртуальной памяти?
Telenn

1
Я полагаю, что то, что вы говорите о высокой / низкой памяти, неверно: я считаю, что в чисто 32-битной системе ядро ​​может напрямую получить доступ ко всем 3 ГБ пользовательского пространства (ядро может получить доступ к пространству ядра и пользовательскому пространству). Однако, когда у вас есть ядро ​​PAE, все становится более сложным, теперь у вас более 3 ГБ ОЗУ, каждый процесс может быть 3 ГБ, и вы не можете получить доступ ко всему пользовательскому пространству напрямую. Это то место, где приходит высокая память и 128 МБ памяти в пространстве ядра. С 64-битным ядром это снова становится проще, без старших, поскольку все пользовательское пространство доступно из ядра.
ctrl-alt-delor

2
@mgalgs ¼, 2/4 и ¾ были просто набором вариантов по умолчанию, которые были выставлены. С 2007 года можно также выбрать 5/16 и 15/32. Если вы знаете, для редактирования какой строки #define, вы можете выбрать почти произвольное разделение.
Йоргенсен

28

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

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

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

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


2
Спасибо Жилю за ответ. Но я все еще не могу понять всю концепцию. Не могли бы вы быть немного проще, не сокращая информацию в нем?
Сен

17

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

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

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

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

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


4

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

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

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

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

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

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

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

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


3

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

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


0

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.