Подтвердить что ты не робот

Как Linux-сервер управляет физической памятью емкостью менее 1 ГБ?

Я изучаю внутренность ядра Linux и, читая "Understanding Linux Kernel", меня поразило немало вопросов, связанных с памятью. Одним из них является то, как ядро ​​Linux обрабатывает отображение памяти, если в моей системе установлена ​​физическая память, скажем, всего 512 МБ.

Как я читал, ядро ​​отображает 0 (или 16) MB-896MB физическое ОЗУ в линейный адрес 0xC0000000 и может напрямую обращаться к нему. Итак, в описанном выше случае, когда у меня есть только 512 МБ:

  • Как ядро ​​может отображать 896 МБ всего 512 МБ? В описанной схеме ядро ​​настраивает все так, чтобы каждая таблица страниц процесса отображала виртуальные адреса от 0xC0000000 до 0xFFFFFFFF (1GB) непосредственно на физические адреса от 0x00000000 до 0x3FFFFFFF (1 ГБ). Но когда у меня есть только 512 МБ физической памяти, как я могу сопоставить, виртуальные адреса от 0xC0000000-0xFFFFFFFF до физического 0x00000000-0x3FFFFFFF? Точка: у меня есть физический диапазон только 0x00000000-0x20000000.

  • Как насчет процессов пользовательского режима в этой ситуации?

  • В каждой статье объясняется только ситуация, когда вы установили 4 ГБ памяти, а ядро ​​отображает 1 ГБ в пространство ядра, а пользовательские процессы используют оставшийся объем оперативной памяти.

Буду признателен за любую помощь в улучшении моего понимания.

Спасибо!..

4b9b3361

Ответ 1

Не все виртуальные (линейные) адреса должны быть сопоставлены ни с чем. Если код обращается к странице без всплытия, ошибка страницы возрастает.

Физическая страница может отображаться одновременно на несколько виртуальных адресов.

В виртуальной памяти 4 ГБ имеется 2 раздела: 0x0... 0xbfffffff - это виртуальная память процесса и 0xc0000000.. 0xffffffff - это виртуальная память ядра.

  • Как ядро ​​может отображать 896 МБ только с 512 МБ?

Он отображает до 896 МБ. Итак, если у вас всего 512, будет отображаться только 512 МБ.

Если ваша физическая память находится в диапазоне от 0x00000000 до 0x20000000, она будет отображаться для прямого доступа к виртуальным адресам 0xC0000000 до 0xE0000000 (линейное сопоставление).

  • Как насчет процессов пользовательского режима в этой ситуации?

Физическая память для пользовательских процессов будет отображаться (а не последовательно, а скорее случайное сопоставление между страницами) к виртуальным адресам 0x0.... 0xc0000000. Это сопоставление будет вторым отображением для страниц от 0..896MB. Страницы будут взяты из бесплатных списков страниц.

  • Где процессы пользовательского режима в физическом ОЗУ?

Anywhere.

  • В каждой статье объясняется только ситуация, когда вы установили 4 ГБ памяти и

Нет. В каждой статье объясняется, как отображается 4 ГБ виртуального адресного пространства. Размер виртуальной памяти всегда 4 ГБ (для 32-разрядной машины без расширений памяти, таких как PAE/PSE/etc для x86)

Как указано в 8.1.3. Memory Zones книги Linux Kernel Development Роберта Лава (я использую третье издание), существует несколько зон физической памяти:

  • ZONE_DMA - содержит кадры страниц с памятью ниже 16 МБ.
  • ZONE_NORMAL - содержит кадры страниц с памятью и выше 16 МБ и ниже 896 МБ.
  • ZONE_HIGHMEM - содержит фреймы страниц с памятью и размером 896 МБ

Итак, если у вас есть 512 МБ, ваш ZONE_HIGHMEM будет пустым, а ZONE_NORMAL будет иметь карту физической памяти 496 МБ.

Также обратите внимание на раздел 2.5.5.2. Final kernel Page Table when RAM size is less than 896 MB книги. Речь идет о случае, когда у вас меньше памяти, чем 896 МБ.

Кроме того, для ARM есть некоторое описание расположения виртуальной памяти: http://www.mjmwired.net/kernel/Documentation/arm/memory.txt

Линия 63 PAGE_OFFSET high_memory-1 - это прямая отображаемая часть памяти

Ответ 2

Аппаратное обеспечение предоставляет Блок управления памятью. Это часть схемы, которая способна перехватывать и изменять любой доступ к памяти. Всякий раз, когда процессор обращается к ОЗУ, например, для чтения следующей команды для выполнения или в качестве доступа к данным, инициированного инструкцией, она делает это на каком-то адресе, который, грубо говоря, имеет 32-битное значение. 32-битное слово может иметь бит более 4 миллиардов различных значений, поэтому есть адресное пространство 4 ГБ: количество байтов, которое может иметь уникальный адрес.

Таким образом, процессор отправляет запрос в свою подсистему памяти, так как "выбирает байта по адресу x и возвращает его мне". Запрос проходит через MMU, который решает, что делать с запросом. MMU фактически разбивает пространство 4 ГБ на страницы; размер страницы зависит от используемого вами оборудования, но типичные размеры - 4 и 8 кБ. MMU использует таблицы, которые сообщают, что делать с обращениями для каждой страницы: либо доступ предоставляется с переписанным адресом (в записи страницы говорится: "да, страница с адресом x существует, она находится в физической памяти по адресу y" ) или отклонено, и в этот момент ядро ​​вызывается для дальнейшего использования. Ядро может решить убить процесс нарушения или выполнить некоторую работу и изменить таблицы MMU, чтобы этот запрос можно было снова попробовать, на этот раз успешно.

Это основа для виртуальной памяти: с точки зрения, процесс имеет некоторую ОЗУ, но ядро ​​переместило его на жесткий диск в "swap space". Соответствующая таблица помечена как "отсутствует" в таблицах MMU. Когда процесс обращается к своим данным, MMU вызывает ядро, которое извлекает данные из swap, возвращает его в какое-то свободное место в физической RAM и изменяет таблицы MMU на то место в этом пространстве. Затем ядро ​​возвращается к процессу, прямо в инструкции, которая запускает все это. Код процесса не видит ничего общего со всем бизнесом, за исключением того, что доступ к памяти занимает довольно много времени.

MMU также обрабатывает права доступа, которые препятствуют процессу считывать или записывать данные, принадлежащие другим процессам, или ядру. Каждый процесс имеет свой собственный набор таблиц MMU, и ядро ​​управляет этими таблицами. Таким образом, каждый процесс имеет собственное адресное пространство, как если бы он был один на машине с 4 ГБ ОЗУ - за исключением того, что у процесса лучше не было доступа к памяти, которую он не распределил по праву из ядра, поскольку соответствующие страницы отмечены как отсутствующие или запрещенные.

Когда ядро ​​вызывается через системный вызов из какого-либо процесса, код ядра должен выполняться в адресном пространстве процесса; поэтому код ядра должен быть где-то в адресном пространстве каждого процесса (но защищен: таблицы MMU предотвращают доступ к памяти ядра из непривилегированного кода пользователя). Поскольку код может содержать жестко закодированные адреса, ядро ​​должно быть на одном и том же адресе для всех процессов; условно, в Linux этот адрес равен 0xC0000000. Таблицы MMU для каждой карты процесса, что часть адресного пространства для любого физического ОЗУ блокирует ядро, фактически загружалась при загрузке. Обратите внимание, что память ядра никогда не заменяется (если код, который может считывать данные из пространства подкачки, сам поменялся, все будет слишком кислым).

На ПК все может быть немного сложнее, потому что есть 32-битный и 64-битный режимы, регистры сегментов и PAE (который выступает как своего рода MMU второго уровня с огромными страницами). Основная концепция остается неизменной: каждый процесс получает свое собственное представление о виртуальном 4 ГБ адресном пространстве, а ядро ​​использует MMU для сопоставления каждой виртуальной страницы с соответствующей физической позицией в ОЗУ или вообще нигде.

Ответ 3

