koh*_*hpe 11 linux paging kernel driver pci
我正在为一个简单的测试设备编写PCI驱动程序.
使用lspci可以正确识别硬件(如您所见,我的驱动程序vab已经注册):
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资源.这将为memstart0返回00000000f0000000,这是我的PCI基地址0.
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;
}
尝试使用以下代码从此memio地址读取时会出现上述错误:
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保留为00000000f d 000000,而Linux将其保留为00000000f 0 000000.
这是为了公立学校的非营利性教育目的.谢谢你的帮助!
Nem*_*emo 19
阅读Documentation/IO-mapping.txt(搜索"iomap")和/或LDD3的第15章.
request_mem_region只是确保没有其他驱动程序已经抓住了该内存区域.iomap在读取/写入之前,您仍需要将其映射到内核的VM空间.
请注意,整个pci_resource_start等舞蹈有点不赞成.我相信这些天推荐的做法是:
pci_request_regions(pdev, "myname");  /* to request regions for all BARs */
然后:
void __iomem *base = pci_iomap(pdev, 0, pci_resources_len(pdev,0)); /* to map BAR 0 */
然后:
ioread32(base + offset);  /* Or readl(base + offset), but this is more generic */
最后,最后:
pci_iounmap(pdev, base);  /* Release kernel VM mapping (undoes pci_iomap) */
pci_release_regions(pdev); /* Release all regions (undoes pci_request_regions) */
您可以通过合并手动完成前两个pci_resource_start,pci_resource_len,request_mem_region,和iomap.但是上面是(a)更短和(b)内存映射设备和使用旧x86 I/O空间的设备之间的通用.(并不是说周围有很多人.)