Здравствуйте!
Подобный вопрос уже поднимался в этой теме: remap PCI memory в user-space Но варианты предложенные там не работают в моем случае. Опишу ситуацию: пишу драйвер для PCI плат, ОС: Ubuntu 11.04 x86_64 Kernel 2.6.38-8-generic.
Для каждой из плат нормальным порядком получаются ресурсы: через pci_resource_start(dev,0) и pci_resource_len (dev, 0) (меня интересует в первую очередь BAR0). Далее необходимо сделать remap в user-space. В первую очередь для проверки правильности получения ресурсов выполняю функцию ioremap_nocache(pci_resource_start(dev,0),pci_resource_len (dev, 0)), на выходе которой получаю указатель, по которому в kernel-space читаются адекватные значения (ресурсы получены правильно). Далее необходимо реализовать mmap. В указанной теме используется такой вариант:
addr = pci_resource_start(dev->pdev, bar);
pfn = virt_to_phys(bus_to_virt(addr)) >> PAGE_SHIFT;
Не работает. Если вывести адреса, получаемые во всех функциях, получается следующее (это для примера):
Resourse start: 0x90104A00
ioremap_nocache: 0xFFFFC90008B9AA00
bus_to_virt: 0xFFFF880090104A00
virt_to_phys(bus_to_virt()): 0x90104A00
Т.е. после конструкции virt_to_phys(bus_to_virt()) получается то же значение. (что не выполняет правильно mmap).
Я пробовал выполнить вариант mmap того адреса, что получается из ioremap_nocache:
pfn = ioremap_nocache >> PAGE_SHIFT;
Тоже на работает. Еще загвоздка в том, что длина получаемых ресурсов равна 0x80, тогда как mmap выполняется минимум для PAGE_SIZE = 0x1000. Вопросы: как выполнить mmap адреса, получаемого после ioremap_nocache и работает ли это для длин не кратных PAGE_SIZE (как я понимаю нет, но существует ли другой способ отправить полученный адрес в user-space)?
Благодарю.