Значение адреса памяти — это заданное значение из диапазона адресов адресного пространства, как, например, 41021f000. Это значение идентифицирует определенный байт в 32-битовом адресном пространстве. Важной частью адресного пространства являются интервалы адресов памяти, к которым процесс имеет право доступа, как, например, 08048000–0804c000. Такие интервалы разрешенных адресов называются областями памяти ( memory area ). С помощью ядра процесс может динамически добавлять и удалять области памяти своего адресного пространства.
Процесс имеет право доступа только к действительным областям памяти. Более того, на область памяти могут быть установлены права только для чтения или запрет на выполнение. Если процесс обращается к адресу памяти, который не находится в действительной области памяти, или доступ к действительной области выполняется запрещенным образом, то ядро уничтожает процесс с ужасным сообщением "Segmentation Fault" (ошибка сегментации).
Области памяти могут содержать следующую нужную информацию.
• Отображение выполняемого кода из выполняемого файла в область памяти процесса, которая называется сегментом кода ( text section ).
• Отображение инициализированных переменных из выполняемого файла в область памяти процесса, которая называется сегментом данных ( data section ).
• Отображение страницы памяти, заполненной нулями, в область памяти процесса, которая содержит неинициализированные глобальные переменные и называется сегментом bss [79] Термин "BSS" сложился исторически и является достаточно старым. Он означает block started by symbol ( блок, начинающийся с символа ). Неинициализированные переменные в выполняемом файле не хранятся, поскольку с ними не связано никакого значения. Тем не менее стандарт языка С требует, чтобы неинициализированным переменным присваивалось определенное значение по умолчанию (обычно все заполняется нулями). Поэтому ядро загружает переменные (без их значений) из выполняемого файла в память и отображает в эту память нулевую страницу, тем самым переменным присваивается нулевое значение без необходимости зря тратить место в объектном файле на ненужную инициализацию.
( bss section ). Нулевая страница памяти (zero page, страница памяти, заполненная нулями) — это страница памяти, которая полностью заполнена нулевыми значениями и используется, например, для указанной выше цели.
• Отображение страницы памяти, заполненной нулями, в память процесса, которая используется в качестве стека процесса пространства пользователя (не нужно путать со стеком процесса в пространстве ядра, который является отдельной структурой данных и управляется и используется ядром).
• Дополнительные сегменты кода, данных и BSS каждой совместно используемой библиотеки, таких как библиотека libc и динамический компоновщик, которые загружаются в адресное пространство процесса.
• Все файлы, содержимое которых отображено в память.
• Все области совместно используемой памяти.
• Все анонимные отображения в память, как, например, связанные с функцией malloc()
[80] В более новых версиях библиотеки glibc функция malloc() реализована через системный вызов mmap() , а не через вызов brk() .
.
Каждое действительное значение адреса памяти в адресном пространстве процесса принадлежит только и только одной области памяти (области памяти не перекрываются). Как будет показано, для каждого отдельного участка памяти в выполняющемся процессе существует своя область: стек, объектный код, глобальные переменные, отображенный в память файл и т.д.
Ядро представляет адресное пространство процесса в виде структуры данных, которая называется дескриптором памяти . Эта структура содержит всю информацию, которая относится к адресному пространству процесса. Дескриптор памяти представляется с помощью структуры struct mm_struct
, которая определена в файле [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; /* последняя использованная
область памяти */
Читать дальше