Я пишу драйвер PCI для простого тестового устройства.
Оборудование корректно распознается с помощью lspci (как видите, мой драйвер vabs зарегистрирован):
04:02.0 Non-VGA unclassified device: Device bace:55aa
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Region 0: Memory at f0000000 (32-bit, prefetchable) [size=16M]
Kernel driver in use: vabs
Инициализация и деинициализация драйвера и подсистемы PCI работают нормально. Я получаю номер устройства, и udev создает файл устройства.
При чтении из файла устройства я получаю следующее сообщение об ошибке:
BUG: unable to handle kernel paging request at 00000000f0000000
Я успешно запрашиваю ресурсы PCI при инициализации. Это возвращает 00000000f0000000 для memstart0, что является моим базовым адресом 0 для PCI.
memstart0 = pci_resource_start( pdev, 0 );
memlen = pci_resource_len( pdev, 0 );
if( request_mem_region(memstart0,memlen,pdev->dev.kobj.name)==NULL ) {
dev_err(&pdev->dev,"Memory address conflict for device\n");
goto cleanup_mem;
}
Попытка чтения с этого мемо-адреса с помощью следующего кода дает указанную ошибку:
ssize_t driver_read(struct file *instance, char __user *buffer, size_t max_bytes_to_read, loff_t *offset) {
u32 test;
dev_dbg(vabs_dev,"copying from %p\n", (void *) memstart0);
test = readl((void *) memstart0);
return max_bytes_to_read;
}
Я также пробовал другие функции доступа, такие как memcpy_fromio, ioread32 и прямой доступ по указателю с тем же результатом.
Аппаратное обеспечение работает на машине Windows. Единственное заметное отличие состоит в том, что Windows резервирует базовый адрес 0 как 00000000fd000000, а Linux резервирует его как 00000000f0000000.
Это для некоммерческих образовательных целей в государственной школе. Спасибо за вашу помощь!