Главная » Ядро Linux » Функцииmmap() и do_mmap(): создание интервала адресов

0

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

Функция do_ramap()  объявлена в файле  <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)

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

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

Параметр pro t указывает права  доступа  для  страниц памяти в данной области. Возможные значение флагов  зависят  от аппаратной платформы и описаны в файле

<asm/mman.h>. Хотя на практике для всех аппаратных платформ определены флаги, приведенные в табл. 14.2.

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

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

Флаг                             Влияние на страницы памяти в созданном  интервале адресов

PROT_READ PROT_WRITE PROT_EXEC PROT_NONE

Соответствует флагу VM_REA D Соответствует флагу VM_WRIT E Соответствует флагу VM_EXE C

К страницам памяти нет доступа

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

Флаг                                        Влияние на созданный интервал адресов

MAP_SHARED MAP_PRIVATE MAP_FIXED

MAP_ANONYMOUS MAP_GROWSDOWN MAP_DENYWRIIE MAP_EXECUTABLE MAP_LOCKED MAP_NORESERVE MAP_POPULATE MAP_NONBLOCK

Отображение может быть совместно используемым Отображение не может быть совместно используемым Создаваемый интервал адресов должен начинаться с указанного

адреса add r

Отображение является анонимным, а не отображением файла

Соответствует флагуVM_GROWSDOWN Соответствует флагу VM DENYWRITE СоответствуетфлагуVM_EXECUTABLE Соответствует флагу VM_LOCKED

Нет необходимости резервировать память для отображения

Предварительно заполнить (prefault) таблицы страниц

Не блокировать при операциях ввода-вывода

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

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

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

void * mmар2 (void *start, size_t length, int prot,

int flags, int fd,

off_t pgoff)

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

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии