How to read data from bar 0, from user space, on a pci-e card in linux?

Windows has this program called pcitree which allows you to install and read memory without writing a device driver. Is there a linux alternative for pcitree that will allow me to read memory on block 0 with my card?

A simple use case would be that I am using the driver code to write a 32 bit integer to the first memory address in my pci-e card number zero. I then use the pcitree alternative to read the value at the first frame zero memory address and see my integer.

thank

+3


source to share


2 answers


I found some code on the internet that does what I want here, github.com/billfarrow/pcimem. As far as I understand, this link offers code that maps kernel memory to user memory via the "mmap" system call

It was mostly stolen from the readme of the program, and the mmap man page. mmap accepts

  • start address
  • the size
  • memory protection flags
  • file descriptor that is associated with bar0 of your pci card.
  • and offset


mmap returns a user-space pointer to memory, specified by the start address and size parameters.

This code shows an example using mmaps.

//The file handle can be found by typing lscpi -v
//and looking for your device.
fd = open("/sys/devices/pci0001\:00/0001\:00\:07.0/resource0", O_RDWR | O_SYNC);
//mmap returns a userspace address
//0, 4096 tells it to pull one page 
ptr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
printf("PCI BAR0 0x0000 = 0x%4x\n", *((unsigned short *) ptr);

      

+2


source


I am using the method to get the PCI BAR0 register described above, but return a segmentation fault. I am using gdb to debug the error from my code as follows and it shows the return value of mmap () is (void *) 0xffffffffffffffff



#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define PRINT_ERROR \
        do { \
                fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
                __LINE__, __FILE__, errno, strerror(errno)); exit(1); \
        } while(0)

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

int main(int argc, char **argv) {

    int fd;
    void *ptr;
    //The file handle can be found by typing lscpi -v
    //and looking for your device.
    fd = open("/sys/bus/pci/devices/0000\:00\:05.0/resource0", O_RDWR | O_SYNC);
    //mmap returns a userspace address
    //0, 4096 tells it to pull one page
    ptr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    printf("PCI BAR0 0x0000 = 0x%4x\n", *((unsigned short *) ptr));

    if(munmap(ptr, 4096) == -1) PRINT_ERROR;
    close(fd);
    return 0;
}

      

0


source







All Articles