Подтвердить что ты не робот

Разница между физическим/логическим/виртуальным адресом памяти

Я немного запутался в терминах физических/логических/виртуальных адресов в операционной системе (я использую Linux-open SUSE)

Вот что я понимаю:

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

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

  • Я столкнулся с обсуждением того, что виртуальные и логические адреса/адресные пространства одинаковы. Это правда?

Любая помощь глубоко оценена.

4b9b3361

Ответ 1

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

Типы адресов

По вопросу 3:

Я сталкивался с тем, что виртуальный и логичный адреса/адресное пространство одинаковы. Это правда?

Насколько я знаю, они одинаковы, по крайней мере, в современных ОС, работающих на процессорах Intel.

Позвольте мне попытаться определить два понятия, прежде чем я объясню больше:

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

Виртуальный/логический адрес

С виртуальным адресом все в порядке, виртуальный адрес, ОС вместе с аппаратной схемой, называемой MMU (блок управления памятью), вводят в заблуждение вашу программу, которая запускается одна в системе, она получила все адресное пространство (наличие 32-битной системы означает Программа будет думать, что она имеет 4 ГБ ОЗУ, грубо говоря).

Очевидно, что если у вас одновременно запущено более одной программы (вы всегда это делаете, GUI, процесс Init, оболочка, приложение часов, календарь и т.д.), Это не сработает.

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

Пример: Ваш процесс может иметь переменную с именем (counter), которой присвоен виртуальный адрес 0xff (предположительно...), и другую переменную с именем (частоNotUsed), которой присвоен виртуальный адрес (0xaa).

Если вы прочтете сборку вашего скомпилированного кода после того, как все связывание произойдет, вы будете получать к ним доступ с помощью этих адресов, но в действительности переменная (часто не полученная) не будет в ОЗУ в 0xaa, она будет на жестком диске потому что процесс не использует его.

Более того, переменная (counter), вероятно, не будет физически в (0xff), она будет где-то еще в ОЗУ, когда ваш ЦП попытается извлечь то, что в 0xff, MMU и части ОС выполнит отображение и получить эту переменную из того места, где она действительно доступна в оперативной памяти, процессор даже не заметит, что ее не было в 0xff.

Что произойдет, если ваша программа запросит переменную (ЧастоNotUsed)? ОС MMU + заметит это "промах" и извлечет его для ЦП с жесткого диска в ОЗУ, а затем передаст его ЦП, как если бы он был в адресе (0xaa); эта выборка означает, что некоторые данные, присутствующие в оперативной памяти, будут отправлены обратно на жесткий диск.

Теперь представьте, что это работает для каждого процесса в вашей системе. Каждый процесс думает, что у него есть 4 ГБ ОЗУ, на самом деле никто этого не имеет, но все работает, потому что у каждого есть некоторые части своей программы, физически доступные в ОЗУ, но большая часть программы находится на жестком диске. Не путайте эту часть памяти программы, помещаемой в HD, с данными программы, к которым вы можете получить доступ посредством файловых операций.

Резюме

Виртуальный адрес: адрес, который вы используете в своих программах, адрес, который ваш ЦП использует для извлечения данных, не является реальным и переводится через MMU на какой-то физический адрес; у каждого он есть, и его размер зависит от вашей системы (32-битный Linux имеет адресное пространство 4 ГБ)

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

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

Последствия этой системы

  • Процессы не могут обращаться к памяти друг друга, у каждого есть свои виртуальные адреса, и каждый процесс получает различный перевод в разные области, даже если иногда вы можете увидеть, что два процесса пытаются получить доступ к одному и тому же виртуальному адресу.
  • Эта система хорошо работает как система кеширования, вы обычно не используете все имеющиеся у вас 4 ГБ, так зачем тратить их впустую? пусть другие делятся этим и позволяют им тоже это использовать; когда вашему процессу требуется больше, операционная система будет извлекать ваши данные с жесткого диска и заменять данные других процессов, конечно же, за счет этого.

Ответ 2

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

Не обязательно верно. Это зависит от конкретного процессора. На процессорах x86 после того, как вы включили трансляцию страницы, весь код перестает работать с физическими адресами или адресами, тривиально конвертируемыми в физические адреса (кроме SMM, AFAIK, но это не важно здесь).

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

Логические адреса не обязательно применяются исключительно к пользовательскому режиму. На процессорах x86 они существуют и в режиме ядра.

Я столкнулся с обсуждением того, что виртуальные и логические адреса/адресные пространства одинаковы. Это правда?

Это зависит от конкретного процессора. Процессоры x86 могут быть сконфигурированы таким образом, чтобы сегменты не использовались явно. Они используются неявно, и их базы всегда равны 0 (за исключением сегментов локально-хранилища потоков). То, что остается, когда вы отбрасываете селектор сегмента с логического адреса, представляет собой 32-разрядное (или 64-битное) смещение, значение которого совпадает с 32-битным (или 64-разрядным) виртуальным адресом. В этой упрощенной настройке вы можете подумать о том, чтобы оба они были одинаковыми или что логических адресов не существует. Это неправда, но для большинства практических целей достаточно хорошая аппроксимация.

Ответ 3

Я имею в виду нижнюю базу ответов на Intel x86 CPU

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

Всякий раз, когда ваша программа находится в процессе выполнения, CPU генерирует логический адрес для инструкций, который содержит (16-битный селектор и 32-битное смещение). Виртуально виртуальный (линейный адрес) генерируется с использованием полей логических адресов.

