Что содержит виртуальная память ядра каждого процесса? - PullRequest
20 голосов
/ 15 марта 2010

Когда, скажем, 3 программы (исполняемые файлы) загружены в память, макет может выглядеть примерно так:

альтернативный текст http://img97.imageshack.us/img97/3460/processesm.jpg

У меня есть следующие вопросы:

  1. Концепция виртуальной памяти ограничена пользовательскими процессами? Мне интересно, где находится ядро ​​операционной системы, драйверы? Как у него с разметкой памяти? Я хочу знать больше о памяти на стороне ядра. Я знаю, что его выбор зависит от операционной системы (Windows / Linux).

  2. Является ли концепция виртуальной памяти на основе процесса? Я имею в виду, правильно ли мне сказать 4 ГБ процесса1 + 4 ГБ процесса2 + 4 ГБ процесса3 = 12 ГБ виртуальной памяти (для всех процессов). Это не звучит правильно. Или из общего пространства 4 ГБ ядро ​​занимает 1 ГБ, а остальные 3 ГБ распределяются между всеми процессами.

  3. Говорят, на 32-битной машине в 4 ГБ адресного пространства. Половина этого (или совсем недавно 1 ГБ) занято ядром. На этой диаграмме видно, что «Виртуальная память ядра» занимает 0xc0000000 - 0xffffffff (= 1 ГБ). Они говорят об этом? Или что-то еще? Просто хочу подтвердить.

  4. Что именно точно содержит Kernel Virtual Memory каждого из этих процессов? Каков его макет?

  5. Когда мы делаем IPC, мы говорим об общей памяти. Я не вижу никакой памяти, разделяемой между этими процессами. Где он живет?

  6. Ресурсы (файлы, реестры в Windows) являются глобальными для всех процессов. Таким образом, таблица дескрипторов ресурсов / файлов должна находиться в некотором глобальном пространстве. В какой области это будет?

  7. Где я могу узнать больше об этой стороне ядра?

Ответы [ 2 ]

23 голосов
/ 15 марта 2010
  1. Когда система использует виртуальную память, ядро ​​также использует виртуальную память. Windows будет использовать верхние 2 ГБ (или 1 ГБ, если вы указали параметр / 3GB в загрузчике Windows) для своего собственного использования. Это включает в себя код ядра, данные (или, по крайней мере, данные, которые выгружаются - это верно, Windows может вывести части адресного пространства ядра на жесткий диск) и таблицы страниц.

  2. Каждый процесс имеет свое собственное адресное пространство ВМ. Когда происходит переключение процесса, таблицы страниц обычно заменяются таблицей страниц другого процесса. Это просто сделать на процессоре x86 - достаточно изменить базовый адрес таблицы страниц в регистре управления CR3. Все адресное пространство 4 ГБ заменяется таблицами, заменяющими совершенно другое адресное пространство 4 ГБ. Сказав это, как правило, будут области адресного пространства, которые являются общими для процессов. Эти области отмечены в таблицах страниц специальными флагами, которые указывают процессору, что эти области не нужно аннулировать в буфере преобразования процессора .

  3. Как я упоминал ранее, код ядра, данные и сами таблицы страниц должны где-то находиться. Эта информация находится в адресном пространстве ядра. Вполне возможно, что некоторые части кода, данных и таблиц ядра сами могут быть выгружены на диск по мере необходимости. Некоторые части считаются более важными, чем другие, и никогда не меняются местами вообще.

  4. См. (3)

  5. Это зависит. Общая память пользовательского режима находится в адресном пространстве пользовательского режима. Части адресного пространства режима ядра вполне могут быть разделены между процессами. Например, было бы весьма распространенным делить код ядра между всеми процессами в системе. Где эта память находится не точно. Я использую здесь произвольные адреса, но общая память, расположенная в 0x100000 в одном процессе, может быть расположена в 0x101000 внутри другого процесса. Две страницы в разных адресных пространствах, по совершенно разным адресам, могут указывать на одну и ту же физическую память.

  6. Я не уверен, что вы имеете в виду здесь. Дескрипторы открытых файлов не являются глобальными для всех процессов. Файловая система, хранящаяся на жестком диске, является глобальной для всех процессов. В Windows дескрипторы файлов управляются ядром, а объекты хранятся в адресном пространстве ядра и управляются диспетчером объектов ядра.

  7. Для систем на базе Windows NT, я бы порекомендовал Windows Internals, 5ed от Mark Russinovich и David Solomon

