Для изучения PTE используйте команду !pte отладчика ядра (см. эксперимент «Трансляция адресов» далее в этой главе). Действительные PTE (здесь мы обсуждаем именно их — о недействительных PTE см. далее) состоят из двух основных полей (рис. 7-19): поля PFN физической страницы с данными (или физического адреса страницы в памяти) и поля флагов, описывающих состояние и атрибуты защиты страницы.
Как вы еще увидите, битовые флаги, помеченные как зарезервированные рис. 7-19), используются, только если PTE недействителен (флаги интерпретируются программно). Аппаратно определяемые битовые флаги действительного PTE перечислены в таблице 7-11.
B х86-системах аппаратный PTE содержит биты Dirty и Accessed. Бит Accessed равен 0, если данные физической страницы, представляемой РТЕ, не были считаны или записаны. Процессор устанавливает этот бит при первой операции чтения или записи страницы. Бит Dirty устанавливается только после первой записи на страницу. Кроме того, бит Write обеспечивает защиту страницы: если он сброшен, страница доступна только для чтения, а если он установлен, страница доступна как для чтения, так и для записи. Когда поток пытается что-то записать на страницу со сброшенным битом Write, возникает исключение управления памятью, и обработчик, принадлежащий диспетчеру памяти, решает, может ли поток записывать данные на эту страницу (если она, например, помечена как копируемая при записи) или следует сгенерировать нарушение доступа.
Для аппаратных PTE в многопроцессорных х86-системах предусматривается дополнительный бит Write, реализуемый программно и предотвращающий остановку системы при сбросе кэша PTE (также называемого ассоциативным буфером трансляции). Этот бит указывает, что страница была модифицирована другим процессором.
Адрес байта в пределах страницы
Как только диспетчер памяти находит искомую страницу, он переходит к поиску нужных данных на этой странице. Ha этом этапе используется поле индекса байта. Оно сообщает процессору, к какому байту данных на этой странице вы хотите обратиться. B х86-системах этот индекс состоит из 12 битов, что позволяет адресоваться максимум к 4096 байтам данных. Таким образом, добавление смещения байта к PFN, извлеченному из РТЕ, завершает трансляцию виртуального адреса в физический.
ЭКСПЕРИМЕНТ: трансляция адресов
Чтобы получше разобраться в том, как транслируются адреса, рассмотрим реальный пример трансляции виртуального адреса в х86-систе-ме без поддержки PAE и с помощью отладчика ядра исследуем каталоги страниц, таблицы страниц и PTE. B этом примере мы используем процесс с виртуальным адресом 0x50001, спроецированным на действительный физический адрес. Как наблюдать за трансляцией недействительных адресов, мы поясним в последующих примерах.
Сначала преобразуем 0x50001 в двоичное значение и разобьем его на три поля, используемых при трансляции адреса. B двоичной системе счисления 0x50001 соответствует значению 101.0000.0000.0000.0001, а его поля выглядят так:
Чтобы начать трансляцию, процессор должен знать физический адрес каталога страниц, который хранится в регистре CR3, пока выполняется поток соответствующего процесса. Этот адрес можно получить как из регистра CR3, так и из дампа блока KPROCESS интересующего вас процесса с помощью команды !process отладчика ядра.
B данном случае физический адрес каталога страниц — 0xl2F0000. Как видно на иллюстрации, поле индекса каталога страниц в этом примере равно 0. Поэтому физический адрес PDE — 0x12F0000.
Команда !pte отладчика ядра выводит PDE и РТЕ, описывающие виртуальный адрес:
B первой колонке отладчик ядра сообщает PDE 5а во второй — РТЕ. Заметьте, что показывается виртуальный адрес PDE, а не физический. Как уже говорилось, каталог страниц процесса в х86-системах начинается с виртуального адреса 0xC0300000. Поскольку мы изучаем первый PDE каталога страниц, его адрес совпадает с адресом самого каталога.
Читать дальше
Конец ознакомительного отрывка
Купить книгу