osgx имеет отличный ответ, но я вижу комментарий, где кто-то все еще не понимает.

В каждой статье объясняется только ситуация, когда вы установили 4 ГБ памяти и ядра отображает 1 ГБ в пространство ядра и пользователя процессы используют оставшийся объем оперативной памяти.

Вот большая путаница. Существует виртуальная память и есть физическая память. Каждый 32-битный процессор имеет 4 ГБ виртуальной памяти. Традиционным разделом ядра Linux было 3G/1G для пользовательской памяти и памяти ядра, но более новые опции позволяют разделить разделы.

Зачем различать ядро ​​и пространство пользователя? - мой собственный вопрос

Когда задача свопит, MMU необходимо обновить. Ядро MMU-пространство должно оставаться неизменным для всех процессов. Ядро должно обрабатывать прерывания и запросы сбоев в любое время.

Как работает виртуальное отображение? - мой собственный вопрос.

Существует множество перестановок виртуальной памяти.

  • одно личное сопоставление с физической страницей RAM.
  • дублированное виртуальное сопоставление на одну физическую страницу.
  • отображение, которое генерирует SIGBUS или другую ошибку.
  • отображение, поддерживаемое disk/swap.

Из приведенного выше списка легко понять, почему у вас может быть больше виртуального адресного пространства, чем в физической памяти. Фактически, обработчик ошибок обычно проверяет информацию о памяти процесса, чтобы увидеть, соответствует ли страница отображаемой (я имею в виду выделен для процесса), но не в памяти. В этом случае обработчик сбоев вызовет подсистему ввода/вывода для чтения на странице. Когда страница была прочитана и таблицы MMU обновлены, чтобы указать виртуальный адрес на новый физический адрес, процесс, вызвавший отказ, возобновляется.

Если вы понимаете вышеизложенное, становится ясно, почему вы хотели бы иметь большее виртуальное отображение, чем физическую память. Так поддерживается обмен памяти.

Существуют и другие виды использования. Например, два процесса могут использовать одну и ту же библиотеку кода. Возможно, что они связаны с разными виртуальными адресами в пространстве процессов из-за привязки. В этом случае вы можете сопоставить различные виртуальные адреса на ту же физическую страницу , чтобы сохранить физическую память. Это довольно распространено для новых распределений; все они указывают на физическую "нулевую страницу". Когда вы касаетесь/записываете память, копируется нулевая страница и назначается новая физическая страница (COW или копирование при записи).

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

В основном виртуальный и физический не совпадают! Легко заявляется, но часто запутывается при просмотре кода VMM Linux.

Ответ 4

-

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

Насколько мне известно, диапазон между 0 (или 16) МБ - 896 МБ указан специально, в то время как у вас больше ОЗУ, чем это число, скажем, у вас на вашем борту 1 ГБ физической памяти, что называется "низкой памятью". Если у вас больше физической памяти, чем 896 МБ на вашей плате, тогда остальная часть физической памяти называется highmem.

Говоря о вашем вопросе, на вашей доске имеется 512 Мбайт физической памяти, так что на самом деле нет 896, нет highmem.

Общее ядро ​​RAM может видеть и также может отображать 512 МБ.

'Потому что между физической памятью и виртуальным адресом ядра существует сопоставление 1 к 1, поэтому для ядра имеется виртуальное адресное пространство 512 Мбайт. Я действительно не уверен, правильна ли предыдущая фраза, но это то, что на мой взгляд.

Что я имею в виду, если есть 512 Мбайт, то объем физической RAM, которую может управлять ядро, также составляет 512 мегабайт, далее ядро ​​не может создать такое большое адресное пространство, как за пределами 512 Мбайт.

Обратитесь к пользовательскому пространству, есть одна другая точка, страницы пользовательского приложения могут быть заменены на жесткий диск, но страницы ядра не могут.

Итак, для пользовательского пространства, с помощью таблиц страниц и других связанных модулей, похоже, что все еще есть 4 ГБ адресного пространства. Конечно, это виртуальное адресное пространство, а не физическое пространство оперативной памяти.

Это то, что я понимаю.

Спасибо.