Ответ на комментарий:

А теперь этот 3ГБ общий для всех ч / б процессы? или каждый процесс имеет 4 ГБ пространство?

Это зависит от ОС. Некоторые ядра (например, микроядро L4 ) используют одну и ту же таблицу страниц для нескольких процессов и разделяют адресные пространства, используя сегментация . В Windows каждый процесс получает свои собственные таблицы страниц. Помните, что даже если каждый процесс может получить свое собственное виртуальное адресное пространство, это не означает, что физическая память всегда различна. Например, образ для kernel32.dll, загруженный в процесс A, используется совместно с kernel32.dll в процессе B. Большая часть адресного пространства ядра также используется несколькими процессами.

Почему у каждого процесса есть ядро виртуальная память?

Лучший способ подумать об этом - спросить себя: «Как будет работать ядро, если оно не выполняется с использованием виртуальной памяти?» В этой гипотетической ситуации каждый раз, когда ваша программа вызывала переключение контекста в ядро ​​(скажем, вы сделали системный вызов), виртуальная память должна была быть отключена, пока процессор выполнялся в пространстве ядра. Это требует затрат, и есть необходимость включить его снова, когда вы вернетесь в пространство пользователя.

Кроме того, давайте предположим, что пользовательская программа передала указатель на некоторые данные для своего системного вызова. Этот указатель является виртуальным адресом. У вас отключена виртуальная память, поэтому указатель должен быть переведен на физический адрес, прежде чем ядро ​​сможет что-либо с ним сделать. Если бы у вас была включена виртуальная память, вы бы получили это бесплатно благодаря блоку управления памятью на процессоре. Вместо этого вам придется вручную переводить адреса в программном обеспечении. Я могу описать все виды примеров и сценариев (некоторые из них связаны с аппаратным обеспечением, другие - с обслуживанием таблиц страниц и т. Д.), Но суть в том, что гораздо проще иметь однородную схему управления памятью. Если пользовательское пространство использует виртуальную память, будет проще написать ядро, если вы будете поддерживать эту схему в пространстве ядра. По крайней мере, это был мой опыт.

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

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

3 голосов
/ 27 февраля 2018

Чтобы ответить на ваш вопрос, вам нужно больше узнать о ядре и методах, которые оно использует для управления ресурсами (ЦП, памятью, ...) и обеспечить элегантную абстракцию программам приложения.

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

В информатике слово « память » имеет два значения. Первый - это то, что вы можете использовать для хранения данных (регистры, кэш, RAM, ROM, HDD и т. Д.). Второй - для синонима первичной памяти (то есть RAM ). Когда вы заменяете слово на слово, «Виртуальный Память » - это не что иное, как «Виртуальный ОЗУ ». Это общий объем доступного пространства в системе, в течение которого программы загружаются для выполнения. Так что это не что иное, как физическая память RAM + память подкачки на вторичной памяти, выделенной ядром. Таким образом, если у вас есть 2 ГБ ОЗУ и 4 ГБ пространства подкачки, выделенного ядром во время установки, то Виртуальная память вашей системы составляет 6 ГБ. Я не собираюсь объяснять больше о памяти подкачки здесь, поскольку это больше отошло бы от темы.