Сегмент сегмента - это 16-битное поле, из которого первый 13 бит является индексом (который является указателем на дескриптор сегмента, находится в GDT, описанном ниже), 1-битное поле TI (TI = 1, Refer LDT, TI = 0 Refer GDT )

Теперь сегментный селектор ИЛИ говорит, что идентификатор сегмента относится к сегменту кода или сегменту данных или сегменту стека и т.д. В Linux содержится одна таблица GDT/LDT (глобальная/локальная дескрипторная таблица), которая содержит 8-байтовый дескриптор каждого сегмента и содержит базовый (виртуальный) адрес сегмента.

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

1) Изучает поле TI Сегмента Селектора, чтобы определить, какой дескриптор Таблица хранит дескриптор сегмента. Это поле указывает, что дескриптор либо в GDT (в этом случае единица сегментации получает базовую линейную адрес GDT из регистра gdtr) или в активной LDT (в этом случае единица сегментации получает базовый линейный адрес этого LDT из регистра ldtr).

2) Вычисляет адрес дескриптора сегмента из поля индекса сегмента Selector. Поле индекса умножается на 8 (размер дескриптора сегмента), и результат добавляется к содержимому регистра gdtr или ldtr.

3) Добавляет смещение логического адреса в поле Base дескриптора сегмента, получая таким образом линейный (виртуальный) адрес.

Теперь работа модуля Pagging заключается в переводе физического адреса с виртуального адреса.

См.: Общие сведения о ядре linux, глава 2 Адресация адресов

Ответ 4

Обычно каждый адрес, выданный (для архитектуры x86), является логическим адресом, который преобразуется в линейный адрес через таблицы сегментов. После перевода в линейный адрес он затем переводится на физический адрес через таблицу страниц.
Хорошая статья, объясняющая то же самое по глубине:
http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation/

Ответ 5

Пользовательские виртуальные адреса Это обычные адреса, видимые программами пользовательского пространства. Адреса пользователей имеют длину 32 или 64 бита, в зависимости от базовой аппаратной архитектуры, и каждый процесс имеет свое собственное виртуальное адресное пространство.

Физические адреса Адреса, используемые между процессором и системной памятью. Физические адреса: 32- или 64-битные величины; даже 32- битовые системы могут использовать 64-битные физические адреса в некоторых ситуациях.

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

Ядра логических адресов Они составляют нормальное адресное пространство ядра. Эти адреса отображают большую часть или всю основную память и часто рассматриваются как физические адреса. На большинстве архитектур логические адреса и связанные с ними физические адреса отличаются только постоянным смещением. Логические адреса используют аппаратный собственный размер указателя и, следовательно, могут быть не в состоянии адресовать всю физическую память в сильно оборудованных битовых системах 32-. Логические адреса обычно хранятся в переменных типа unsigned long или void *. Память, возвращаемая из kmalloc, имеет логический адрес.

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

Если у вас есть логический адрес, макрос __pa() (определенный в) вернет связанный с ним физический адрес. Физические адреса могут быть сопоставлены с логическими адресами с помощью __va(), но только для страниц с небольшим объемом памяти.

Ссылочная.

Ответ 6

Физический адрес - это адрес, который видит блок памяти, то есть один загруженный в регистр адресов памяти. Логический адрес - это адрес, который генерируется процессором. Пользовательская программа никогда не сможет увидеть реальный физический адрес. Модуль сопоставления памяти преобразует логический адрес в физический адрес. Логический адрес, сгенерированный пользовательским процессом, должен быть сопоставлен с физической памятью до их использования.

Ответ 7

Логическая память относится к соответствующей программе i.e(Начальная точка программы + смещение)

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

Ответ 8

В Usermode или UserSpace все адреса, просматриваемые программой, являются виртуальными адресами. Когда в режиме ядра адреса, видимые ядром, остаются виртуальными, но называются логическими, так как они равны физическому + pageoffset.  Физические адреса - это те, которые видны ОЗУ. С виртуальной памятью каждый адрес в программе проходит через таблицы страниц.

Ответ 9

когда u напишите небольшую программу, например:

int a=10;
int main()
{
 printf("%d",a);
}   


compile: >gcc -c fname.c
>ls 
fname.o //fname.o is generated
>readelf -a fname.o >readelf_obj.txt

/readelf - это команда для понимания объектных файлов и исполняемого файла, который будет в 0 и 1. вывод записывается в файле readelf_onj.txt/

`>vim readelf_obj.txt`

/* в разделе "заголовок раздела" вы увидите разделы .data.text.rodata вашего объектного файла. каждый начальный или базовый адрес начинается с 0000 и растет до соответствующего размера, пока он не достигнет размера под заголовком "размер" ---- > это логические адреса. */

>gcc fname.c
>ls
a.out //your executabe
>readelf -a a.out>readelf_exe.txt
>vim readelf_exe.txt 

/* здесь базовый адрес всех разделов не равен нулю. он начинается с определенного адреса и заканчивается на конкретный адрес. Компилятор будет предоставлять непрерывные адреса всем разделам (см. Файл readelf_exe.txt. Обратите внимание на базовый адрес и размер каждого раздела. Они запускаются непрерывно), поэтому только базовые адреса различаются.--- > это называется виртуальным адресное пространство. */

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