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

Организация виртуальной памяти

что такое виртуальный адрес. Смотреть фото что такое виртуальный адрес. Смотреть картинку что такое виртуальный адрес. Картинка про что такое виртуальный адрес. Фото что такое виртуальный адресПривет, Хабрахабр!

В предыдущей статье я рассказал про vfork() и пообещал рассказать о реализации вызова fork() как с поддержкой MMU, так и без неё (последняя, само собой, со значительными ограничениями). Но прежде, чем перейти к подробностям, будет логичнее начать с устройства виртуальной памяти.

Конечно, многие слышали про MMU, страничные таблицы и TLB. К сожалению, материалы на эту тему обычно рассматривают аппаратную сторону этого механизма, упоминая механизмы ОС только в общих чертах. Я же хочу разобрать конкретную программную реализацию в проекте Embox. Это лишь один из возможных подходов, и он достаточно лёгок для понимания. Кроме того, это не музейный экспонат, и при желании можно залезть “под капот” ОС и попробовать что-нибудь поменять.

Введение

Любая программная система имеет логическую модель памяти. Самая простая из них — совпадающая с физической, когда все программы имеют прямой доступ ко всему адресному пространству.
При таком подходе программы имеют доступ ко всему адресному пространству, не только могут “мешать” друг другу, но и способны привести к сбою работы всей системы — для этого достаточно, например, затереть кусок памяти, в котором располагается код ОС. Кроме того, иногда физической памяти может просто не хватить для того, чтобы все нужные процессы могли работать одновременно. Виртуальная память — один из механизмов, позволяющих решить эти проблемы. В данной статье рассматривается работа с этим механизмом со стороны операционной системы на примере ОС Embox. Все функции и типы данных, упомянутые в статье, вы можете найти в исходном коде нашего проекта.

Будет приведён ряд листингов, и некоторые из них слишком громоздки для размещения в статье в оригинальном виде, поэтому по возможности они будут сокращены и адаптированы. Также в тексте будут возникать отсылки к функциям и структурам, не имеющим прямого отношения к тематике статьи. Для них будет дано краткое описание, а более полную информацию о реализации можно найти на вики проекта.

Общие идеи

Аппаратная поддержка

Обращение к памяти хорошо описанно в этой хабростатье. Происходит оно следующим образом:

Процессор подаёт на вход MMU виртуальный адрес
Если MMU выключено или если виртуальный адрес попал в нетранслируемую область, то физический адрес просто приравнивается к виртуальному
Если MMU включено и виртуальный адрес попал в транслируемую область, производится трансляция адреса, то есть замена номера виртуальной страницы на номер соответствующей ей физической страницы (смещение внутри страницы одинаковое):
Если запись с нужным номером виртуальной страницы есть в TLB [Translation Lookaside Buffer], то номер физической страницы берётся из нее же
Если нужной записи в TLB нет, то приходится искать ее в таблицах страниц, которые операционная система размещает в нетранслируемой области ОЗУ (чтобы не было промаха TLB при обработке предыдущего промаха). Поиск может быть реализован как аппаратно, так и программно — через обработчик исключения, называемого страничной ошибкой (page fault). Найденная запись добавляется в TLB, после чего команда, вызвавшая промах TLB, выполняется снова.

Таким образом, при обращении программы к тому или иному участку памяти трансляция адресов производится аппаратно. Программная часть работы с MMU — формирование таблиц страниц и работа с ними, распределение участков памяти, установка тех или иных флагов для страниц, а также обработка page fault, ошибки, которая происходит при отсутствии страницы в отображении.

В тексте статьи в основном будет рассматриваться трёхуровневая модель памяти, но это не является принципиальным ограничением: для получения модели с бóльшим количеством уровней можно действовать аналогичным образом, а особенности работы с меньшим количеством уровней (как, например, в архитектуре x86 — там всего два уровня) будут рассмотрены отдельно.

Программная поддержка

Виртуальный адрес

Page Global Directory (далее — PGD) — таблица (здесь и далее — то же самое, что директория) самого высокого уровня, каждая запись в ней — ссылка на Page Middle Directory (PMD), записи которой, в свою очередь, ссылаются на таблицу Page Table Entry (PTE). Записи в PTE ссылаются на реальные физические адреса, а также хранят флаги состояния страницы.

То есть, при трёхуровневой иерархии памяти виртуальный адрес будет выглядеть так:
что такое виртуальный адрес. Смотреть фото что такое виртуальный адрес. Смотреть картинку что такое виртуальный адрес. Картинка про что такое виртуальный адрес. Фото что такое виртуальный адрес

