Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Раздел для кода и данных режима ядра (Windows2000 и Windows98) ⇐ ПредыдущаяСтр 2 из 2
В этот раздел помещается код операционной системы, в том числе драйверы устройств и код низкоуровневого управления потоками, памятью, файловой системой, сетевой поддержкой. Все, что находится здесь, доступно любому процессу. В Windows 2000 эти компоненты полностью защищены. Поток, который попытается обратиться по одному из адресов памяти в этом разделе, вызовет нарушение доступа, а это приведет к тому, что система в конечном счете просто закроет его приложение. В 64-разрядной Windows 2000 раздел пользовательского режима (4 Тб) выглядит непропорционально малым по сравнению с 16 777 212 Тб, отведенными под раздел для кода и данных режима ядра. Дело не в том, что ядру так уж необходимо все это виртуальное пространство, а просто 64-разрядное адресное пространство настолько огромно, что его большая часть не задействована Система разрешает нашим программам использовать 4 Тб, а ядру — столько, сколько ему нужно. К счастью, какие-либо внутренние структуры данных для управления незадействованными частями раздела для кода и данных режима ядра не требуются. В Windows 98 данные, размещенные в этом разделе не защищены — любое приложение может что-то считать или записать в нем и нарушить нормальную работу операционной системы. №19 Резервирование региона памяти Адресное пространство, выделяемое процессу в момент создания, практически все свободно (незарезервировано). Поэтому, чтобы воспользоваться какой-нибудь его частью, нужно выделить в нем определенные регионы через функцию VirtualAlloc. При резервировании система обязательно выравнивает начало региона с учетом так называемой гранулярности выделения памяти (allocation granularity). Последняя величина в принципе зависит от типа процессора, но для процессоров х86, 32-и 64-разрядных Alpha и IA-64 она одинакова и составляет 64 Кб.Резервируя регион в адресном пространстве, система обеспечивает еще и кратность размера региона размеру страницы. Так называется единица объема памяти, используемая системой при управлении памятью. Как и гранулярность выделения ресурсов, размер страницы зависит от типа процессора. В частности, для процессоров х86 он равен 4 Кб, а для Alpha (под управлением как 32-разрядной, так и 64-разрядной Windows 2000) — 8 Кб. Иногда система сама резервирует некоторые регионы адресного пространства в интересах Вашего процесса, например, для хранения блока переменных окружения процесса (process environment block, РЕВ). Этот блок — небольшая структура данных, создаваемая, контролируемая и разрушаемая исключительно операционной системой. Выделение региона под РЕВ-блок осуществляется в момент создания процесса. Кроме того, для управления потоками, существующими на данный момент в процессе, система создает блоки переменных окружения потоков (thread environment blocks, TEBs). Регионы под эти блоки резервируются и освобождаются по мере создания и разрушения потоков в процессе. Если Вы попытаетесь зарезервировать регион размером 10 Кб, система автоматически округлит заданное значение до большей кратной величины. А это значит, что на х86 будет выделен регион размером 12 Кб, а на Alpha — 16 Кб. Когда зарезервированный регион адресного пространства становится не нужен, его следует вернуть в общие ресурсы системы. Эта операция — освобождение (releasing) региона — осуществляется вызовом функции VirtualFree. Резервирование региона в адресном пространстве Для этого предназначена функция VirtualAlloc: PVOID VirtualAlloc ( PVOID pvAddress, SIZE_T dwSize, DWORD fdwAllocationType, DWORD fdwProtect); В первом параметре, pvAddress, содержится адрес памяти, указывающий, где именно система должна зарезервировать адресное пространство. Обычно в этом, параметре передают NULL, тем самым сообщая функции VirtualAlloc, что система, ведущая учет свободных областей, должна зарезервировать регион там, где по ее мнению, будет лучше. Поэтому нет никаких гарантий, что система станет резервировать регионы, начиная с нижних адресов или, наоборот, с верхних. Однако с помощью флага МЕМ_ TOP_DOWN Вы можете сказать свое веское слово. Пример можно убрать Допустим, нужно выделить регион, начиная с “отметки” 50 Мб в адресном пространстве процесса. Тогда параметр pvAddress должен быть равен 52 428 800 (50 х 1024 х 1024). Если по этому адресу можно разместить регион требуемого размера, система зарезервирует его и вернет соответствующий адрес. Если же по этому адресу свободного пространства недостаточно или просто нет, система не удовлетворит запрос, и функция VirtuaIAlloc вернет NULL. Адрес, передаваемый в pvAddress, должен укладываться в границы раздела пользовательского режима процесса, так как иначе VirtualAlloc вернет NULL. Регионы всегда резервируются с учетом гранулярности выделения памяти (64 Кб для существующих реализаций Windows). Поэтому, если Вы попытаетесь зарезервировать регион по адресу 19 668 992 (300 х 65 536 + 8192), система округлит этот адрес до ближайшего меньшего числа, кратного 64 Кб, и на самом деле зарезервирует регион по адресу 19 660 800 (300 х 65 536). Если VirtualAlloc в состоянии удовлетворить запрос, она возвращает базовый адрес зарезервированного региона. Если параметр pvAddress содержал конкретный адрес, функция возвращает этот адрес, округленный при необходимости до меньшей величины, кратной 64 Кб. Второй параметр функции VirtualAlloc -— dwSize — указывает размер резервируемого региона в байтах. Поскольку система резервирует регионы только порциями, кратными размеру страницы, используемой данным процессором, то попытка зарезервировать скажем, 62 Кб даст регион размером 64 Кб. Третий параметр, fdwAllocationType, сообщает системе, что именно Вы хотите сделать: зарезервировать регион или передать физическую память. Поэтому, чтобы зарезервировать регион адресного пространства, в этом параметре нужно передать идентификатор MEM_RESERVE. Если Вы хотите зарезервировать регион и не собираетесь освобождать его в ближайшее время, попробуйте выделить его в диапазоне самых старших — насколько это возможно — адресов. Тогда регион не окажется где-нибудь в середине адресного пространства процесса, что позволит не допустить вполне вероятной фрагментации этого пространства. Чтобы зарезервировать регион по самым старшим адресам, при вызове функции VirtualAlloc в параметре pvAddress передайте NULL, а в параметре fdwAllocationType — флаг MEM_RESERVE, скомбинированный с флагом MEM_TOP_DOWN. В Windows 98 флаг MEM_TOP_DOWN игнорируется. Последний параметр, fdwProtect, указывает атрибут защиты, присваиваемый региону. Заметьте, что атрибут защиты, связанный с регионом, не влияет на переданную память, отображаемую на этот регион. Но если ему не передана физическая память, то — какой бы атрибут защиты у него ни был — любая попытка обращения по одному из адресов в этом диапазоне приведет к нарушению доступа для данного потока. Резервируя регион, присваивайте ему тот атрибут защиты, который будет чаще всего использоваться с памятью, передаваемой региону. Скажем, если Вы собираетесь передать региону физическую память с атрибутом защиты PAGE_READWRITE (этот атрибут самый распространенный), то и резервировать его следует с тем же атрибутом. Система работает эффективнее, когда атрибут защиты региона совпадает с атрибутом защиты передаваемой памяти. Вы можете использовать любой из следующих атрибутов защиты: PAGE_NOACCESS, PAGE_READWRITE, PAGE_READONLY, PAGE_EXECUTE, PAGE_EXECUTE_READ или PAGE_ EXECUTE_READWRITE. Но указывать атрибуты PAGE_WRITECOPY или PAGE_EXECUTE_ WRITECOPY нельзя: иначе функция VirtualAlloc не зарезервирует регион и вернет NULL. Кроме того, при резервировании региона флаги PAGE_GUARD, PAGE_WRITECOMBINE или PAGE_NOCACHE применять тоже нельзя — они присваиваются только передаваемой памяти. Windows 98 поддерживает лишь атрибуты защиты PAGE_NOACCESS, PAGE_READ-ONLY и PAGE_READWRITE. Попытка резервирования региона с атрибутом PAGE_EXECUTE или PAGE_EXECUTE_READ дает регион с атрибутом PAGE_READONLY. А указав PAGE_EXECUTE_READWRITE, Вы получите регион с атрибутом PAGE_READWRITE. |
Последнее изменение этой страницы: 2019-04-09; Просмотров: 194; Нарушение авторского права страницы