ioread32后跟iowrite32没有给出相同的值

Vig*_*esh 1 linux memory io linux-device-driver

我已经开始学习linux设备驱动程序了.我正在做一些示例程序作为我学习的一部分.为了理解内存映射IO,我编写了以下代码.(这里只显示了init).基地址没有硬件映射.

static unsigned long base = 0xfed00000;
unsigned long device_base=0;
unsigned long virtual_base=0;

static int __init sharedirqmodule_init(void) {
u32 register1=0;
u32 value=0x23456789;
device_base=base;
void *address=0;

if(!request_mem_region(device_base,8,"device"))
    return -ENODEV;

virtual_base = (unsigned long) ioremap(device_base, 8);
address=(void *)virtual_base;

printk(KERN_ERR "Sharedirq : Address value: %lx\n",address);

iowrite32(value,address);
wmb();

register1=(u32)ioread32(address);
rmb();

printk(KERN_ERR "Shared irq :value: %d \n",register1);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该模块是insmod'ing.但是我在使用ioread32时没有得到正确的值.我得到以下输出,

[20441.627344] Sharedirq : Address value: ffffc900001ce000
[20441.627365] Shared irq :value: -1  
Run Code Online (Sandbox Code Playgroud)

该计划出了什么问题?如果错误是愚蠢的,我将不胜感激而不是直接的解决方案.(抱歉为同一个值使用多个变量.. virtual_base和地址)

saw*_*ust 5

基地址没有硬件映射.......程序出了什么问题?

正如@AndreasBombe指出的那样,写入然后读取没有硬件(RAM或设备寄存器/存储器)的存储器位置将产生不确定的结果.

我只是request_mem_region那个区域并做了一个ioremap来使用该区域.不应该那样吗?我认为这有点模拟内存映射的IO使用情况.

这应该" 工作 ",因为你不会从这些调用中得到任何错误.但由于这些物理位置没有硬件,因此访问这些虚拟地址毫无意义.

该值应保存在物理内存中,因为ioremap提供的虚拟地址已映射到物理地址.

这些惯例并不像你认为的那样做.您之前写道,物理地址没有硬件.在调用这些例程之后也不会有任何事情发生.

request_mem_region()实质上是"分配"给定的物理地址范围(也就是说,它被记录为"此驱动程序正在使用").就这样; 除了地址管理外别无其他.
ioremap()是特定于体系结构的,其目的是为物理地址区域提供虚拟地址映射.Linux代码只能使用虚拟地址来引用内存,因此现在可以访问这些设备寄存器/内存.
无论request_mem_region()ioremap的()实际上将您的驾驶员提供用于任何物理内存.

我以为iowrite和ioread在内存映射的IO情况下转换为普通的MOV指令.我的理解错了吗?

内存映射的I/O位置将作为虚拟内存操作进行访问.如果CPU的指令集使用MOV操作码访问内存,那么你是正确的.
但是为了正确执行程序,必须在那些可以响应存储和获取操作的位置存在实际硬件.

我知道它在I/O映射的情况下会失败

没有"I/O映射"这样的东西.
存在"端口映射I/O",其具有与存储器分开的空间中的设备地址,并且使用输入输出指令来访问.

为内存映射IO设备编写的驱动程序如何使用request_mem_region()&ioremap()来使用它请求的内存?

从技术上讲,内存不是"请求"的.我会将其称为"设备内存(或寄存器)映射到虚拟内存(空间)".

include/asm-generic/iomap.h中,ioremap()返回的值被描述为cookie,因此不应被驱动程序用作虚拟内存地址,而是通过诸如ioread*()iowrite*之类的访问器函数. ():

 17 /*
 18  * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
 19  * access or a MMIO access, these functions don't care. The info is
 20  * encoded in the hardware mapping set up by the mapping functions
 21  * (or the cookie itself, depending on implementation and hw).
 22  *
 23  * The generic routines just encode the PIO/MMIO as part of the
 24  * cookie, and coldly assume that the MMIO IO mappings are not
 25  * in the low address range. Architectures for which this is not
 26  * true can't use this generic implementation.
 27  */
 28 
Run Code Online (Sandbox Code Playgroud)

ioread*()iowrite*()的通用版本通常由特定于体系结构的版本替换.

在这种情况下,ioread()和iowrite()会自动工作吗?

如果"自动"表示"始终",则表示"否".并非每个设备寄存器都是可读和/或可写的.
所述ioread*()应该只在一个寄存器,是可读的被执行.该iowrite*()应只在一个寄存器是可写的执行.EG设备状态寄存器当然是可读的,很可能是不可写的.