
- •Лекция №4. Архитектура памяти. Управление памятью. Mdl. Выделение памяти. Отображение памяти. [4.1] Организация памяти в защищенном режиме работы процессора
- •[4.2] Организация системного адресного пространства
- •[4.4] Совместное использование памяти
- •[4.5] Объект Секция
- •[4.6] Таблица описания памяти (Memory Descriptor List - mdl)
- •[4.7] Подведение итогов. Функции работы с памятью
- •[4.7.1]Выделениепамяти
- •[4.7.2] Lookaside List
- •[4.7.3] Отображение памяти устройств и пространства в/в
- •[4.7.4]УправлениепамятьюиMdl
[4.5] Объект Секция
Диспетчер Памяти в NT экспортирует единственную структуру для контроля данных – Объект-Секцию. Подобно другим объектам, Объект-Секция может быть именованным, т.е. имя будет видимо в пространстве имен Диспетчера Объектов.
Секция может быть использована драйвером для отображения участка памяти системного адресного пространства (в том числе невыгружаемого) в пользовательское адресное пространство. В этом случае прикладная программа и драйвер получат в свое распоряжение совместно используемую область памяти, что может быть полезно, например, при необходимости передачи большого объема данных от драйвера к приложению.
Секция используется для описания всего, что может быть отображено в память. Например, для каждого отображаемого в память файла создается объект-Секция. При этом, сколько бы не было открытий такого файла, объект-Секция всегда одна. Поскольку все исполняемые файлы загружаются посредством механизма отображения памяти, единственность объекта-секции всегда гарантирует наличие только одной копии такого файла в памяти.
При создании секции указывается режим доступа (чтение/запись/исполнение). Этот режим доступа будет влиять на записи в таблице страниц, относящиеся к секции.
Функции работы с секциями:
ZwOpenSection()
ZwMapViewOfSection()
ZwUnmapViewOfSection()
[4.6] Таблица описания памяти (Memory Descriptor List - mdl)
Диспетчер памяти использует структуру MDL для описания набора страниц физической памяти, составляющих буфер виртуальной памяти в контексте памяти некоторого процесса.. Интерпретация MDL не зависит от контекста памяти, поскольку MDL оперирует со страницами физической памяти. Получив для данного буфера описание в виде MDL, драйвер в дальнейшем может использовать буфер в контексте памяти любого процесса. Для того, чтобы обращаться к такой памяти, необходимо получить для MDL адрес памяти в системном адресном пространстве. Сделать это можно с помощью функции MmGetSystemAddressForMdl().
Кроме того, буфер, описанный с помощью MDL может быть использован для операций DMA. Для этого физический адрес внутри MDL должен быть транслирован в логический адрес (имеющий смысл только для данного устройства DMA) с помощью функции IoMapTransfer().
Интересно отметить следующий момент. MDL предназначен для описания буфера данных, непрерывного в виртуальной памяти. Однако страницы физической памяти, список которых собственно и содержит MDL, могут располагаться в памяти произвольным образом. Это дает возможность «собирать» непрерывный в виртуальной памяти буфер из различных фрагментов физической памяти без копирования памяти.
В основном, мы будем встречаться с MDL при передаче данных в драйвер посредством пакетов IRP (которые будут описаны в последующих лекциях).
[4.7] Подведение итогов. Функции работы с памятью
Из всего вышеизложенного нужно выделить основные моменты:
1) Все адресное пространство процесса (контекст памяти) делится на 2 области – системное адресное пространство (верхние 2 Гб) и пользовательское адресное пространство (нижние 2 Гб)
Системное адресное пространство всегда одинаково, вне зависимости от текущего контекста памяти
Пользовательское адресное пространство разное для каждого контекста памяти
2) Код пользовательского режима и режима ядра пользуется для доступа к памяти разными селекторами
для одного контекста памяти селекторы адресуют одну и ту же физическую память, но с разными режимами доступа.
Селекторы не имеют ничего общего с контекстом памяти
По селекторам для ядра можно получить доступ (по крайней мере для чтения) ко всему адресному пространству в данном контексте памяти, а по селекторам для ядра – только для пользовательской области памяти
3) Код в пользовательском адресном пространстве всегда вытесняемый, если не предприняты меры по созданию новой записи в каталоге страниц, указывающих на невытесняемую память.
4) Код, работающий на уровне IRQL >= DISPATCH_LEVEL, может использовать только невыгружаемую память (соответственно, сам код должен находиться в невыгружаемой памяти)
5) В ОС существуют функции для выполнения любой работы с памятью:
Выделение/освобождение памяти в выгружаемой/невыгружаемой, кешируемой/некешируемой памяти
Преобразование адресов памяти (виртуальный->физический, физический->виртуальный)
Проверка доступности памяти
Рассмотрим эти функции более подробно.