Функции mmap() и do_mmap() : создание интервала адресов
Функции 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 в дескрипторе памяти. В конце концов, функция возвращает начальный адрес вновь созданного интервала адресов.