简体   繁体   English

从Linux内核模块访问/ dev / mem

[英]Access /dev/mem from Linux kernel module

I'm working on Raspberry PI (Linux rpi 3.12.28+) and I have the following C code that I can use to manipulate GPIO ports: 我正在使用Raspberry PI(Linux rpi 3.12.28+),并且具有以下可用于操纵GPIO端口的C代码:

// IO Acces
struct bcm2835_peripheral {
unsigned long addr_p;
int mem_fd; // memory file descriptor
void *map;
volatile unsigned int *addr;
};

struct bcm2835_peripheral gpio = {0x40000000};

// Exposes the physical address defined in the passed structure using mmap on /dev/mem
int map_peripheral(struct bcm2835_peripheral *p)
{
   // Open /dev/mem
   if ((p->mem_fd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) {
      return -1;
   }

   p->map = mmap(
      NULL,
      BLOCK_SIZE,
      PROT_READ | PROT_WRITE,
      MAP_SHARED,
      p->mem_fd,  // File descriptor to physical memory virtual file '/dev/mem'
      p->addr_p   // Address in physical map that we want this memory block to expose
   );

   if (p->map == MAP_FAILED) {
        return -1;
   }

   p->addr = (volatile unsigned int *)p->map;

   return 0;
}

Above code works fine for normal programs (user space). 上面的代码适用于普通程序(用户空间)。 But I need to create a Linux kernel module that will do the same. 但是我需要创建一个将执行相同操作的Linux内核模块。 The problem is that compiler doesn't recognize methods like open() or mmap(). 问题在于,编译器无法识别open()或mmap()之类的方法。 What is an appropriate approach to convert this code to the kernel module (driver)? 有什么合适的方法将此代码转换为内核模块(驱动程序)? Are these functions available for kernel programming or should I do that in a different way? 这些功能是否可用于内核编程,还是应该以其他方式使用? I've seen methods like syscall_open(), filp_open(), sys_mmap2() but I'm confused. 我见过像syscall_open(),filp_open(),sys_mmap2()之类的方法,但是我很困惑。 I will appreciate any help. 我将不胜感激。

You don't have system calls (open, close, read, write, etc..) in kernel space, instead, you'd have to use the internal interfaces provided by the modules, but seems that is not your case. 您在内核空间中没有系统调用(打开,关闭,读取,写入等),而是必须使用模块提供的内部接口,但事实并非如此。

Considering you are accessing /dev/mem I suppose you are trying to read the physical memory of the RaspberyPi. 考虑到您正在访问/dev/mem我想您正在尝试读取RaspberyPi的物理内存。 From kernel space you can access it directly since there's no memory protection, but, you'd have to use phys_to_virt function to translate the addresses. 由于没有内存保护,因此可以从内核空间直接访问它,但是,您必须使用phys_to_virt函数来转换地址。

It is true that there is no need to access /dev/mem in kernel modules. 确实,无需在内核模块中访问/dev/mem Accessing memory directly using phys_to_virt is a solution to manipulate memory, but it will not work on Raspberry PI if the goal is to manipulate GPIO ports. 使用phys_to_virt直接访问内存是一种操纵内存的解决方案,但是如果目标是操纵GPIO端口,则在Raspberry PI上将无法使用。

The solution is to access hardware registers. 解决方案是访问硬件寄存器。 I have found excellent tutorial here: 我在这里找到了很好的教程:

Creating a Basic LED Driver for Raspberry Pi 为Raspberry Pi创建基本的LED驱动器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM