Ты наверное не понимаешь принцип работы виртуальной памяти.
В Винде всё обстоит так:
Есть физическая память, которой управляет менеджер памяти.
И есть Виртуальная память, которая по сути - это ссылка на физическую память.
Существую каталоги страниц (РТЕ) там находится связь - какая страница виртуальной памяти с какой страницей физической памяти связана или если юзается файл подкачки, то откуда взаимодействие с этим механизмом.
И вот есть общий катало страниц - глобальный и отдельно на каждый процесс.
По этому если в виртуальном адресном пространстве записаны подряд несколько страниц, то это не значит что они также будут идти в физической памяти.
Советую почитать книги по програмирвоанию дров. там описаны принципи работы этого механизма.
Вот будет тебе полезно:
Цитата:
Virtual Memory
Виртуальная память.
Рассмотрим пример. Предположим, некая фирма имеет оплачиваемое пространство на складе своего оптового поставщика. Учет ее имущества производится хозяином склада в следующей форме. Каждая коробка имеет двузначный номер ПК (Полка/Коробка), где К — это действительно номер коробки 0..9 на соответствующей полке, а вот с номером полки дело обстоит сложнее. Для того чтобы узнать сквозной (физический) номер полки на складе, необходимо заглянуть в журнал выделения полок фирмам и получить из него настоящий номер полки. Правда, склад в нашем примере небольшой — всего десять полок!
Неудивительной будет ситуация, если через несколько дней работы по предложенной системе коробка, относящаяся к рассматриваемой фирме, с виртуальным номером 19 будет находиться на полке 2, притом, что коробка номер 20 — уже на полке 8. Но нумерация коробок осталась непрерывной, что очень нравится владельцам коробок!
Что дает такая система? Предположим, что очередному пользователю склада понадобилось 5 свободных полок, они имеются, но не подряд. Такая ситуация не внесет никакого разлада в систему учета, и понравившаяся клиентам склада непрерывная нумерация его пространства так и останется непрерывной.
Аналогичная методика принята в современных операционных системах. Преимущества ее использования огромны. Приложениям не нужно ожидать получения непрерывных пространств памяти — достаточно наличия фрагментов стандартной длины. Более того, если какое-либо приложения имеет низкую активность, можно его виртуальную память "сбросить" в файл на жестком диске (этот процесс называется swapping), a физическую память предоставить активным приложениям. (То есть — хранить коробки в подвале, но к моменту приезда клиентов — элегантно размещать их на полках склада. При определенной сноровке можно внушить каждому клиенту с большими запасами, что склад используется только для хранения его товара.)
Помимо этого, можно относительно легко контролировать несанкционированный доступ приложений к памяти по адресам, которые им не были предоставлены.
Столь объемное лирическое отступление было выполнено ради того, чтобы описать ситуацию, в которой проявляются весьма существенные проблемы.
System Paging File
Системный файл для хранения временно неиспользуемых областей странично организованной памяти (выгруженных из физической памяти).
User Space
Пользовательское пространство памяти. Область виртуальной памяти, выделенная для работы пользовательских приложений. Обычно составляет 2 гигабайта и ограничена сверху адресом 0x79999999 (в серверной конфигурации возможны варианты, когда, в результате регулировки настроек операционной системы, приложения пользовательского режима получают возможность использовать 3 гигабайта виртуальной памяти, оставляя под системные нужды лишь 1 гигабайт). Все сказанное относится к 32-разрядным версиям Windows. B 64-разрядных версиях Windows XP и Windows Server 2003 ситуация более сложная, хотя для 32-разрядных приложений и там ничего не меняется. Подробнее вопросы адресации в 64-разрядных версиях Windows будут рассмотрены в главе 4.
Pool Memory
Память в пулах (страничном или нестраничном). Области в пространстве памяти ядра (адреса выше 0x80000000 для стандартной конфигурации системы — поскольку для сервера можно определить иначе), в которых можно динамически выделять (получать, аллокировать) и освобождать (деаллокировать) области памяти. Менеджер Памяти (Memory Manager) различает два типа пулов, к которым драйвер может получать доступ при помощи вызовов функций исполнительного блока Ex(ecutive):
Paged pool — страничный пул, в котором каждый процесс имеет собственный набор РТЕ (Page Table Entries) — записей в таблице страниц.
Nonpaged pool — нестраничный пул, в котором все процессы совместно используют один набор РТЕ — записей в таблице страниц.
Выделение областей для физически непрерывных областей или областей некэшируемой памяти производится из ресурсов нестраничного пула.
Paged Memory, Paged Pool
Странично организованная память, страничный пул, страничная память.
Виртуальная память, которая может быть перемещена системой на жесткий диск, в любой момент, когда она сочтет эту операцию целесообразной (например, при низкой активности приложения). Эта перемещенная область имеет название "paged", то есть "постранично сброшенная на диск". В том случае, если приложение, например, снова становится активным и обращается к отсутствующей в физической памяти области своей виртуальной памяти, то возникает исключение, хорошо известное под названием "page fault". B результате его перехвата к работе приступает системный обработчик этого исключения и "подтягивает" в физическую память отсутствующую информацию.
Однако при работе в режиме ядра кода, имеющего IRQL уровень приоритета равный или выше DISPATCH_LEVEL, возникает катастрофическая ситуация. Если обстоятельства сложились так, что этот программный код должен получить доступ к виртуальной странице, сброшенной на диск, и эта страница могла бы быть размещена в физической памяти усилиями системного обработчика исключения типа "page fault", но... Но уровень IRQL обработчика ниже приоритета DISPATCH_LEVEL, и система не дает ему возможности приступить к работе, вместо этого прекращая всю работу системы! Обращаться к страничной памяти (если не предпринимать специальных мер) и производить получение новых областей категорически рекомендуется только из кода, работающего на IRQL уровнях PASSIVE_LEVEL или APC_LEVEL.
Можно, конечно, организовать собственный перехват исключения в сомнительном месте, как это сделано во фрагменте кода ниже.
__try
{
char x=*(char*)0x0L;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Exception detected in my driver");
};
Однако такое решение позволяет лишь уйти от конкретной ошибки (да и работает только на IRQL уровне PASSIVE_LEVEL). Получение доступа к нужным данным так и остается нерешенной задачей. Другое, более правильное решение предлагается ниже.
Nonpaged Memory, Nonpaged Pool
Нестранично организованная память, нестраничный пул, нестраничная память.
Виртуальная память, которая никогда не может быть перемещена системой на жесткий диск и всегда остается в физической оперативной памяти. Ценный ресурс операционной системы, которым следует распоряжаться весьма осмотрительно. К памяти данного типа можно безопасно обращаться из потоков, работающих на любом уровне IRQL.
Недостатки нестраничной памяти (помимо того, что ее не очень много) проявляются практически в одном случае — при работе с устройствами, поддерживающими режим прямого доступа к памяти (DMA или, в русском варианте, ПДП). Будь то страничная виртуальная память, либо нестраничная — соответствующие области в физической памяти могут быть разрывными. Однако работа с DMA устройствами требует физической непрерывности областей, из которых берутся или куда передаются данные при DMA операциях. Выход, который могла бы предложить функция MmAllocateContiguousMemory (она умеет выделять непрерывные области физической памяти), может лишь отсрочить момент краха, который неминуем, если все потоки в режиме ядра начнут практиковать исключительно такие методы.
Объем памяти, которую система отводит под нестраничную память, ограничен. Даже при наличии достаточного объема физической оперативной памяти Windows 2000 позволяла иметь до 660 Мбайт нестраничной памяти, а 32-разрядная версия Windows XP до 1,3 Гбайт. Использование физической памяти свыше 4 Гбайт в 32-разрядных версиях Windows (даже если это позволяет аппаратура) производится через механизм физических адресов, что определяется параметром /РАЕ (разрешающим использование Physical Address Extension через загрузку другой под-версии ядра) в файле конфигурирования процесса загрузки boot.ini, см. главу 4.
|
|