Переход к виртуальному адресному пространству. Поэтому, чтобы понять это, вам нужно немного настроить свой разум. Как говорит само название «Виртуал», адресного пространства на самом деле нет! Это всего лишь иллюзия, созданная ядром для программистов приложений (для достижения многих преимуществ, как я упоминал в параграфе 2) Таким образом, каждому процессу ядру предоставляется отдельное виртуальное адресное пространство. (Если бы в системе не было Ядра, и если бы вы запустили свою прикладную программу на оборудовании, тогда она использовала бы физическое адресное пространство, то есть RAM, в качестве своего адресного пространства) Таким образом, на машине с 32-разрядными адресными регистрами ядро ​​может предоставить виртуальное адресное пространство 2 ^ 32 = 4 ГБ для каждого процесса. (Таким образом, этот диапазон виртуального адресного пространства изменяется с архитектурой HW. Последние процессоры имеют 48-битные регистры адресов, поэтому они могут обеспечить виртуальное адресное пространство 2 ^ 48 = 256 ТБ) И, что важно, это виртуальное адресное пространство просто в воздухе !! Вы бы сейчас подумали, если оно просто в воздухе, как вообще можно выполнить код, данные процесса. Да, это должно быть сопоставлено с физической памятью. То, как оно сопоставляется с физической памятью, управляется ядром с помощью концепции, называемой подкачкой. Итак, теперь вы можете увидеть, как ядро ​​достигло изоляции процесса с помощью виртуального адресного пространства. Таким образом, адрес, который может генерировать каждый процесс, составляет от 0 до 4 ГБ (при условии, что для простоты система имеет 32-разрядный адресный регистр), то есть в пределах своей полноты. И он ничего не знает ни о каком другом процессе, запущенном в системе. Так что каждый процесс упакован в отдельном пространстве.

Так что код ядра также похож на другой процесс / сущность. Так что, если бы ядро ​​находилось в совершенно другом адресном пространстве. Тогда не было средств для взаимодействия прикладных программ с ядром. Если приложение не может обмениваться данными с ядром, а ядро ​​не может обмениваться данными с приложением, тогда ядро ​​не может управлять системой. Итак, вопрос теперь - Как заставить процессы приложения взаимодействовать с ядром? Возможен вариант: если код ядра присутствует в виртуальном адресном пространстве процесса приложения, они могут взаимодействовать друг с другом. Вот почему код ядра присутствует в каждом виртуальном адресном пространстве процесса, потому что каждый процесс должен взаимодействовать с ядром. Не волнуйтесь, код ядра физически не дублируется для каждого процесса. Как я упоминал ранее, VAS - это всего лишь иллюзия, поэтому в физической памяти будет только одна копия кода ядра, и на него будут ссылаться все виртуальные адресные пространства (через пейджинг). В случае Linux ядро ​​будет помещено в верхнее адресное пространство между C000 0000 и FFFF FFFF (то есть причина, по которой 1 ГБ зарезервировано для ядра в VAS), а остальные 3 ГБ (от 0000 0000 до BFFF FFFF) разрешены прикладной программе для использовать. Виртуальное адресное пространство, в котором находится ядро, называется пространством ядра, а место, в котором находится прикладная программа, называется пространством пользователя. Если бы вы внимательно наблюдали, то у вас возник бы вопрос: если код приложения и код ядра находятся в одном и том же виртуальном адресном пространстве, и поскольку ядро ​​находится в хорошо предопределенном адресном расположении, то это невозможно для кода приложения, чтобы повредить код ядра! Ой, поначалу это кажется возможным, но это невозможно. Причина - это защищено с помощью HW. На процессоре будет установлен флажок, который указывает, является ли режим выполнения режимом SUPERVISOR или режимом пользователя. Код пространства ядра должен выполняться в режиме SUPERVISOR (установка соответствующего флага), а код пространства пользователя должен выполняться в режиме пользователя. Так что, если вы находитесь в режиме USER и пытаетесь получить доступ / изменить код в пространстве ядра, возникает исключение! (процессор узнает его по адресу, к которому пытается обратиться инструкция. Если он выше C000 0000, он может легко обнаружить, что пытается получить доступ к коду пространства ядра, и текущий режим выполнения не имеет соответствующих разрешений, поскольку флаг устанавливается с разрешения USER MODE). Просто примечание: в режиме SUPERVISOR процессор обеспечивает доступ к дополнительному набору команд.

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

...