Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Страницы в этом регионе доступны для чтения
Страницы в этом регионе доступны для записи Страницы в этом регионе могут быть выполнены Страницы в этом регионе могут быть доступны сразу для нескольких процессов Линейные адреса добавляются начиная с нижнего Линейные адреса добавляются начиная с верхнего Запись на страницы запрещена Страницы в этом регионе состоят из исполнимого кода Страницы блокированы Страницы нельзя скопировать Эта виртуальная область памяти не может быть расширена а.В оригинальном тексте опечатка - должно быть VM_DONTEXPAND. Примеч. науч. ред. Размещение образа процесса и линейное адресное пространство 219 4.7.2.5 vm_rb vm_rb хранит узел красно-черного дерева, связанного с областью памяти. 4.7.2.6 vm_ops vm_ops состоит из структуры указателей функций, обрабатывающих отдельные vm_area_struct. Эти функции включают открытие области памяти, закрытие и отмену отображения. Кроме этого, указатель функции на функцию вызывается каждый раз, когда возникает исключение об отсутствии страницы. Размещение образа процесса и линейное адресное пространство Когда в память загружается программа пользовательского пространства, она получает линейное адресное пространство, разделенное на области памяти (memory_areas), или сегменты. Эти сегменты выполняют различные функции при выполнении процесса. Функционально разделенные сегменты отображаются в адресное пространство процесса. С выполнением процесса связано 6 главных сегментов. • TeKCT(text). Этот сегмент, также известный как сегмент кода, хранит исполнимые инструкции программы. Поэтому он обычно имеет атрибуты execute и read. В случае, когда из одной программы может быть загружено много процессов, загружать одни и те же инструкции несколько раз слишком расточительно. Linux позволяет нескольким процессам разделять в памяти текстовые сегменты. Поля start_code и end_code структуры mm_struct хранят адреса начала и конца текстового сегмента. • Данные(сШа). Этот сегмент хранит все инициализированные данные. Инициализированные данные включают статически выделенные и глобальные инициализированные данные. Следующий фрагмент кода демонстрирует пример инициализированных данных. example.с int gvar = 10; int main(){ } • gvar. Глобальная переменная, которая инициализируется и хранится в сегменте данных. Эта секция имеет атрибуты чтения-записи, но не может быть разделена между несколькими процессами, выполняющими одну и ту же программу. Поля Глава 4 • Управление памятью start_data и end_data структуры mm_struct хранят адреса начала и конца сегмента данных. • BSS. Эта секция хранит неинициализированные данные. Эти данные состоят из глобальных переменных, инициализируемых в 0 при запуске программы. Также эта секция называется секцией инициализируемых нулем данных. Следующий фрагмент кода демонстрирует неинициализируемые данные. example2.с int gvarl[10]; long gvar2; int main(){ } Объекты в этой секции имеют только атрибуты name и size. • Куча (Heap). Используется для наращивания линейного адресного пространства процесса. Когда программа использует mall ос () для динамического получения памяти, эта память выделяется из кучи. Поля start_brk и brk структуры mm_struct хранят адреса начала и конца кучи. При вызове mall ос () для динамического получения памяти вызов системного вызова sys_brk () перемещает указатель brk на новую позицию, увеличивая при этом кучу. • Стек (Stack). Хранит все выделяемые локальные переменные. Когда вызываются функции, локальные переменные для этих функций помещаются в стек. Как только функции завершаются, связанные с ними переменные извлекаются из стека. Остальная информация, включая адреса возврата и параметры, также размещается в стеке. Поле start_stack структуры mm_struct помечает начальный адрес стека процесса. Несмотря на то что с выполняемым процессом связано 6 сегментов, они отображаются только в 3 области памяти адресного пространства. Эти области памяти называются text, data и stack. Сегмент data включает инициализированный выполняемый сегмент data, bss и кучу. Сегмент text включает исполнимый сегмент text. Рис. 4.11 показывает, как выглядит линейное адресное пространство и как mm_struct следит за этими сегментами. Различные области памяти отображаются в файловую систему /ргос. К отображенной для процесса памяти можно получить доступ через вывод /ргос/< pid> /maps. Теперь рассмотрим пример программы и посмотрим список адресов памяти в адресном пространстве процесса. Код в example3.с показывает отображенную в память программу. Размещение образа процесса и линейное адресное пространство
Рис. 4.11. Адресное пространство процесса example3.с #include < stdio.h> int main(){ while(1); return(O); } Вывод /proc/< pid> /maps для этого примера содержит то, что представлено на рис. 4.12. Глава 4 • Управление памятью
Рис. 4.12. /prod< pid> /maps Самая левая колонка показывает диапазон сегментов памяти. Это начальные и конечные адреса отдельных сегментов. Следующая колонка показывает разрешение на доступ к этим сегментам. Эти флаги похожи на разрешения доступа к файлам: г означает чтение, w - запись, а х - возможность выполнения. Последним флагом может быть р, обозначающее частный (private) сегмент, или s, означающее разделяемый (shared) сегмент. (Частный сегмент не обязательно неразделяемый.); р указывает, что текущий сегмент не был разделен. Следующая колонка содержит отступ для сегмента. Четвертая колонка слева хранит два числа, разделенные двоеточием. Она означают максимальное и минимальное число файлов файловой системы, связанных с данным сегментом. (Некоторые сегменты не имеют ассоциированных с ними файлов, и для них эти значения будут равны 00: 00.) Пятая колонка хранит inode файла, а самая правая колонка- имя файла. Для сегментов без имен файлов эта колонка остается пустой, а колонка inode равна 0. В нашем примере первая строка содержит описание текстового сегмента нашей программы. Здесь можно увидеть устанавливаемые для исполнимых файлов флаги разрешений. Следующая колонка описывает сегмент данных нашей программы. Обратите внимание, что разрешения этой секции включают возможность записи. Наша программа связывается динамически, что означает, что используемые ей функции принадлежат к загружаемой во время ее выполнения библиотеке. Эти функции необходимо отобразить в адресное пространство, чтобы к ним можно было получить доступ. Следующие 6 строк работают с динамически загружаемыми библиотеками. Следующие 3 строчки описывают text, data и bss библиотеки Id. За этими тремя строчками следует описание секций библиотеки test, data и bss в том же порядке. Последняя строчка обладает разрешением на чтение, запись и выполнение, представляет стек процесса и расширяется до 0х0С0000000, т. е. до наибольшего адреса в памяти, доступного для процесса из пользовательского пространства. Таблицы страниц Таблицы страниц Память программы удобно представлять с помощью виртуальных адресов. Единственная возникающая проблема связана с тем, что, когда инструкции используются процессором, он ничего не может сделать с виртуальным адресом. Процессор оперирует физическими адресами. Связь между виртуальным и соответствующим ему физическим адресом обеспечивается ядром (с помощью аппаратного обеспечения) в таблицах страниц. Таблицы страниц следят за памятью в элементах фреймов страниц. Они хранятся в оперативной памяти в течение всей жизни ядра. Linux использует так называемую трехуровневую схему подкачки. Трехуровневая подкачка необходима для того, чтобы даже 64-битовая архитектура смогла отобразить в виртуальную память все свои физические адреса. Как следует из названия схемы, трехуровневая система подкачки имеет 3 типа таблиц подкачки: таблицы верхнего уровня, называемые глобальной директорией страниц (Page Global Directory) (PGD), представляемой с помощью типа данных pgd_t; таблицы средней директории страниц (Page Middle Directory, PMD), представляемой с помощью типа данных pmd_t, и таблицы страницы (Page Table, РТЕ), представляемая в виде типа данных pte__t. Таблицы страниц изображены на рис. 4.13.
Рис. 4.13. Таблицы страниц в Linux PGD хранит вхождения, связанные с PMD. PMD хранит вхождения, связанные с РТЕ, а РТЕ хранит вхождения ссылок на отдельные страницы. Каждая страница обладает собственным набором таблиц страниц. Поле mm_strue t-> pgd хранит указатель на PGD процесса; 32- и 654-битовые виртуальные адреса разделяются (в зависимости от архитектуры) на поля отступа различного размера. Каждому полю соответствует отступ в PGD, PMD, РТЕ и в самой странице. Глава 4 • Управление памятью Ошибка страницы На протяжении жизни процесса он может попытаться получить доступ к адресам, которые принадлежат адресному пространству, но не загружены в оперативную память. Вместо этого он может попытаться получить доступ к странице памяти, для которой у него нет разрешения на доступ (например, может попытаться произвести запись в область только для чтения). Когда это происходит, система генерирует ошибку страницы (page fault). Ошибка страницы - это обработчик исключения, обрабатывающий ошибки доступа программы к странице. Когда аппаратное обеспечение порождает исключение ошибки страницы, перехватываемое ядром, страница достается из хранилища. После этого ядро выделяет недостающую страницу. На каждой архитектуре есть своя архитектурно-зависимая функция для обработки ошибки страницы. На х86 и РРС вызывается функция do__page_f ault (). Обработчик ошибки страницы х86 do_page__f ault (*regs, error_code) находится в /arch/ i3 8 6/mm/fault, с. Обработчик ошибки памяти PowerPC do_page_fault (*regs, address, error__code) находится в /arch/ppc/mm/fault. с. Они настолько похожи, что для того, чтобы понять функционирование версии для PowerPC, нам будет достаточно рассмотреть только вариант do_page__f ault () для х86. Основная разница в обработке ошибки страницы этими двумя архитектурами проявляется на этапе сбора и сохранения информации об ошибке, предшествующем вызову do_page__f ault (). Для начала рассмотрим особенности обработки ошибки страницы на х86, а затем перейдем к функции do_page_fault (). После этого мы рассмотрим отличия версии для PowerPC. Популярное:
|
Последнее изменение этой страницы: 2016-03-25; Просмотров: 969; Нарушение авторского права страницы