Как один и тот же виртуальный адрес для разных процессов отображается на разные физические адреса - PullRequest
14 голосов
/ 08 августа 2010

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

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

0x023f4a54 in p1's VAS => PA 0x12321321
0x023f4a54 in p2's VAS => PA 0x23af2341 # (random addresses)

Ответы [ 6 ]

22 голосов
/ 08 августа 2010

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

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

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

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

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

6 голосов
/ 08 августа 2010

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

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

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

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

5 голосов
/ 09 августа 2010

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

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

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

2 голосов
/ 09 августа 2010

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

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

1 голос
/ 08 августа 2010

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

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

0 голосов
/ 28 июня 2018

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

Когда конкретный процесс обращается к своей таблице страниц и пытается получить доступ к странице, которая еще не была сопоставлена ​​с фреймом страницы, ОС выделяет другой фрагмент физической памяти для этого конкретного процесса и сопоставляет его с виртуальным адресом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...