2010-08-08 2 views
13

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

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

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

https://en.wikipedia.org/wiki/Virtual_memory –

ответ

3

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

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

6

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

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

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

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

+0

Моя проблема не о совместном использовании. Проблема заключается в том, что, когда p1 пытается достичь VA 0x04, этот VA переносится на физический адрес, тогда произошел переход контекста, а другой процесс p2 пытается достичь того же VA 0x04, что этот VA переведен на другой физический адрес, но он не может быть таким же с p1. Как может быть это различие, обеспечиваемое ОС. Они могут достигать одинаковых VA, но эти VA не сопоставляются с одним и тем же физическим адресом. Мне интересно, какой механизм выходит за рамки этой проблемы перевода. Как OS препятствует тому, чтобы этот процесс столкнулся с другим? – dirtybit

+2

@Pushdown Как уже упоминалось, ОС хранит отдельное сопоставление для каждого процесса, и оно меняет местами и выводит эти сопоставления при переключении между процессами. – nos

22

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

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

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

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

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

+2

Btw, спасибо за книгу гормана. Это действительно хорошо. – dirtybit

1

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

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

+2

Магические * внутренние * - это MMU (аппаратное обеспечение фактически, а не ОС), см. Ответ nos. ОС действительно принимает решение о сопоставлении и программирует MMU для фактического осуществления перевода. – Wim

5

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

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

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