Шрифт:
Когда процесс запланирован на выполнение, то загружается адресное пространство, на которое указывает поле
mm
этого процесса. Поле active
_mm дескриптора процесса обновляется таким образом, чтобы указывать на новое адресное пространство. Потоки ядра не имеют своего адресного пространства, поэтому значение поля mm для них равно NULL
. Поэтому, когда поток ядра планируется на выполнение, ядро определяет, что значение ноля mm
равно NULL
, и оставляет загруженным предыдущее адресное пространство. После этого ядро обновляет поле active_mm
дескриптора процесса для потока ядра, чтобы он указывал на дескриптор памяти предыдущего процесса. При необходимости поток ядра может использовать таблицы страниц предыдущего процесса. Так как потоки ядра не обращаются к памяти в пространстве пользователя, то они используют только ту информацию об адресном пространстве ядра, которая связана с памятью ядра и является общей для всех процессов. Области памяти
Области памяти (memory areas) представляются с помощью объектов областей памяти, которые хранятся в структурах типа
vm_area_struct
. Эта структура определена в файле <linux/mm.h>
. Области памяти часто называются областями виртуальной памяти (virtual memory area, или VMA). Структура
vm_area_struct
описывает одну непрерывную область памяти в данном адресном пространстве. Ядро рассматривает каждую область памяти, как уникальный объект. Для каждой области памяти определены некоторые общие свойства, такие как права доступа и набор соответствующих операций. Таким образом, одна структура VMA может представлять различные типы областей памяти, например файлы, отображаемые в память, или стек пространства пользователя. Это аналогично объектно-ориентированному подходу, который используется в подсистеме VFS (см. главу 12, "Виртуальная файловая система"). Ниже показана эта структура данных с комментариями, описывающими назначение каждого поля.
struct vm_area_struct {
struct mm_struct *vm_mm; /* соответствующая структура mm_struct */
unsigned long vm_start; /* начало диапазона адресов */
unsigned long vm_end; /* конец диапазона адресов */
struct vm_area_struct *vm_next; /* список областей VMA */
pgprot_t vm_page_prot; /* права доступа */
unsigned long vm_flags; /* флаги */
struct rb_node vm_rb; /* узел текущей области VMA */
union { /* связь с address_space->i_mmap, или i_mmap_nonlinear */
struct {
struct list_head list;
void *parent;
struct vm_area_struct *head;
} vm_set;
struct prio_tree_node prio_tree_node;
} shared;
struct list_head anon_vma_node; /* анонимные области */
struct anon_vma *anon_vma; /* объект анонимной VMA */
struct vm_operations_struct *vm_ops; /* операции */
unsigned long vm_pgoff; /* смещение в файле */
struct file *vm_file; /* отображенный файл (если есть) */
void *vm_private_data; /* приватные данные */
};
Как уже было рассказано, каждый дескриптор памяти связан с уникальным диапазоном (интервалом) адресов в адресном пространстве процесса. Поле vm_
start
— это начальный (минимальный) адрес, а поле vm_end
— конечный (максимальный) адрес данного интервала. Следовательно, значение (vm_end - vm_start
) — это размер (длина) интервала адресов в байтах. Интервалы адресов разных областей памяти одного адресного пространства не могут перекрываться. Поле
vm_mm
указывает на структуру mm_struct
, связанную с данной областью VMA. Заметим, что каждая область VMA уникальна для той структуры mm_struct
, с которой эта область связана. Поэтому, даже если два разных процесса отображают один и тот же файл на свои адресные пространства, то для каждого процесса создается своя структура vm_area_struct
, чтобы идентифицировать уникальные области памяти каждого процесса. Следовательно, два потока, которые совместно используют адресное пространство, также совместно используют и все структуры vm_area_struct
в этом адресном пространстве. Флаги областей VMA
Поле флагов
vm_flags
содержит битовые флаги, которые определены в файле <linux/mm.h>
. Они указывают особенности поведения и содержат описательную информацию о страницах памяти, которые входят в данную область памяти. В отличие от прав доступа, которые связаны с определенной физической страницей памяти, флаги областей VMA указывают особенности поведения, за которые отвечает ядро, а не аппаратное обеспечение. Более того, поле vm_flags
содержит информацию, которая относится к каждой странице в области памяти или, что то же самое, ко всей области памяти в целом. В табл. 14.1 приведен список возможных значений флагов vm_flags
.