Значения полей PGD, PMD и PTE — это индексы в соответствующих таблицах (то есть сдвиги от начала этих таблиц), а offset — это смещение адреса от начала страницы.

В зависимости от архитектуры и режима страничной адресации, количество битов, выделяемых для каждого из полей, может отличаться. Кроме того, сама страничная иерархия может иметь число уровней, отличное от трёх: например, на x86 нет PMD.

Для обеспечения переносимости мы задали границы этих полей с помощью констант: MMU_PGD_SHIFT, MMU_PMD_SHIFT, MMU_PTE_SHIFT, которые в приведённой выше схеме равны 24, 18 и 12 соответственно их определение дано в заголовочном файле src/include/hal/mmu.h. В дальнейшем будет рассматриваться именно этот пример.

На основании сдвигов PGD, PMD и PTE вычисляются соответствующие маски адресов.

Эти макросы даны в том же заголовочном файле.

Для работы с виртуальной таблицами виртуальной памяти в некоторой области памяти хранятся указатели на все PGD. При этом каждая задача хранит в себе контекст struct mmu_context, который, по сути, является индексом в этой таблице. Таким образом, к каждой задаче относится одна таблица PGD, которую можно определить с помощью mmu_get_root(ctx).

Страницы и работа с ними

Размер страницы

В реальных (то есть не в учебных) системах используются страницы от 512 байт до 64 килобайт. Чаще всего размер страницы определяется архитектурой и является фиксированным для всей системы, например — 4 KiB.

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

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

В дальнейшем речь пойдёт о страницах обычного размера.

Устройство Page Table Entry

В реализации проекта Embox тип mmu_pte_t — это указатель.
Каждая запись PTE должна ссылаться на некоторую физическую страницу, а каждая физическая страница должна быть адресована какой-то записью PTE. Таким образом, в mmu_pte_t незанятыми остаются MMU_PTE_SHIFT бит, которые можно использовать для сохранения состояния страницы. Конкретный адрес бита, отвечающего за тот или иной флаг, как и набор флагов в целом, зависит от архитектуры.

Можно установить сразу несколько флагов:

Здесь vmem_page_flags_t — 32-битное значение, и соответствующие флаги берутся из первых MMU_PTE_SHIFT бит.

Трансляция виртуального адреса в физический

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

Для того, чтобы получить из виртуального адреса физический, необходимо пройти по цепочке таблиц PGD, PMD и PTE. Функция vmem_translate() и производит эти шаги.
Сначала проверяется, есть ли в PGD указатель на директорию PMD. Если это так, то вычисляется адрес PMD, а затем аналогичным образом находится PTE. После выделения физического адреса страницы из PTE необходимо добавить смещение, и после этого будет получен искомый физический адрес.

Пояснения к коду функции.
mmu_paddr_t — это физический адрес страницы, назначение mmu_ctx_t уже обсуждалось выше в разделе “Виртуальный адрес”.

С помощью функции vmem_get_idx_from_vaddr() находятся сдвиги в таблицах PGD, PMD и PTE.

что такое виртуальный адрес. Смотреть фото что такое виртуальный адрес. Смотреть картинку что такое виртуальный адрес. Картинка про что такое виртуальный адрес. Фото что такое виртуальный адрес

Работа с Page Table Entry

Для работы с записей в таблице страниц, а так же с самими таблицами, есть ряд функций:

Эти функции возвращают 1, если у соответствующей структуры установлен бит MMU_PAGE_PRESENT

Page Fault

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

Выталкивание страниц во внешнюю память и их чтение в случае page fault не реализовано. С одной стороны, это лишает возможности использовать больше физической памяти, чем имеется на самом деле, а с другой — не является актуальной проблемой для встраиваемых систем. Нет никаких ограничений, делающих невозможной реализацию данного механизма, и при желании читатель может попробовать себя в этом деле 🙂

Выделение памяти

Для виртуальных страниц и для физических страниц, которые могут быть использованы при работе с виртуальной памятью, статически резервируется некоторое место в оперативной памяти. Тогда при выделении новых страниц и директорий они будут браться именно из этого места.
Исключением является набор указателей на PGD для каждого процесса (MMU-контексты процессов): этот массив хранится отдельно и используется при создании и разрушении процесса.
Выделение страниц
Итак, выделить физическую страницу можно с помощью vmem_alloc_page

