Linux PCIe驱动程序-用户空间如何访问它?

Linux PCIe驱动程序-用户空间如何访问它?,linux,linux-kernel,linux-device-driver,pci-e,userspace,Linux,Linux Kernel,Linux Device Driver,Pci E,Userspace,我正在为Linux编写PCIe驱动程序,目前没有DMA,需要知道从用户空间启用PCIe设备后如何读取和写入 在驱动程序中,我在probe()中执行基本操作: 但是我如何从用户空间访问这个内存来读写呢?我是否将文件操作添加到PCIe驱动程序?来自pci_iomap的内存是否显示用户空间代码可以调用的位置: open('mapped memory location'); mmap(...); 如果是,那么位置是什么 注意:PCIe设备不会插入任何Linux子系统,如音频、以太网等。您可以使用和等功

我正在为Linux编写PCIe驱动程序,目前没有DMA,需要知道从用户空间启用PCIe设备后如何读取和写入

在驱动程序中,我在probe()中执行基本操作:

但是我如何从用户空间访问这个内存来读写呢?我是否将文件操作添加到PCIe驱动程序?来自pci_iomap的内存是否显示用户空间代码可以调用的位置:

open('mapped memory location');
mmap(...);
如果是,那么位置是什么


注意:PCIe设备不会插入任何Linux子系统,如音频、以太网等。

您可以使用和等功能注册设备。考虑:

static int\uu init chr\u dev\u init(void)
{
int小调;
if(注册chrdev(MEM_MAJOR、MEM和memory_fops))
printk(“无法获取内存开发的主%d”,MEM_-major);
mem_class=class_create(该_模块,“mem”);
如果(是错误(成员类))
返回PTR_ERR(mem_类);
mem_class->devnode=mem_devnode;
用于(次要=1;次要<数组大小(devlist);次要++){
如果(!devlist[minor].name)
继续;
/*
*是否创建/dev/port?
*/
如果((次要==DEVPORT_次要)&&!arch_有_dev_port())
继续;
设备创建(mem_类,NULL,MKDEV(mem_主,辅),
NULL,devlist[minor].name);
}
返回tty_init();
}
fs_initcall(chr_dev_init);

如果您只想将内存从内核空间导出到用户空间并获得中断,请考虑以下问题

有了它,所有的访问都将通过/dev/uioX文件完成。您可以对其执行mmap()以导出内存,还可以读取(使用阻塞读取)以“捕获”中断


UIO非常适合PCIe,在内核中也有它的应用。

不确定这是否是推荐的操作方式,但其他内核驱动程序会公开虚拟设备,如
/dev/vboxnetctl
,我认为您可以向其发出命令。我不确定Linux内核是否允许任何用户空间程序随意读/写PCIe设备,这听起来可能很危险。我也在考虑这一点。我需要做什么才能让我的设备显示在那里?例如,我应该在我的驱动程序中进行哪些API调用?也许可以看看VirtualBox驱动程序源代码,了解一些想法。顺便说一句,最好使用
pcim*()
API。什么是
pcim*()
,我为什么要使用它?有时候收集Linux文档可能会很痛苦,所以请您提供一两句关于它的话好吗?是的,我最终为我的PCIe设备创建了一个字符设备驱动程序。我建议其他人阅读Linux设备驱动程序手册第3章,了解更多信息。它已经过时了,但是你可以挑选一些基本的东西来继续。
open('mapped memory location');
mmap(...);
static int __init chr_dev_init(void)
{
    int minor;

    if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
        printk("unable to get major %d for memory devs\n", MEM_MAJOR);

    mem_class = class_create(THIS_MODULE, "mem");
    if (IS_ERR(mem_class))
        return PTR_ERR(mem_class);

    mem_class->devnode = mem_devnode;
    for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
        if (!devlist[minor].name)
            continue;

        /*
         * Create /dev/port?
         */
        if ((minor == DEVPORT_MINOR) && !arch_has_dev_port())
            continue;

        device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
                  NULL, devlist[minor].name);
    }

    return tty_init();
}

fs_initcall(chr_dev_init);