Регионы в адресном пространстве.
4 Гб адресное пространство выделяется процессу в момент создания и является практически свободным, незарезервированным. Для того, чтобы воспользоваться адресным пространством нужно выделить регион, обратившись к функции VirtualAlloc(...). Эта функция выделяет регион в адресном пространстве. Надо указать начальный адрес выделяемого региона и его размер. Для чего нужны регионы в адресном пространстве?
- чтобы разместить программный код
- чтобы разместить различные системные структуры
- чтобы разместить структуры данных загружаемого процесса и так далее.
При выделении регионов в ОС учитываются гранулярность выделения ресурсов, другими словами, начало региона должно быть выделено по определенной границе (64 Кб). При выделении региона размер региона всегда кратен размеру страницы. Иногда ОС сама резервирует некоторые регионы адресного пространства в интересах конкретного процесса. Например, для хранения блока окружения процесса.
Передача физической памяти региону.
Чтобы получить возможность практического использования зарезервированного региона адресного пространства, необходимо выделить физическую область, а затем увязать ее с регионом. Физическая память всегда выделяется в страничном файле, а не в оперативной памяти, то есть загрузка страниц в ОЗУ - это функции ОС.
VirtualAlloc(..., Mem_Commit) - для выделения региона - это ключ. При передаче физ. памяти региону, не обязательно отводить её целому региону. Например, регион 64 Кб можно зарезервировать, а память передать только 2 и 4 странице. Например:
200×250×128=...
Физическая память выделяется только тем клеткам, которые будут использоваться. Экономия реальной физической памяти.
Механизм выделения страниц физической памяти.
СФ – страничный файл.
Если данные в страничном файле есть. LIFO.
LRU - менеджер виртуальной памяти отмечает и выгружается та страница, к которой наиболее длительное время не было обращения. В основном используется именно этот алгоритм. Каждый процесс может заблокировать страницу в оперативной памяти. Для блокирования страниц используется функция VirtualLock(...). Причем, для того, чтобы какой-либо процесс не приобрел приоритет количество страниц ограничивается тридцати двумя. Блокировка действует только на время работы данного процесса.
Выделение физической памяти под программный код.
Физическая память выделяется в страничном файле. При запуске приложения ОС открывает его исполняемый файл и определяет объем кода и данных приложения. ОС резервирует регион адресного пространства и помечает, что физическая память, связанная с этим регионом – это сам исполнительный (ехе) файл. ОС не выделяет пространство из страничного файла, а использует истинное содержимое исполнительного (ехе) файла, как зарезервированный регион адресного пространства. Программный файл, размещённый на жестком диске и используемый как физическая память для того или иного региона адресного пространства, называется файлом, проецируемым в память. Windows резервирует регион. Файлы Windows готовы к "употреблению", в DOS необходимы заголовки.
7. Атрибуты защиты страниц памяти в Win32. Изменение атрибутов защиты.
Атрибуты защиты страниц.
Отдельные страницы имеют различные атрибуты защиты:
1) PAGE_NOACCESS. Попытка чтения, записи, исполнения в этом регионе памяти вызовет нарушение доступа.
2) PAGE_READONLY. Попытка записи, исполнения в этом регионе памяти вызовет нарушение доступа.
3) PAGE_READWRITE. Попытка исполнения в этом регионе памяти вызовет нарушение доступа.
4) PAGE_EXECUTE. Попытка чтения, записи в этом регионе памяти вызовет нарушение доступа.
5) PAGE_EXECUTE_READWRITE. Данный регион допускает любые операции.
6) PAGE_EXECUTE_READ. Попытка записи в этом регионе памяти вызовет нарушение доступа.
7) PAGE_WRITECOPY. Попытка исполнения в этом регионе памяти вызовет нарушение доступа. Запись в память этого региона приводит к тому, что процессу предоставляется личная копия данной страницы физической памяти.
8) PAGE_EXECUTE_WRITECOPY. Данный регион допускает любые операции.
В Windows 95 используются 1,2 и 3 атрибуты защиты. Кроме рассмотренных атрибутов защиты существуют два флага: PAGE_NOCACHE – отключает кэширование выделенной страницы. Использовать его не рекомендуется. В основном используется этот флаг разработчиками драйверов; PAGE_GUARD – специальный флаг. Используется при работе стека потока. Windows 95 эти флаги игнорирует. Флаги защиты можно объединять, используя логическую операцию OR. Для изменения атрибутов используется функция VirtualProtect(...).
Виртуальное адресное пространство ////////////////////////////////////////////////// |
////////////////////////////////////////////// |
Программный код или данные |
1-я копия Физическая память 2-я копия
Чтобы предотвратить одновременную запись в общий блок данных разными процессами ОС присваивает этому блоку данных атрибут защиты копирования при записи. Когда поток в одном процессе пытается записать что-нибудь в общий блок данных, то он
1) выделяет из страничного файла страницу физической памяти
2) отыскивает свободную страницу в памяти
3) копирует страницу с данными, которые поток пытается записать в общий блок на свободную страницу памяти, полученную на этапе 2
4) сопоставляет адрес этой страницы виртуальной памяти с новой страницей в памяти.
После этих действий ОС получает собственную копию этого блока данных и может делать с ней, что хочет. Windows 95 и Windows 98 не поддерживают копирование рпи записи.
8. Стек потока под управлением Windows NT (2000).
ОС сама резервирует место в виртуальном адресном пространстве регион для размещения стека потока.
Глобальные переменные хранятся в специальном сегменте, а локальные в стеке.
программный сегмент сегмент данных |
Рассмотрим стек Windows NT, 2000. Под стек по умолчанию выделяется регион размером 1 Мб и передаются две страницы физической памяти. Значения устанавливаемые по умолчанию можно изменять в программе. Размер физической памяти можно менять при вызове функции CreateThread(…). Так выглядит стек при создании:
080FF000
Страница физической памяти | PAGE_READWRITE Страница физической памяти c флагом | PAGE_GUARD Зарезервированная страница | | … Зарезервированная страница | … | Программный код |
Указатель стека устанавливается в верхней части стека. Физическая память выделена двум страницам.
Вторая страница имеет флаг запрещения доступа.
По мере создания различных локальных переменных стек разрастается, по мере его заполнения происходит переход во вторую страницу. Но эта страница защищена. ОС будет извещена о попытке записи на защищенную страницу и обрабатывает её следующим образом: снимает флаг запрещения записи со второй старницы. Выделяет стеку третью страницу физической памяти и присваивает третьей странице атрибуты PAGE_READWRITE и флаг PAGE_GUARD.
Рассмотрим ситуацию, когда стек потока фактически заполнен.
//////////////////////////// PAGE_GUARD 3арезервированная страница Зарезервированная страница |
Флаг PAGE_GUARD снимается и физическая память выделяется следующей странице.
Физическая
память
После этого ОС формирует исключение, то есть информирует процесс о Stack Overflow. В этом случае процесс должен среагировать, если этого не произойдёт, то производится попытка записи на зарезервированную страницу, то есть когда это происходит, то ОС берёт управление на себя и завершает не только данный поток, а и весь процесс. В этом случае ОС даже не извещает пользова-теля. Процесс исчезает бесследно.
Почему нижняя страница стека всегда остаётся зарезервированной?
1. Для того, чтобы защитить стек от перезаписи.
Стек Зарезервированная страница Данные |
память
Физическая
память
2. Для защиты программ и данных при переполнении стека. Например,
Стек Пароли |
память
Стираем пароли и получаем доступ к сети.