Функция page_alloc() ищет участок памяти из N незанятых страниц и возвращает физический адрес начала этого участка, помечая его как занятый. В приведённом коде virt_page_allocator ссылается на участок памяти, резервированной для выделения физических страниц, а 1 — количество необходимых страниц.
Выделение таблиц
Тип таблицы (PGD, PMD, PTE) не имеет значения при аллокации. Более того, выделение таблиц производится также с помощью функции page_alloc(), только с другим аллокатором (virt_table_allocator).

Участки памяти (Memory Area)

После добавления страниц в соответствующие таблицы нужно уметь сопоставлять участки памяти с процессами, к которым они относятся. У нас в системе процесс представлен структурой task, содержащей всю необходимую информацию для работы ОС с процессом. Все физически доступные участки адресного пространства процесса записываются в специальный репозиторий: task_mmap. Он представляет из себя список дескрипторов этих участков (регионов), которые могут быть отображены на виртуальную память, если включена соответствующая поддержка.

brk — это самый большой из всех физических адресов репозитория, данное значение необходимо для ряда системных вызовов, которые не будут рассматриваться в данной статье.
ctx — это контекст задачи, использование которого обсуждалось в разделе “Виртуальный адрес”.
struct dlist_head — это указатель на начало двусвязного списка, организация которого аналогична организации Linux Linked List.

За каждый выделенный участок памяти отвечает структура marea

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

Отображение виртуальных участков памяти на физические (Mapping)

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

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

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

В качестве параметров передаётся контекст задачи, адрес начала физического участка памяти, а также адрес начала виртуального участка. Переменная flags содержит флаги, которые будут установлены у соответствующих записей в PTE.

Основную работу на себя берёт do_map_region(). Она возвращает 0 при удачном выполнении и код ошибки — в ином случае. Если во время маппирования произошла ошибка, то часть страниц, которые успели выделиться, нужно откатить сделанные изменения с помощью функции vmem_unmap_region(), которая будет рассмотрена позднее.

Рассмотрим функцию do_map_region() подробнее.

Макросы GET_PTE и GET_PMD нужны для лучшей читаемости кода. Они делают следующее: если в таблице памяти нужный нам указатель не ссылается на существующую запись, нужно выделить её, если нет — то просто перейти по указателю к следующей записи.

В самом начале необходимо проверить, выровнены ли под размер страницы размер региона, физический и виртуальный адреса. После этого определяется PGD, соответствующая указанному контексту, и извлекаются сдвиги из виртуального адреса (более подробно это уже обсуждалось выше).
Затем последовательно перебираются виртуальные адреса, и в соответствующих записях PTE к ним привязывается нужный физический адрес. Если в таблицах отсутствуют какие-то записи, то они будут автоматически сгенерированы при вызове вышеупомянутых макросов GET_PTE и GET_PMD.

Освобождение виртуального участка памяти (Unmapping)

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

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

try_free_pte, try_free_pmd, try_free_pgd — это вспомогательные функции. При удалении очередной страницы может выясниться, что директория, её содержащая, могла стать пустой, а значит, её нужно удалить из памяти.

нужны как раз для случая двухуровневой иерархии памяти.

Заключение

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

Источник

Адреса памяти: физические, виртуальные, логические, линейные, эффективные, гостевые

Мне периодически приходится объяснять разным людям некоторые аспекты архитектуры Intel® IA-32, в том числе замысловатость системы адресации данных в памяти, которая, похоже, реализовала почти все когда-то придуманные идеи. Я решил оформить развёрнутый ответ в этой статье. Надеюсь, что он будет полезен ещё кому-нибудь.
При исполнении машинных инструкций считываются и записываются данные, которые могут находиться в нескольких местах: в регистрах самого процессора, в виде констант, закодированных в инструкции, а также в оперативной памяти. Если данные находятся в памяти, то их положение определяется некоторым числом — адресом. По ряду причин, которые, я надеюсь, станут понятными в процессе чтения этой статьи, исходный адрес, закодированный в инструкции, проходит через несколько преобразований.

что такое виртуальный адрес. Смотреть фото что такое виртуальный адрес. Смотреть картинку что такое виртуальный адрес. Картинка про что такое виртуальный адрес. Фото что такое виртуальный адрес

На рисунке — сегментация и страничное преобразование адреса, как они выглядели 27 лет назад. Иллюстрация из Intel 80386 Programmers’s Reference Manual 1986 года. Забавно, что в описании рисунка есть аж две опечатки: «80306 Addressing Machanism». В наше время адрес подвергается более сложным преобразованиям, а иллюстрации больше не делают в псевдографике.

