Работа с Таблицей Страниц в Linux

Типы pte t, pmd t, pud t и pgd t описывают формат записи Таблицы Страниц, среднего каталога страниц, верхнего каталога страниц и глобального каталога страниц соответственно. Они представляют собой 64-битовые типы данных при включенном механизме РАЕ и 32-битовые при выключенном. Тип pgprot t является 64-битовым (механизм РАЕ включен) или 32-битовым (механизм РАЕ выключен) и представляет флаги, ассоциированные с одной записью.
Пять макросов преобразования типа, pte, _pmd, pud, pgd и pgprot, переводят целое без знака в требуемый тип. Пять других макросов, pte vai, pmd vai, pud vai, pgd vai и pgprot vai, выполняют обратное преобразование из упомянутых специализированных типов в целое без знака.
Ядро также предоставляет ряд макросов и функций для чтения и модификации записей таблицы страниц:
— макросы pte_none, pmd_none, pud_none и pgd_none — возвращают, если соответствующая запись содержит нули, и 0 в противном случае;
— макросы pte_clear, pmd_clear, pud_clear и pgd_clear — очищают запись соответствующей таблицы страниц, тем самым запрещая процессу использовать линейные адреса, отображаемые этой записью. Функция ptep get and ciear () очищает запись Таблицы Страниц и возвращает предыдущее значение;
— макросы set pte, set pmd, set pud и set pgd — записывают заданное значение в таблицу страниц. Макрос set pte atomic идентичен макросу set pte, но при включенном механизме рае он гарантирует, что 64-битовое значение будет записано атомарным образом;
— функция pte_same(а,Ь) — возвращает 1, если две записи Таблицы Страниц, ссылаются на одну и ту же страницу и задают одинаковые привилегии. В противном случае возвращается 0;
— функция pmd iarge(e) — возвращает 1, если запись е среднего каталога страниц ссылается на страницу большого размера (2 или 4 Мбайт). В противном случае возвращается 0.
— макрос pmdjoad используется в различных функциях для проверки корректности записей среднего каталога страниц, передаваемых в качестве параметров. Он возвращает 1, если запись указывает на недопустимую Таблицу Страниц, т. е. если имеет место хотя бы одно из следующих условий:
— страница отсутствует в основной памяти (флаг Present сброшен);
— разрешено только чтение страницы (флаг Read/write сброшен);
— сброшен либо флаг Accessed, либо флаг Dirty (Linux принудительно устанавливает эти флаги для каждой имеющейся Таблицы Страниц).
Макросы pudjoad и pgdjoad всегда возвращают 0. Макроса ptejoad не существует, потому что вполне допустимо, чтобы запись Таблицы Страниц ссылалась на страницу, отсутствующую в основной памяти, не доступную для записи, или вообще недоступную.
Макрос pte present возвращает 1, если либо флаг Present, либо флаг Page size в записи Таблицы Страниц равняется 1. В противном случае макрос возвращает 0. Вспомним, что флаг Page size в записи Таблицы Страниц не несет никакого смысла для блока управления страницами микропроцессора. Тем не менее, ядро сбрасывает флаг Present и устанавливает флаг Page size для страниц, присутствующих в памяти, но без привилегий на чтение, запись или выполнение. Таким образом, любое обращение к этим страницам провоцирует исключение ошибка обращения к странице”, поскольку флаг Present сброшен, но ядро, проверив флаг Page Size, может распознать, что ошибка возникла не из-за отсутствия страницы.
Макрос pmd present возвращает, если флаг Present соответствующей записи установлен, т. е. если соответствующая страница или Таблица Страниц загружена в оперативную память. Макросы pud present и pgd present всегда возвращают.