LINUX.ORG.RU

mmap из ядра в приложение.


0

2

ЛЮди, у кого есть реально работающий пример, когда кусок памяти из ядра, можно отмапить в память юзер-спейс.
mmap_t mmap __attribute__ ((aligned(4096)));

static int
fops_mmap(struct file *file, struct vm_area_struct *vma)
{

FileData_t *fd;
//static mmap_t *mmapTest = kmalloc(sizeof(mmap_t)+ 4096*2, GFP_USER);
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long size = vma->vm_end - vma->vm_start;

//mmapTest

fd = file->private_data;

printk (KERN_INFO «fops_mmap offset = %lX \n», offset);
printk (KERN_INFO «fops_mmap size = %lX %lu \n», size, size);
printk (KERN_INFO «fops_mmap vm_end = %lX \n», vma->vm_end);
printk (KERN_INFO «fops_mmap vm_start = %lX \n», vma->vm_start);
printk (KERN_INFO «mmap = %p \n»,(void*)&mmap);
//printk (KERN_INFO «mmapTest = %p \n»,(void*)&mmapTest);


if (offset & ~PAGE_MASK)
{
printk(«offset not aligned: %ld\n», offset);
return -ENXIO;
}

if (size > (sizeof(mmap_t)+4096LL))
{
printk(
«size too big. vma->vm_end-vma->vm_start=%lu sizeof(mmap_t)=%lu diff=%llu \n»,
vma->vm_end - vma->vm_start, sizeof(mmap_t), sizeof(mmap_t) +4096LL - size);
return (-ENXIO);
}

if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED))
{
printk(«writeable mappings must be shared, rejecting\n»);
return (-EINVAL);
}

/* we do not want to have this area swapped out, lock it */
vma->vm_flags |= VM_LOCKED;

//memset(&mmapTest,5,sizeof(mmapTest));
memset(&mmap,5,sizeof(mmap_t));

{
void *vmalloc_area_ptr = &mmap;
unsigned start = vma->vm_start;
int ret;
while (size > 0) {
unsigned pfn = vmalloc_to_pfn(vmalloc_area_ptr);
if ((ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE,
PAGE_SHARED)) < 0) {
return ret;
}
start += PAGE_SIZE;
vmalloc_area_ptr += PAGE_SIZE;
size -= PAGE_SIZE;
}
}
/*if (remap_pfn_range(vma,vma->vm_start,virt_to_phys((void*)&mmap)>>PAGE_SHIFT, size, PAGE_SHARED))
{
printk(«remap page range failed\n»);
return -ENXIO;
}*/
printk(«remap page range OK!!! \n»);
//return -ENXIO;
return (0);

}


В юзер-спейс, два один тред инкрементирует переменную в в mmap, и выводит ее на экран. Другой тред просто выводит ее на экран. Все работает. Но из ядра я обмениваться данными с юзер-спейс не могу. Хоть и есть memset, но читаются одни нули. Что мемсет обнуляет, я понять не могу.

Ответ на: комментарий от Artem-Dnepr

> Так мне же не free нужны. Мне нужны уже занятые. Если фри, то какая-же это общая память будет?

Афигеть. Может, тебе лучше придерживаться copy_to_user?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Так и делаю. Куча гемороя, но работает как-то. А что плохого в том, чтобы иметь несколько указателей на одну и туже страницу?

Artem-Dnepr
() автор топика
Ответ на: комментарий от Artem-Dnepr

> А что плохого в том, чтобы иметь несколько указателей на одну и туже страницу?

Плохо то, что ты задаешь такие вот вопросы:

Artem-Dnepr> Если фри, то какая-же это общая память будет?

Это говорит о том, что у тебя серьезные пробелы в знаниях.

tailgunner ★★★★★
()
Ответ на: комментарий от sn1ln

copy_to_user. Разбираться с менеджером памяти нет ни времени ни желания. Тем более что в планах переделка HW, так что будет куча мелких буферов выделенных через pci_alloc_consistent, которые мапятся без особых проблем вроде как. А сейчас оно и через seek/read живет.

Artem-Dnepr
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.