@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снова.
Спасибо Жилю за ответ. Но я все еще не могу понять всю концепцию. Не могли бы вы быть немного проще, не сокращая информацию в нем?
Сен
17
Это относится к ядру Linux; Я не уверен, как любое ядро Unix справляется с этим.
Большая память - это сегмент памяти, к которому могут обращаться программы пользовательского пространства. Это не может коснуться Низкой Памяти.
Недостаток памяти - это сегмент памяти, к которому ядро Linux может обращаться напрямую. Если ядро должно получить доступ к High Memory, оно должно сначала отобразить его в своем собственном адресном пространстве.
Недавно был выпущен патч, который позволяет вам контролировать, где находится сегмент. Компромисс заключается в том, что вы можете забрать адресуемую память из пространства пользователя, чтобы у ядра было больше памяти, которую ему не нужно отображать перед использованием.
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 низкий объем памяти предназначен только для ядра, а высокий - для пользовательских процессов.
Согласно «Книге динозавров (концепции операционной системы)», мы можем разместить операционную систему либо в малой, либо в большой памяти. Основным фактором, влияющим на это решение, является местоположение вектора прерывания. Поскольку вектор прерывания часто находится в нехватке памяти, программисты обычно также помещают операционную систему в нехватку памяти.
Ответы:
В 32-разрядной архитектуре диапазон адресного пространства для адресации ОЗУ составляет:
или
4'294'967'295
(4 ГБ).Ядро linux делит это на 3/1 (также может быть 2/2 или 1/3 1 ) на пространство пользователя (высокая память) и пространство ядра (низкая память) соответственно.
Диапазон пространства пользователя:
Каждый недавно созданный пользовательский процесс получает адрес (диапазон) внутри этой области. Пользовательские процессы обычно не заслуживают доверия и поэтому им запрещен доступ к пространству ядра. Кроме того, они считаются несрочными, поскольку, как правило, ядро пытается отложить выделение памяти этим процессам.
Диапазон пространства ядра:
Процессы ядра получают свой адрес (диапазон) здесь. Ядро может напрямую обращаться к этим 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 может обращаться напрямую. Если ядро должно получить доступ к High Memory, оно должно сначала отобразить его в своем собственном адресном пространстве.
Недавно был выпущен патч, который позволяет вам контролировать, где находится сегмент. Компромисс заключается в том, что вы можете забрать адресуемую память из пространства пользователя, чтобы у ядра было больше памяти, которую ему не нужно отображать перед использованием.
Дополнительные ресурсы:
источник
HIGHMEM - это область памяти ядра, но это НЕ память, к которой вы обращаетесь, а место, куда вы помещаете то, что хотите получить.
Типичная 32-битная карта виртуальной памяти Linux выглядит так:
0x00000000-0xbfffffff: пользовательский процесс (3 ГБ)
0xc0000000-0xffffffff: пространство ядра (1 ГБ)
(Вектор, специфичный для процессора, и все остальное здесь игнорируется).
Linux разделяет пространство ядра в 1 ГБ на 2 части, LOWMEM и HIGHMEM. Разделение варьируется от установки к установке.
Если установка выбирает, скажем, 512 МБ-512 МБ для НИЗКОГО и ВЫСОКОГО мемов, то 512 МБ LOWMEM (0xc0000000-0xdfffffff) статически отображается во время загрузки ядра; обычно для этого используются первые так много байтов физической памяти, чтобы виртуальные и физические адреса в этом диапазоне имели постоянное смещение, скажем, 0xc0000000.
С другой стороны, последние 512 МБ (HIGHMEM) не имеют статического сопоставления (хотя вы можете оставить там полупостоянное сопоставление страниц, но вы должны сделать это явно в своем коде драйвера). Вместо этого страницы временно отображаются и не отображаются здесь, так что виртуальные и физические адреса в этом диапазоне не имеют согласованного отображения. Типичное использование HIGHMEM включает одноразовые буферы данных.
источник
Насколько я помню, "High Memory" используется для пространства приложения, а "Low Memory" для ядра.
Преимущество состоит в том, что приложения (пользовательского пространства) не могут получить доступ к памяти пространства ядра.
источник
Многие люди говорят, что недостаточно памяти для операционной системы. Обычно это так, но не обязательно. Большой объем памяти и низкий объем памяти - это только две части пространства памяти, но в системе Linux низкий объем памяти предназначен только для ядра, а высокий - для пользовательских процессов.
Согласно «Книге динозавров (концепции операционной системы)», мы можем разместить операционную систему либо в малой, либо в большой памяти. Основным фактором, влияющим на это решение, является местоположение вектора прерывания. Поскольку вектор прерывания часто находится в нехватке памяти, программисты обычно также помещают операционную систему в нехватку памяти.
источник