Библиотека Интернет Индустрии I2R.ru |
|||
|
Физические адреса в Win95(98)  Вы никогда не задумывались над тем, в каком именно мегабайте вашего компа выполняется ваша программа ? А в каком уютно разместился кернел ? Нет ? А мне вот стало интересно, и я решил узнать... Страничная адресация   Для начала немного теории.   Несколько слов о том, как процессоры 386+ осуществляют страничную адресацию. Информация взята из книги Е.Бердышева "Технология MMX. Возможности процессоров P5 и P6".   Пара определений. Физическим адресом назовем реальный номер байта в памяти. Линейным адресом назовем адреса, которые используют выполняющиеся программы.   Допустим, для доступа к сегменту данных в win32 приложении может встретиться такая инструкция:   mov byte ptr ds:[eax],2h   Как же процессор может вычислять физический адрес требуемой ячейки памяти ?   Если не используется страничная адресация, то процессор обратится к дескриптору памяти, задаваемому значением селектора в регистре ds, возьмет из него базовый адрес сегмента памяти, являющемся именно физическим адресом, прибавит к нему смещение, задаваемое регистром eax:   Физический адрес = база из дескриптора + eax.   Если включено страничное преобразование, то все происходит иначе. Рассмотрим случай размера страницы в 4 килобайта. Процессор выделяет из значения смещения в eax три части:   Номера битов смещения/Предназначение   22..31 Index in Page Directory   12..21 Index in Page Table   0..11 Index in Page   Взяв "Index in Page Directory", процессор обращается к так называемой "Page Directory" - каталогу страниц. Это область памяти с физическими адресами таблиц страниц. Физический адрес этого каталога находится в регистре CR3(только старшие 20 бит CR3 !), а число элементов нетрудно получить из количества бит, отводимых под индекс в каталоге - 10 бит дают 1024 элемента. Таким образом, сначала процессор извлекает элемент из каталога страниц:   Элемент каталога = [ CR3 + Index in Page Directory * 4 ],   который является(не совсем весь, только старшие 20 бит) физическим адресом начала одной из таблиц страниц. Таблицы страниц (Page Table) являются, в свою очередь, набором физических адресов(опять только старшие 20 бит) начала самих страниц в памяти. Для выборки конкретного элемента из Page Table процессор использует адрес ее начала (Элемент каталога) и "Index in Page Table" из смещения команды:   Адрес начала страницы = [ Элемент каталога + Index in Page Table * 4]   Окончательный физический адрес элемента памяти вычисляется по адресу начала страницы и индексу элемента страницы из смещения в команде:   Физический адрес = Адрес начала страницы + Index in Page. Схематично это можно представить таким образом: Смещение в команде ______________ [31..22] [21..12] [11..0] ------------>| Физ. адрес | | | ______________ | Page | | x 4 |- x 4 ->| Начало Page |->|______________| | ______________ | | | | | | Page Table | |->|Начало P.Table|->|______________| | | |Page Directory| CR3--->|______________| Управление страничной адресацией   Теперь подробнее о том, как задается страничная адресация.   За включение страничной адресации ответственнен бит PG(Paging Flag) (31 бит) регистра CR0 процессора. Если он 1, то страничное преобразование разрешено.   Тип страничной адресации задается битами PAE(Physical Address Extention) (5 бит), PSE(Page Size Extention) (4 бит) регистра CR4 процессора, а также битом PS(Page Size) (7 бит) в выбранном элементе Page Directory.   Следует отметить, что регистр CR4 доступен только в процессорах Pentium, и в общем случае необходимо проверять тип процессора командой CPUID и только затем - биты в регистре CR4.   Если бит PAE=1, то разрешен 36-ти разрядный физический адрес, иначе - "обычный" 32-х разрядный. Если бит PSE=0, то размер страницы 4 Килобайта, иначе - может быть 2 или 4 Мегабайта.   Экспериментально тип страничного преобразования можно проверить, например, так: Итак, если бит PG=1, а биты PSE=PAE=0, то у нас "обычное" страничное преобразование с 4-х киобайтным размером страницы и 32-х битным адресом..586p ; Pentium Processor PG equ 1 shl 31 PAE equ 1 shl 5 PSE equ 1 shl 4 ; ... mov eax,CR0 test eax,PG jz @@NoPageRegim mov eax,CR4 test eax,PAE jnz @@PhysAddr_36bit ; ... @@PhysAddr_36bit: ; ... @@NoPageRegim:   Значения этих битов в windows98 показывают, что эта ОС использует как раз именно такой тип страничного преобразования. Как получить физический адрес по линейному адресу   Решим следующую небольшую задачку: напишем процедуру, которая будет возвращать win32-приложению по заданному линейному адресу физический адрес.   Код процедруры разместим в динамическом VxD, поскольку для его реализации необходимо использование привелигерованных инструкций типа "mov eax,CR0", недопустимых в win32-коде. Подробнее о написании динамических VxD можно прочесть, например, в "tutorials by iczelion", размещенных на сайте HI-TECH.   Условимся также пропустить проверки на тип страничного преобразования, считая, что windows98 использует 4-х килобайтные страницы и 32-х разрядный физический адрес.   Итак, начнем. Сначала - стандартное начало динамического VxD: ; Программа чтения физического адреса по линейному. ; Этот динамический VxD можно загружать через DeviceIOControl и получать ; по указателю физический адрес по линейному адресу. ; Coded by Chingachguk. 2002. ; .386p include vmm.inc include vwin32.inc DECLARE_VIRTUAL_DEVICE PHY,1,0, PHY_Control,\ UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER Begin_control_dispatch PHY Control_Dispatch w32_DeviceIoControl, OnDeviceIoControl End_control_dispatch PHY   Определимся с передачей параметров и получением результатов нашего кода. Будем передавать VxD адрес следующей структуры: ; Структура параметров при вызове CallParams struc LinearAddr dd ? ; Линейный адрес PhysAddr dd ? ; Сюда вернуть физический адрес CallParams ends   Определим в сегменте данных одну переменную - флаг ошибки: ; Сегмент данных нашего VxD VxD_PAGEABLE_DATA_SEG Result dd ? ; Если будет ошибка, мы будем хранит тут 0FFFFFFFFh (-1). VxD_PAGEABLE_DATA_ENDS   Алгоритм вычисления физического адреса понятен. Остается решить один важный вопрос: как же обращаться к памяти, если у нас есть физический адрес, а мы находимся в режиме страничного преобразования ? Например, мы получили физический адрес элемента в Page Directory(например, сейчас он в eax), но команда вида:   mov eax,[eax]   совсем не приведет к чтению элемента каталога страниц, поскольку процессор будет трактовать значение в eax согласно страничному преобразованию !   Разумным решением было бы вызвать сервис другого VxD, например VMM, с целью получить физический адрес по линейному (в этом случае нам вообще делать будет нечего, даже не надо читать никаких Page Directory, Page Table...). Однако такого сервиса не существует(DDK) ! С другой стороны, существует сервис получения линейного адреса по физическому у VMM. Необходимость его существования следует из необходимости некоторым драйверам адресоваться к конкретной физической памяти, например при работе с BIOS и т.д.:   Get linear address by physical address(DDK)   VMMCall _MapPhysToLinear,   Таким образом, нам придется вызывать данный сервис всякий раз, когда
потребуется по физическому адресу извлечь из памяти значение.
  А вот наш сегмент кода:
  Для примера приведен фрагмент вызова такого VxD из win32-кода:
