Таблица 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в дескрипторе памяти. В конце концов, функция возвращает начальный адрес вновь созданного интервала адресов.
Возможности функции 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()удаляет интервал адресов из указанного адресного пространства процесса. Эта функция объявлена в файле следующим образом.
int do_munmap(struct mm_struct *mm,
unsigned long start, size_t len);
Первый параметр указывает адресное пространство, из которого удаляется интервал адресов, начинающийся с адреса startи имеющий длину lenбайт. В случае успеха возвращается нуль, а в случае ошибки — отрицательное значение.
Системный вызов munmap()экспортируется в адресное пространство пользователя, чтобы иметь возможность удалять интервалы адресов из адресного пространства. Эта функция является комплиментарной к системному вызову mmap()и имеет следующий прототип.
int munmap(void*start, size_t length);
Данный системный вызов реализован в виде очень простой интерфейсной оболочки (wrapper) функции do_munmap().
asmlinkage long sys_munmap(unsigned long addr, size_t len) {
int ret;
struct mm_struct *mm; mm = current->mm;
down_write(&mm->mmap_sem);
ret = do_munmap(mm, addr, len);
p_write(&mm->mmap_sem);
return ret;
}
Хотя пользовательские программы и работают с виртуальной памятью, которая отображается на физические адреса, процессоры работают непосредственно с этими физическими адресами. Следовательно, когда приложение обращается к адресу виртуальной памяти, этот адрес должен быть конвертирован в физический адрес, чтобы процессор смог выполнить запрос. Соответствующий поиск выполняется с помощью таблиц страниц. Таблицы страниц работают путем разбиения виртуального адреса на части. Каждая часть используется в качестве индекса (номера) записи в таблице. Таблица содержит или указатель на другую таблицу, или указатель на соответствующую страницу физической памяти.
Читать дальше