ioread32后跟iowrite32没有给出相同的值 [英] ioread32 followed by iowrite32 not giving same value

查看:959
本文介绍了ioread32后跟iowrite32没有给出相同的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have started learning linux device drivers. I'm doing some sample programs as a part of my learning. To understand memory mapped IO I wrote the following code.(only init is shown here). There is no hardware mapped at the base address.

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;
}

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

The module is insmod'ing. But I'm not getting the correct value I wrote when using ioread32. I'm getting the following output,

[20441.627344] Sharedirq : Address value: ffffc900001ce000
[20441.627365] Shared irq :value: -1  

程序出了什么问题?如果错误是愚蠢的,我将不胜感激而不是直接的解决方案。(对不起,对于相同的值使用多个变量.. virtual_base和地址)

What is going wrong in the program? If the mistake is silly I would appreciate a clue than a direct solution.(Sorry for using multiple variable for the same value.. virtual_base and address)

推荐答案


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

There is no hardware mapped at the base address. ... What is going wrong in the program?

正如@AndreasBombe指出的那样,写入然后读取没有硬件的内存位置(既不是RAM也不是设备寄存器/内存)将产生未定义的结果。

As @AndreasBombe pointed out, writing and then reading a memory location that has no hardware (neither RAM or a device register/memory) will produce undefined results.


我只是request_mem_region该区域并使用ioremap来使用该区域。那应该不行吗?我认为它模拟了内存映射的IO使用情况。

I just request_mem_region that region and did a ioremap to use that region. Shouldn't that work? I thought it kind of simulate the memory mapped IO usage.

在某种意义上应该工作你不会从这些电话中得到任何错误。但由于这些物理位置没有硬件,因此访问这些虚拟地址毫无意义。

That should "work" in the sense that you will not get any error from those calls. But since there is no hardware at those physical locations, then accessing those virtual addresses makes no sense.


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

The value should be saved in physical memory as the virtual address provided by ioremap would have mapped to a physical address.

这些例程不会像你认为的那样做。您之前写过,物理地址上没有硬件。在这些例程被调用之后也不会有。

Those routines do not do what you seem to think they do. You previously wrote that there is no hardware at the physical address. Nor will there be any after these routines are called.

request_mem_region()基本上分配给定的物理地址范围(即,它记录为此驾驶员正在使用)。就这样;除了地址管理之外别无其他。

ioremap()是特定于体系结构的,其目的是为物理地址区域提供虚拟地址映射。 Linux代码只能使用虚拟地址来引用内存,因此现在可以访问这些设备寄存器/内存。

request_mem_region() ioremap()实际上将为您的驱动程序提供任何物理内存。

request_mem_region() essentially "allocates" the given physical address range (that is, it is recorded as "in use by this driver"). That's all; nothing else but housekeeping of addresses.
ioremap() is architecture specific, and the intent is to provide a virtual address mapping for a region of physical addresses. Linux code can only use virtual address to reference memory, so now those device registers/memory are accessible.
Neither request_mem_region() or ioremap() will actually provide any physical memory for use by your driver.


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

I thought iowrite and ioread get converted to ordinary MOV instruction in memory mapped IO case.Is my understanding wrong?

内存映射的I / O位置将作为虚拟内存操作进行访问。如果CPU的指令集使用MOV操作码访问内存,那么你是正确的。

但是为了正确执行你的程序,必须在那些可以响应商店的位置有实际的硬件和获取操作。

The memory mapped I/O location would be accessed as a virtual memory operation. If the instruction set of the CPU uses a MOV opcode to access memory, then you're correct.
But for proper execution of your program, there has to be actual hardware at those locations that can respond to store and fetch operations.


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

I understand it will fail in I/O mapped case

没有I / O映射这样的东西。

端口映射I / O在单独的空间中有设备地址从内存中,使用输入输出指令进行访问。

There is no such thing as "I/O mapped".
There is "port mapped I/O" that has device addresses in a separate space from memory, and are accessed using input and output instructions.


为内存映射IO设备编写的驱动程序使用request_mem_region()& ;; ioremap的()?

How does a driver written for a memory mapped IO device use the memory it requested using request_mem_region() & ioremap()?

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

Technically the memory is not "requested". I would phrase it as "the device memory (or registers) are mapped into virtual memory (space)".

include / asm-generic / iomap.h 中, ioremap()返回的值被描述为一个cookie,因此不应该被驱动程序用作虚拟内存地址,而是通过访问器功能,例如 ioread *()& iowrite *()

In include/asm-generic/iomap.h, the value returned by ioremap() is described as a cookie and therefore should not used as a virtual memory address by the driver, but through accessor functions such as 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 

ioread *的通用版本()& iowrite *()通常被特定于体系结构的版本所取代。

The generic versions of ioread*() & iowrite*() are often replaced by architecture-specific versions.


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

Will ioread() and iowrite() automatically work in that case?

如果自动表示始终,则表示否。并非每个设备寄存器都是可读和/或可写的。

ioread *()只能在可读的寄存器上执行。 iowrite *()只能在可写的寄存器上执行。例如。设备状态寄存器肯定是可读的,很可能是不可写的。

If "automatically" means "always", then "no". Not every device register may be readable and/or writeable.
The ioread*() should only be performed on a register that is readable. The iowrite*() should only be performed on a register that is writeable. E.G. a device status register is certainly readable and most likely not writeable.

这篇关于ioread32后跟iowrite32没有给出相同的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