Как тот же виртуальный адрес для различных процессов отображен на различных физических адресах

Я взял курс о дизайне Операционной системы и понятии, и теперь я пытаюсь изучить ядро Linux полностью. У меня есть вопрос, от которого я не могу избавиться. В современных операционных системах каждый процесс имеет собственное виртуальное адресное пространство (VAS) (например, 0 к 2^32-1 в 32-разрядных системах). Это обеспечивает много преимуществ. Но в реализации я смущен в некоторых точках. Позвольте мне объяснить это путем предоставления примера:

Скажем, у нас есть два процесса p1, p2; p1 и p2 имеют их собственные ВАЗЫ. Адрес 0x023f4a54 отображается на различных физических адресах (PA), как это может быть? Как сделан этот перевод этим способом. Я подразумеваю, что знаю механизм перевода, но я не могу понять, что тот же самый адрес отображается на другом физическом адресе, когда он прибывает адресное пространство различных процессов.

0x023f4a54 in p1's VAS => PA 0x12321321
0x023f4a54 in p2's VAS => PA 0x23af2341 # (random addresses)
14
задан NullUserException 8 August 2010 в 19:02
поделиться

5 ответов

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

http://tldp.org/LDP/tlk/mm/memory.html

2
ответ дан 1 December 2019 в 07:18
поделиться

ЦП, который предоставляет виртуальную память, позволяет вам настроить отображение адресов памяти, как ЦП видит, в адреса физической памяти, обычно это выполняется аппаратным модулем, называемым MMU.

Ядро ОС может программировать этот MMU, обычно не до отдельных адресов, а скорее в единицах страниц (обычно 4096 байт). Это означает, что MMU можно запрограммировать на перевод, например, виртуальные адреса 0x1000-0x2000 для преобразования в физический адрес 0x20000-0x21000.

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

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

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

23
ответ дан 1 December 2019 в 07:18
поделиться

Есть две важные структуры данных, связанные с разбиением на страницы: таблица страниц и TLB. ОС поддерживает разные таблицы страниц для каждого процесса. TLB - это просто кеш таблицы страниц.

Теперь разные процессоры, ну, разные. x86 обращается к таблицам страниц напрямую, используя специальный регистр CR3, который указывает на используемую таблицу страниц. Процессоры MIPS ничего не знают о таблице страниц, поэтому ОС должна работать напрямую с TLB.

Некоторые процессоры (например, MIPS) хранят идентификатор в TLB для разделения различных процессов, поэтому ОС может просто изменить регистр управления при переключении контекста (если только ей не нужно повторно использовать идентификатор). Другим ЦП требуется полная очистка TLB при каждом переключении контекста. Итак, в основном, ОС необходимо изменить некоторые регистры управления и, возможно, необходимо очистить TLB (выполнить сброс TLB), чтобы виртуальные адреса из разных процессов отображались на любые физические адреса, которые они должны.

5
ответ дан 1 December 2019 в 07:18
поделиться

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

Рабочим примером является функция библиотеки времени выполнения C sprintf () . При правильном объявлении и вызове он включается в программу как общий объектный модуль вместе со всеми необходимыми подфункциями. Адрес sprintf варьируется от программы к программе, потому что библиотека загружается по доступному свободному адресу. Для простой программы hello world sprintf может быть загружен по адресу 0x101000. Для сложной программы, которая рассчитывает налоги, она может быть загружена по адресу 0x763f8000 (из-за всей нелепой логики, содержащейся в основной программе, она предшествует библиотекам, на которые она ссылается). С точки зрения системы, разделяемая библиотека загружается в память только в одном месте, но адресное окно (диапазон адресов), которое видит каждый процесс, является уникальной памятью для этого исполняемого файла.

Конечно, это еще больше усложняется некоторыми функциями Security Enhanced Linux (SELinux) , который рандомизирует адреса, по которым различные разделы программы загружаются в память, включая отображение разделяемых библиотек.

--- пояснение --- Как кто-то правильно указывает, отображение виртуальных адресов каждого процесса индивидуально для каждого процесса, мало чем отличается от его набора дескрипторов файлов, соединений сокетов, родительского и дочернего процесса и т. Д.То есть p1 может сопоставить адрес 0x1000 с физическим 0x710000, в то время как p2 сопоставляет адрес 0x1000 с ошибкой страницы, а p3 сопоставлен с некоторой общей библиотекой по физическому адресу 0x9f32a000. Сопоставление виртуальных адресов тщательно контролируется операционной системой, возможно, для обеспечения таких функций, как подкачка и разбиение по страницам, но также для предоставления таких функций, как общий код и данные, а также данные, совместно используемые процессами.

6
ответ дан 1 December 2019 в 07:18
поделиться

Это отображение (виртуальный адрес в физический адрес) обрабатывается ОС и MMU (см. Ответ @nos); суть этой абстракции такова, что p1 «думает», что обращается к 0x023f4a54 , тогда как на самом деле он обращается к 0x12321321 .

Если вы вернетесь к своему классу, чтобы узнать, как программы работают на уровне машинного кода, p1 будет ожидать, что некоторая переменная / функция / что угодно будет находиться в одном и том же месте (например, 0x023f4a54 ) каждый раз при загрузке. Эту абстракцию обеспечивает отображение операционной системы физического на виртуальный адрес. На самом деле, он не всегда будет загружаться на один и тот же физический адрес, но вашей программе все равно, если он находится на одном и том же виртуальном адресе.

1
ответ дан 1 December 2019 в 07:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: