假设我有一个内存映射外设,可以在某个地址读取或写入,例如 0x43C00000。我希望能够从 Linux 操作系统中的同一内存位置读取数据,以便与该外设进行通信。由于所讨论的地址是物理地址,因此我应该能够编写一个可以从该地址位置读取的内核模块。
在内核中,如果我有类似的东西
#define BASE_ADDR 0x43C00000
#define OFFSET 4
int * mem_addr;
mem_addr = BASEADDR + OFFSET;
我认为,这应该给我指向外设第二个写入块(0x43C00004)的指针。印刷
printk(KERN_INFO "%p\n", mem_addr)
似乎告诉我这是对的。
现在如果我尝试做类似的事情
printk(KERN_INFO "%d\n", *mem_addr);
我本以为应该读取外围设备正在写入内存的数据,从而完成我想要做的事情。但如果我尝试将这样的语句放入模块中,Linux 就会杀死它。看看我的 /var/log/messages 我看到这个:
Oops: 0000 [#1] SMP
Modules linked in; TEST_MOD(0+) ...
接下来是一堆有关寄存器状态的信息。所以显然我不被允许这样读取内存。有没有某种方法可以授予内核模块读取内存的权限?
答案1
您需要为该位置设置内核虚拟地址映射,例如
mem_addr = ioremap_nocache(BASEADDR + OFFSET, SIZE);
(您似乎已经问了两次同样的问题 - 请参阅在此输入链接描述)。