Как remap_pfn_range переназначает память ядра в пользовательское пространство?

Функция

remap_pfn_range (используется в mmap вызове в драйвере) может использоваться для сопоставления памяти ядра с пользовательским пространством. Как это делается? Кто-нибудь может объяснить точные шаги? Режим ядра - это привилегированный режим (PM), в то время как пространство пользователя не является привилегированным (NPM). В ЦП ЦП можно получить доступ ко всей памяти, в то время как в NPM ограниченная память - доступ к ЦП невозможен. Когда вызывается remap_pfn_range, как этот диапазон памяти, который был ограничен только PM, теперь доступен для пользовательского пространства?

В коде remap_pfn_range есть pgprot_t struct. Это связанная структура защиты. Что такое защита? Это ответ на этот вопрос?

Ответ 1

Просто, память ядра (обычно) просто имеет запись в таблице страниц с битом, специфичным для архитектуры, который гласит: "Эта запись в этой таблице действительна только в том случае, когда процессор находится в режиме ядра".

Что такое remap_pfn_range, это создать запись другой таблицы страниц с другим виртуальным адресом на той же странице физической памяти, которая не имеет этого набора бит.

Как правило, это плохая идея btw: -)

Ответ 2

Ядром механизма является страница таблицы MMU:

Связанное изображение1 http://windowsitpro.com/content/content/3686/figure_01.gif

или это:

Related image

Обе фотографии выше являются характеристиками аппаратного модуля памяти x86, не имеющего ничего общего с ядром Linux.

Ниже описано, как VMA связаны с процессом task_struct:

Связанное изображение http://image9.360doc.com/DownloadImg/2010/05/0320/3083800_2.gif

Related image
(источник: slideplayer.com)

И, глядя на саму функцию здесь:

http://lxr.free-electrons.com/source/mm/memory.c#L1756

Данные в физической памяти могут быть доступны ядру через ядро PTE, как показано ниже:

Image result for page protection flags linux kernel
(источник: tldp.org)

Но после вызова remap_pfn_range() получается PTE (для существующей памяти ядра, но для использования в пользовательском пространстве для доступа к ней) (с разными флагами защиты страницы). Память VMA процесса будет обновлена, чтобы использовать этот PTE для доступа к той же памяти, что сводит к минимуму необходимость тратить память на копирование. Но PTE ядра и пользовательского пространства имеют разные атрибуты, которые используются для управления доступом к физической памяти, и VMA также будет определять атрибуты на уровне процесса:

vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;