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

ЖАНРЫ

Разработка ядра Linux (Второе издание)
Шрифт:

Параметр

pprev
после возвращения из функции содержит указатель на предыдущую область VMA.

Функция

find_vma_intersection

Функция

find_vma_intersection
возвращает первую область памяти, которая перекрывается с указанным интервалом адресов. Эта функция определена в файле
<linux/mm.h>
следующим образом. Это функция с подстановкой тела.

static inline struct vm_area_struct* find_vma_intersection(

 struct mm_struct *mm, unsigned long start_addr,

 unsigned long end_addr) {

 struct vm_area_struct *vma;

 vma = find_vma(mm, start_addr);

 if (vma && end_addr <= vma->vm_start)

vma = NULL;

 return vma;

}

Первый

параметр — адресное пространство, в котором выполняется поиск, параметр
start_addr
— это первый адрес интервала адресов, а параметр
end_addr
 — последний адрес интервала.

Очевидно, что если функция

find_vma
возвращает значение
NULL
, то это же значение будет возвращать и функция
find_vma_intersection
. Если функция
find_vma
возвращает существующую область VMA, то функция
find_vma_intersection
возвратит ту же область только тогда, когда эта область не начинается после конца данного диапазона адресов. Если область памяти, которая возвращается функцией
find_vma
, начинается после последнего адреса из указанного диапазона, то функция
find_vma_intersection
возвращает значение
NULL
.

Функции

mmap
и
do_mmap
: создание интервала адресов

Функция

do_mmap
используется ядром для создания нового линейного интервала адресов. Говорить, что эта функция создает новую область VMA, — технически не корректно, поскольку если создаваемый интервал адресов является смежным с существующим интервалом адресов и у этих интервалов одинаковые права доступа, то два интервала объединяются в один. Если это невозможно, то создается новая область VMA В любом случае функция
do_mmap
— это функция, которая добавляет интервал адресов к адресному пространству процесса, независимо от того, создается ли при этом новая область VMA или расширяется существующая.

Функция

do_mmap
объявлена в файле
<linux/mm.h>
следующим образом.

unsigned long do_mmap(struct file *file,

 unsigned long addr, unsigned long len,

 unsigned long prot,
unsigned long flag,

 unsigned long offset);

Эта функция выполняет отображение на память содержимого файла

file
начиная с позиции в файле
offset
; размер отображаемого участка равен
len
байт. Значения параметров
file
и
offset
могут быть нулевыми, в этом случае отображение не будет резервироваться (сохраняться) в файле. Такое отображение называется анонимным (anonymous mapping). Если указан файл и смещение, то отображение называется отображением файла в память (file-backed mapping).

Параметр

addr
указывает (точнее, всего лишь подсказывает), откуда начинать поиск свободного интервала адресов.

Параметр

prot
указывает права доступа для страниц памяти в данной области. Возможные значение флагов зависят от аппаратной платформы и описаны в файле
<asm/mman.h>
. Хотя на практике для всех аппаратных платформ определены флаги, приведенные в табл. 14.2.

Таблица 14.2. Флаги защиты страниц памяти

Флаг Влияние на страницы памяти в созданном интервале адресов
PROT_READ
Соответствует флагу
VM_READ
PROT_WRITE
Соответствует флагу
VM_WRITE
PROT_EXEC
Соответствует флагу
VM_EXEC
PROT_NONE
К страницам памяти нет доступа

Параметр

flags
позволяет указать все остальные флаги области VMA Эти флаги также определены в
<asm/mman.h>
и приведены в табл. 14.3.

Таблица 14.3.

Флаги защиты страниц памяти

Флаг Влияние на созданный интервал адресов
MAP_SHARED
Отображение может быть совместно используемым
MAP_PRIVATE
Отображение не может быть совместно используемым
MAP_FIXED
Создаваемый интервал адресов должен начинаться с указанного адреса
addr
MAP_ANONYMOUS
Отображение является анонимным, а не отображением файла
MAP_GROWSDOWN
Соответствует флагу
VM_GROWSDOWN
MAP_DENYWRITE
Соответствует флагу
VM_DENYWRITE
MAP_EXECUTABLE
Соответствует флагу
VM_EXECUTABLE
MAP_LOCKED
Соответствует флагу
VM_LOCKED
MAP_NORESERVE
Нет необходимости резервировать память для отображения
MAP_POPULATE
Предварительно заполнить (prefault) таблицы страниц
MAP_NONBLOCK
Не блокировать при операциях ввода-вывода

Если какой-либо из параметров имеет недопустимое значение, то функция

do_mmap
возвращает отрицательное число. В противном случае создастся необходимый интервал адресов. Если это возможно, то этот интервал объединяется с соседней областью памяти. Если это невозможно, то создается новая структура
vm_area_struct
, которая выделяется в слябовом кэше
vm_area_cachep
. После этого новая область памяти добавляется в связанный список и красно-черное дерево областей памяти адресного пространства с помощью функции
vma_link
. Затем обновляется значение поля
total_vm
в дескрипторе памяти. В конце концов, функция возвращает начальный адрес вновь созданного интервала адресов.

Системный вызов

mmap

Возможности функции

do_mmap
экспортируются в пространство пользователя с помощью системного вызова
mmap
, который определен следующим образом.

void *mmap2(void *start,

 size_t length, int prot, int flags, int fd, off_t pgoff);

Этот системный вызов имеет имя

mmap2
, т.е. второй вариант функции
mmap
. Первоначальный вариант
mmap
требовал в качестве последнего параметра смещение в байтах, а текущий вариант,
mmap2
, — смещение в единицах размера страницы памяти. Это позволяет отображать файлы большего размера с большим значением смещения. Первоначальный вариант функции
mmap
, который соответствует стандарту POSIX, доступен через библиотеку функций языка С, как функция
mmap
, но в ядре уже не реализован. Новый вариант библиотечной функции называется
mmap2
. Обе эти библиотечные функции используют системный вызов
mmap2
. При этом библиотечная функция
mmap
переводит значение смещения из байтов в количество страниц памяти.

Функции

munmap
и
do_munmap
: удаление интервала адресов

Функция

do_munmap
удаляет интервал адресов из указанного адресного пространства процесса. Эта функция объявлена в файле
<asm/mman.h>
следующим образом.

int do_munmap(struct mm_struct *mm,

 unsigned long start, size_t len);

Первый параметр указывает адресное пространство, из которого удаляется интервал адресов, начинающийся с адреса

start
и имеющий длину
len
байт. В случае успеха возвращается нуль, а в случае ошибки — отрицательное значение.

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