Здравствуйте, unkn2000, Вы писали:
U>Как в драйвере (kernel mode) организовать передачу данных из устройства непосредственно в буфер процесса (user mode), минуя буфер в драйвере?
U>ОС Linux 2.4.18.
U>PCI устройство в режиме мастеринга (без участия процессора, как в DMA) заливает данные в буфер памяти. Адрес начала буфера и его размер я пишу в порты в\в устройства.
U>Хотелось бы передавать устройству физический адрес буфера процесса запросившего данные.
U>Объемы данных (несколько аудио и видео потоков) большие и поэтому лишнее копирование из устройства в буфер драйвера и оттуда в буфер процесса крайне не желательно. В то же время использовать для перекачки данных процессор, когда драйвер читает данные из порта и передаёт их процессу ( что-то типа put_user(inb(PORT), buf++); ) то же достаточно накладно.
U>Как можно реализовать схему при которой данные из устройства сразу поступают в адресное пространство процесса ждущего данные?
U>Что-то типа следующего:
U>Процесс получает буфер (malloc) и передаёт указатель на него и его размер в драйвер (при помощи ioctl). Процесс засыпает в ioctl (при помощи очереди ожидания). В драйвере определяется физический адрес этого буфера и передаётся устройству. Устройство заполняет буфер данными и генерирует прерывание. В обработчике прерывания процесс пробуждается и при выходе из ioctl буфер либо заполнен либо возвращается код ошибки.
U>Подскажите хоть в каком направлении рыть.
Вариант:
1. В kernel выделяешь кусок памяти ( DrvBuf ) ( kmalloc или ставь патч bigphysarea с
http://www.polyware.nl/~middelink/En/hob-v4l.html#bigphysarea )
2. Регистрируешь в драйвере ( file_operations ) обработчик mmap, вида
int my_mmap( struct file* file, struct vma_area_struct* vma )
{
unsigned long size = vma->vm_end — vma->vm_start; /* == BufferLength см. ниже */
...
return remap_page_range( vma_vm_start, __pa( DrvBuf ), size, vma->vm_page_prot );
}
3. Вызываешь из приложения mmap( NULL, BufferLength, PROT_READ | PROT_WRITE, MAP_SHARED, driverFD, 0 ). Этот вызов подцепить то, что ты зарегистрируешь в п.2
4. mmap возвратит приложению виртуальный отмапенный( ну и слово ) на userspace адрес буфера драйвера ( UserBuf ).
5. Далее
а) если писать в устройсво
Приложение записывает по UserBuf всё что нужно и пинает драйвер. Драйвер скармливает __pa( DrvBuf ) dma'ю или как там у тебя.
б) если читать, то всё наоборот
Кажись всё. Удачи!