mmap: отображение в пользовательском пространстве буфера ядра, выделенного с kmalloc

Как правильно отобразить в процессе пользовательского пространства буфер, выделенный с помощью kmalloc? еще не понимал отображение памяти ... Я пишу модуль ядра, который выделяет этот буфер (например, 120 байт), и я буду читать и записывать его в процессе пользовательского пространства. Очевидно, я создал устройство char и реализовал mmap в структуре file_operations Мой метод:

static int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
  //printk(KERN_INFO "Allocated virtual memory length = %d", vma->vm_end - vma->vm_start);

  long unsigned int size = vma->vm_end - vma->vm_start;

  if (remap_pfn_range(vma, vma->vm_start,
                      __pa(mem_area) >> PAGE_SHIFT,  //what about vma->vm_pgoff?
                      size,
                      vma->vm_page_prot) < 0)
    return -EAGAIN;

  vma->vm_flags |= VM_LOCKED;
  vma->vm_ops = &vmops;
  vma->vm_flags |= VM_RESERVED;

  my_vm_open(vma);

  return 0;
}

где mem_area указывает на область памяти, выделенную с помощью kmalloc в модуле init. Область заполнена тем же значением (например, 0x10). Все работает, но я думаю, что в этом коде что-то не так:

  1. kmalloc может вернуть указатель, который не выровнен по странице, и в этом случае Я не думаю, что значение третьего параметра remap_pfn_range является правильным, на самом деле в пользовательском пространстве я прочитал неправильное значение. d все работает, если я использую __ get_free_page (потому что функция всегда возвращает указатель, выровненный по странице) или когда kmalloc возвращает указатель, выровненный по странице. Отображение памяти работает с областями памяти, состоящими из нескольких PAGE_SIZE , поэтому следует ли выделять целую страницу вместо использования kmalloc ?

  2. Когда вызывается my_mmap , ядро еще не выделило несколько страниц? Я спрашиваю об этом, потому что нашел несколько реализаций пользовательского метода mmap , который вызывает remap_pfn_range с vma-> vm_pgoff в качестве третьего параметра ... как это может быть полезно? Это страничный фрейм первой новой выделенной страницы? Если я передаю в качестве третьего параметра фрейм страницы, как в my_mmap , я должен освободить страницы, начиная со страницы в vma-> vm_pgoff ?

  3. Однако я нашел реализацию mmap , который отображает буфер, выделенный с помощью kmalloc . Чтобы правильно отобразить буфер, операция (которую я пока не понимаю) выполняется до remap_pfn_range . Предположим, что mem - это указатель, возвращаемый kmalloc , mem_area инициализируется следующим образом:

     mem_area = (int *) (((unsigned long)  mem + PAGE_SIZE - 1) & PAGE_MASK);
     

Итак, mem_area содержит то же значение mem , только если mem выровнено по странице, в противном случае он должен содержать указатель в начале следующей страницы. Однако с этой операцией, если я передаю в качестве третьего параметра remap_pfn_range , сопоставление значения __ pa (mem_area) >> PAGE_SHIFT работает хорошо. Почему?

Всем спасибо!

11
задан MirkoBanchi 6 August 2011 в 15:46
поделиться