【发布时间】:2014-10-16 19:25:27
【问题描述】:
我正在研究 Raspberry PI (Linux rpi 3.12.28+),我有以下 C 代码可用于操作 GPIO 端口:
// 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;
}
以上代码适用于普通程序(用户空间)。但我需要创建一个 Linux 内核模块来做同样的事情。问题是编译器无法识别 open() 或 mmap() 等方法。将此代码转换为内核模块(驱动程序)的合适方法是什么?这些函数可用于内核编程还是我应该以不同的方式进行?我见过像 syscall_open()、filp_open()、sys_mmap2() 这样的方法,但我很困惑。我将不胜感激。
【问题讨论】:
-
内核代码已经可以访问所有内存,不需要打开
/dev/mem。请注意物理地址与虚拟地址。
标签: c linux kernel raspberry-pi driver