Чтение онлайн

ЖАНРЫ

Разработка ядра Linux
Шрифт:

• Отображение выполняемого кода из выполняемого файла в область памяти процесса, которая называется сегментом кода (text section).

• Отображение инициализированных переменных из выполняемого файла в область памяти процесса, которая называется сегментом данных (data section).

• Отображение страницы памяти, заполненной нулями, в область памяти процесса, которая содержит неинициализированные глобальные переменные и называется сегментом bss [79] (bss section).

Нулевая страница памяти (zero page, страница памяти, заполненная нулями) — это страница памяти, которая полностью заполнена нулевыми значениями и используется, например, для указанной выше цели.

79

Термин "BSS" сложился исторически и является достаточно старым. Он означает block started by symbol (блок, начинающийся с символа). Неинициализированные переменные в выполняемом файле не хранятся, поскольку с ними не связано никакого значения. Тем не менее стандарт языка С требует, чтобы неинициализированным переменным присваивалось определенное значение по умолчанию (обычно все заполняется нулями). Поэтому ядро загружает переменные (без их значений) из выполняемого файла в память и отображает в эту память нулевую страницу, тем самым переменным присваивается нулевое значение без необходимости зря тратить место в объектном файле на ненужную инициализацию.

• Отображение страницы памяти, заполненной нулями, в память процесса, которая используется в качестве стека процесса пространства пользователя (не нужно путать со стеком процесса в пространстве ядра, который является отдельной структурой данных и управляется и используется ядром).

• Дополнительные сегменты кода, данных и BSS каждой совместно используемой библиотеки, таких как библиотека libc и динамический компоновщик, которые загружаются в адресное пространство процесса.

• Все файлы, содержимое которых отображено в память.

• Все области совместно используемой памяти.

• Все анонимные отображения в память, как, например, связанные с функцией

malloc
[80] .

Каждое действительное значение адреса памяти в адресном пространстве процесса принадлежит только и только одной области памяти (области памяти не перекрываются). Как будет показано, для каждого отдельного участка памяти в выполняющемся процессе существует своя область: стек, объектный код, глобальные переменные, отображенный в память файл и т.д.

80

В более новых версиях библиотеки glibc функция

malloc
реализована через системный вызов
mmap
, а не через вызов
brk
.

Дескриптор памяти

Ядро представляет адресное пространство процесса в виде структуры данных, которая называется дескриптором памяти. Эта структура содержит всю информацию, которая относится к адресному пространству процесса. Дескриптор памяти представляется с помощью структуры

struct mm_struct
, которая определена в файле
<linux/sched.h>
[81] .

Рассмотрим эту структуру с комментариями, поясняющими назначение каждого поля.

81

Между дескриптором процесса, дескриптором

памяти и соответствующими функциями существует тесная связь. Поэтому структура
struct mm_struct
и определена в заголовочном файле
sched.h
.

struct mm_struct {

 struct vm_area_struct *mmap; /* список областей памяти */

 struct rb_root mm_rb; /* красно-черное дерево

областей памяти */

 struct vm_area_struct *mmap_cache; /* последняя использованная

область памяти */

 unsigned long free_area_cache; /* первый незанятый участок

адресного пространства */

 pgd_t *pgd; /* глобальный каталог страниц */

 atomic_t mm_users; /* счетчик пользователей адресного

пространства */

 atomic_t mm_count; /* основной счетчик использования */

 int map_count; /* количество областей памяти */

 struct rw_semaphore mmap_sem; /* семафор для областей памяти */

 spinlock_t page_table_lock; /* спин-блокировка

таблиц страниц */

 struct list_head mmlist; /* список всех структур mm_struct */

 unsigned long start_code; /* начальный адрес сегмента кода */

 unsigned long end code; /* конечный адрес сегмента кода */

 unsigned long start_data; /* начальный адрес сегмента данных */

 unsigned long end_data; /* конечный адрес сегмента данных */

 unsigned long start_brk; /* начальный адрес сегмента "кучи" */

 unsigned long brk; /* конечный адрес сегмента "кучи" */

 unsigned long start_stack; /* начало стека процесса */

 unsigned long arg_start; /* начальный адрес

области аргументов */

 unsigned long arg_end; /* конечный адрес

области аргументов */

 unsigned long env_start; /* начальный адрес

области переменных среды */

 unsigned long env_end; /* конечный адрес

области переменных среды */

 unsigned long rss; /* количество физических страниц памяти */

 unsigned long total_vm; /* общее количество страниц памяти */

 unsigned long locked_vm; /* количество заблокированных страниц

памяти */

 unsigned long def_flags; /* флаги доступа, используемые

по умолчанию */

 unsigned long cpu_vm_mask; /* маска отложенного переключения

буфера TLB */

 unsigned long swap_address; /* последний сканированный адрес */

 unsigned dumpable:1; /* можно ли создавать файл core? */

 int used_hugetlb; /* используются ли гигантские

страницы памяти (hugetlb)? */

Поделиться с друзьями: