Search code examples
cdriverx86-64kali-linuxmemory-mapped-io

reading Memory-Mapped IO registers How to (from datasheet) and using them in mmap


I have intel system with Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection (Lewisville) (rev 04). I have downloaded the datasheet like datasheet for Intel ® 82579 Gigabit Ethernet PHY

Now I am reading resource0 of pci ethernet device like

    if((fd = open("/sys/bus/pci/devices/0000:00:19.0/resource1", O_RDWR | O_SYNC)) == -1) {
        perror("Error: open error");
    }

    int map_size = 4096UL;
    ...
    map_base = mmap(0,4096UL , PROT_READ, MAP_SHARED, fd, Register_Values_From_Datasheet);

I have x86-64 bit system. kali linux 5.7. so I am substituting Register_Values_From_Datasheetfrom above with register offset values from datasheet like 0x00008 for STATUS:Device Status Register=from datasheet

but errno of mmap() is having value 22:EINVAL after mmap call. Means invalid argument. Maybe the offset values that I am reading from datasheet may have to be interpreted some other way.

My resource file in sys/bus/pci/devices/0000:00:19.0 of Ethernet device is something like this

        0x00000000fe400000 0x00000000fe41ffff 0x0000000000040200
        0x00000000fe427000 0x00000000fe427fff 0x0000000000040200
        0x000000000000f060 0x000000000000f07f 0x0000000000040101
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000
        0x0000000000000000 0x0000000000000000 0x0000000000000000

As from above dump of resource text file (resource0) shows my Memory-Mapped IO starts at 0x00000000fe400000. So that I think should be the return address of mmap (return (void*)=&0x00000000fe400000)= but I am getting something like 0xffffffff and errno is 22. Can any one guide me in the right direction as to how the offset needs to be interpreted from datasheet. Also which registers normally need to be accessed for getting packets for pci Ethernet device. Since I am new to device programming.


Solution

  • in kernel function iomem_is_exclusive check IS_ENABLED(CONFIG_IO_STRICT_DEVMEM) or IORESOURCE_EXCLUSIVE flag is set:

            if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM)
                    || p->flags & IORESOURCE_EXCLUSIVE) {
                err = true;
                break;
            }
    

    we can simply use stap to pass through the check for test:

    stap -g -e 'probe kernel.function("iomem_is_exclusive").return { $return = 0 }'