PCIe Driver - How does user space access it?
Asked Answered
P

2

7

I am writing a PCIe driver for Linux, currently without DMA, and need to know how to read and write to the PCIe device once it is enabled from user space.

In the driver I do the basics in probe():

pci_enable_device();
pci_request_regions();
pci_iomap();

But then how do I access this memory from user space to read and write? Do I add file operations to my PCIe driver? Does the memory from pci_iomap show up some place where the user space code can call:

open('mapped memory location');
mmap(...);

If so then what is the location?

Note: the PCIe device will not plugging into any Linux subsystems such as audio, Ethernet, etc.

Pyrene answered 8/2, 2016 at 18:26 Comment(5)
Not sure if it's the recommended way of doing things, but other kernel drivers expose virtual devices like /dev/vboxnetctl, which I assume you can issue commands to. I'm not certain that the Linux kernel would allow any userspace program to read/write to a PCIe device willy-nilly, that sounds like it might be dangerous.Betsey
I was looking at that as well. Is there anything I need to do in order for my device to show up there? For example, what API calls do I make in my driver?Pyrene
Perhaps take a look at the VirtualBox driver source code for ideas.Betsey
Btw, better to use pcim_*() API.Placatory
What is pcim_*() exactly and why should I be using it? Sometimes documentation for Linux can be painful to gather so could you please provide a sentence or two on it?Pyrene
A
1

You can register devices using functions like register_chrdev and device_create. Consider the kernel source for /dev/null and /dev/mem:

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);
Alsatia answered 8/2, 2016 at 19:46 Comment(1)
Yes, I eventually created a character device driver for my PCIe device. I would recommend others to read the Linux Device Drivers book, chapter 3, to learn more. It's outdated but you can pick out some basics to get you going.Pyrene
C
4

If you just want to export memory from the kernel space to the user space and get interrupts, think about the UIO driver.

With it, all the accesses will be done through /dev/uioX file. You can do mmap() on it to export memory and you can read (with a blocking read) to "catch" the interrupt.

UIO is perfectly suited for PCIe, there already is a driver in kernel for it.

Chronicles answered 9/2, 2016 at 8:31 Comment(0)
A
1

You can register devices using functions like register_chrdev and device_create. Consider the kernel source for /dev/null and /dev/mem:

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);
Alsatia answered 8/2, 2016 at 19:46 Comment(1)
Yes, I eventually created a character device driver for my PCIe device. I would recommend others to read the Linux Device Drivers book, chapter 3, to learn more. It's outdated but you can pick out some basics to get you going.Pyrene

© 2022 - 2024 — McMap. All rights reserved.