Пример трансляции линейных адресов
  Для примера привожу трансляцию нескольких характерных
линейных адресов в физические под windows98, компьютер с 16 Мегабайт памяти:
Итого
  Таким образом, единственный необходимый сервис ОС для получения
физического адреса по линейному - это сервис "Получить линейный адрес по
физическому". Очевидно, аналогичные сервисы существуют не только windows98(95),
а и windows NT и ее наследниках - windows2000 и т.д, что позволит переносить
приведенный выше код без особых изменений на эти платформы, используя
соответствующие модели драйверов(*.wdm).
  Знание настоящего положения программ в памяти, на мой взгляд, не
только любопытно, но и позволяет глубже понять стратегию размещения программ
ОС и делать грубые оценки ее работы и эффективности. Например, оказывается
что windows98 использует наиболее простой тип страничного преобразования в
случае размера памяти компьютера 16 МБайт, в то время как технологии позволяют
использовать еще несколько режимов с большими размерами страниц или же смешанным
размером страниц. Было бы интересно оценить поведение этой ОС в случае
существенного увеличения размера памяти, ведь в наше время не такая уж экзотика
компьютер с 128 МБайт памяти и более, а также используемые типы страничного
преобразования в новых версиях windows.
Chingachguk /HI-TECH |
|
2000-2008 г. Все авторские права соблюдены. |
|