2013-12-13 4 views
1

Я понимаю, что если я попытаюсь напечатать адрес элемента массива, это будет адрес из виртуальной памяти, а не из реальной памяти i.e DRAM.Как получить адрес DRAM вместо виртуального адреса

printf ("Address of A[5] and A[6] are %u and %u", &A[5], &A[6]); 

Я нашел адреса последовательными (при условии, что элементы являются символами). Я понимаю, что в действительности они не будут последовательными, по крайней мере, вообще, в DRAM. Я хочу знать этот реальный адрес. Как мне это получить?

Мне нужно знать это для Windows или Linux.

+0

Это зависит от того, на какой платформе (например, ОС) вы находитесь. Также обратите внимание, что виртуальные адреса могут не обязательно отображаться на физические адреса. –

+6

'Я хочу знать, что настоящий адрес.': No вы не делаете !! Какова фактическая проблема, которую, по вашему мнению, вы собираетесь решить, имея физический адрес вместо виртуального? – John3136

+4

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

ответ

3

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

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

+0

Вам даже не нужно делать системный вызов. Достаточно получить доступ к незапечатанной странице. С другой стороны, в зависимости от привилегий процесса и конфигурации системы вы могли бы использовать 'mlock (2)', чтобы заставить страницы (-ы) быть резидентными, и в этом случае их физическое отображение будет стабильным. Даже если вы это сделаете, я не верю, что есть способ узнать, что такое отображение, за исключением ядра. – rici

+0

@rici Доступ к незапечатанной странице никуда не годится, отсюда и терминология. Правда, многие ОС предоставляют некоторый способ записи драйверов пользовательского режима с жестко закодированными адресами. – Potatoswatter

+0

@Potatoswatter: s/unmapped/swapped-out /. Я не должен комментировать, когда устал. – rici

2

Простой ответ заключается в том, что в общем случае для пользовательских процессов или потоков в многопроцессорной ОС, такой как Windows или Linux, невозможно найти адрес даже статической переменной в адресном пространстве памяти процессора, пусть только адрес DRAM.

Есть несколько причин для этого:

  1. памяти, выделенная для процесса является виртуальной памятью. ОС может переназначать эту память процесса время от времени из одного диапазона физических адресов в другой, и нет способа обнаружить это переназначение в пользовательском процессе. То есть физический адрес переменной может меняться в течение всего жизненного цикла процесса.
  2. Интерфейс от пользовательского пространства до пространства ядра, который позволит процессу пользовательского пространства проходить через таблицу процессов и кеш страницы ядра, чтобы найти физический адрес процесса. В Linux вы можете написать модуль ядра или драйвер, который может это сделать.
  3. DRAM часто отображается в адресное пространство процессора через блок управления памятью (MMU) и кэш памяти. Хотя MMU-сопоставление DRAM в адресное пространство процессора обычно выполняется только один раз, во время загрузки системы использование процессором кэша может означать, что значения, записанные в переменную, во всех случаях не могут быть записаны в DRAM.

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

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

Вот ссылка на статью под названием Translating Virtual to Physical Address on Windows: Physical Addresses что дает намек на крайности заканчивается, к которому вы должны пойти, чтобы получить физические адреса на Windows.

Смежные вопросы