Как ядро ​​Linux управляет менее 1 ГБ физической памяти? - PullRequest
48 голосов
/ 25 декабря 2010

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

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

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

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

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

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

спасибо ..! * * 1023

Ответы [ 5 ]

44 голосов
/ 25 декабря 2010

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

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

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

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

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

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

  • А как обстоят дела с процессами пользовательского режима в этой ситуации?

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

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

Anywhere.

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

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

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

  • 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 являетсячасть памяти с прямым отображением

17 голосов
/ 05 января 2011

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

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

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

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

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

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

4 голосов
/ 10 сентября 2014

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

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

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

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

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

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

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

  • одно частное сопоставление с физической страницей ОЗУ.
  • дублирующаяся виртуальная памятьсопоставление с одной физической страницей.
  • сопоставление, которое выдает SIGBUS или другую ошибку.
  • сопоставление, поддерживаемое диском / подкачкой.

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

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

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

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

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

3 голосов
/ 30 июля 2012

-

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

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

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

Общее количество ОЗУ, которое может видеть, а также может отображать, составляет 512 МБ.

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

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

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

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

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

Спасибо.

0 голосов
/ 09 марта 2014

Если физическая память меньше 896 МБ, ядро ​​linux сопоставляется с этим физическим адресом линейно.

Подробнее см. http://learnlinuxconcepts.blogspot.in/2014/02/linux-addressing.html

...