Начнём немного с конца — с цели всей цепочки преобразований.

Физический адрес

Эффективный адрес

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

Например, для инструкции (ассемблер в AT&T-нотации)

addl %eax, 0x11(%ebp, %edx, 8)

эффективный адрес операнда-назначения будет вычислен по формуле:

eff_addr = EBP + EDX * 8 + 0x11

Логический адрес

Здесь обычно у тех, кто столкнулся с этими понятиями впервые, голова начинает идти кругом. Несколько упростить (или усложнить) ситуацию помогает тот факт, что почти всегда выбор селектора (и связанного с ним сегмента) делается исходя из «смысла» доступа. По умолчанию, если в кодировке машинной инструкции не сказано иного, для получения адресов кода используются логические адреса с селектором CS, для данных — с DS, для стека — с SS.

Линейный адрес

Эффективный адрес — это смещение от начала сегмента — его базы. Если сложить базу и эффективный адрес, то получим число, называемое линейным адресом:

lin_addr = segment.base + eff_addr

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

Сегментация была модной на некотором этапе развития вычислительной техники. В настоящее она почти всюду была заменена другими механизмами, и используется только для специфических задач. Так, в режиме IA-32e (64-битном) только два сегмента могут иметь ненулевую базу. Для остальных четырёх в этом режиме всегда линейный адрес == эффективный.

Что такое виртуальный адрес?

В литературе и в документации других архитектур встречается ещё один термин — виртуальный адрес. Он не используется в документации Intel на IA-32, однако встречается, например, в описании Intel® Itanium, в котором сегментация не используется. Можно смело считать, что для IA-32 виртуальный == линейный.
В советской литературе по вычислительной технике этот вид адресов также именовался математическим.

Страничное преобразование

Однако общая идея всегда одна и та же: линейный адрес разбивается на несколько частей, каждая из которых служит индексом в одной из системных таблиц, хранящихся в памяти. Записи в таблицах — это адреса начала таблицы следующего уровня или, для последнего уровня — искомая информация о физическом адресе страницы в памяти и её свойствах. Самые младшие биты не преобразуются, а используются для адресации внутри найденной страницы. Например, для режима PAE с размером страниц 4 кбайт преобразование выглядит так:

что такое виртуальный адрес. Смотреть фото что такое виртуальный адрес. Смотреть картинку что такое виртуальный адрес. Картинка про что такое виртуальный адрес. Фото что такое виртуальный адрес

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

Гостевой физический

До введения возможностей аппаратной виртуализации в процессорах Intel страничное преобразование было последним в цепочке. Когда же на одной системе работают несколько виртуальных машин, то физические адреса, получаемые в каждой из них, приходится транслировать ещё один раз. Это можно делать программным образом, или же аппаратно, если процессор поддерживает функциональность EPT (англ. Extended Page Table). Адрес, раньше называвшийся физическим, был переименован в гостевой физический для того, чтобы отличать его от настоящего физического. Они связаны с помощью EPT-преобразования. Алгоритм последнего схож с ранее описанным страничным преобразованием: набор связанных таблиц с общим корнем, последний уровень которых определяет, существует ли физическая страница для указанной гостевой физической.

Полная картина

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

что такое виртуальный адрес. Смотреть фото что такое виртуальный адрес. Смотреть картинку что такое виртуальный адрес. Картинка про что такое виртуальный адрес. Фото что такое виртуальный адрес

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

Заключение

Источник

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

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

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

любая помощь будет высоко оценили.

9 ответов

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

Типы Адресов

относительно вопроса 3:

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

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

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

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

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

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

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

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

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

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

теперь, что произойдет, если ваша программа запрашивает переменную (oftenNotUsed)? MMU + OS заметит этот «промах» и получит его для вас с жесткого диска в ОЗУ, а затем передаст его вам, как если бы он был в адресе (0xaa); эта выборка означает, что некоторые данные, которые присутствовали в ОЗУ, будут отправлены обратно в ОЗУ Жесткий диск.

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

резюме

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

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

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

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

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

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

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

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

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

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

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

теперь селектор сегмента или идентификатор сегмента say относится к сегменту кода или сегменту данных или сегменту стека и т. д. Linux содержит один GDT/LDT (Global / Local Descriptor Table), который содержит 8-байтовый дескриптор каждого сегмента и содержит базовый (виртуальный) адрес сегмента.

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

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

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

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

см.: понимание ядра linux, глава 2 Адресация Памяти

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *