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


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

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

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

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

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

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

Спасибо..!

5 46

5 ответов:

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

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

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

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

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

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

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

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

  • где находятся процессы пользовательского режима в оперативной памяти phys?

Где угодно.

  • каждая статья объясняет только ситуацию, когда вы установили 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 является прямой отображенной частью памяти

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-

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

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

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

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

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

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

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

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

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

Спасибо.

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

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