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

我已经开始学习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; } 

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

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

程序中出了什么问题? 如果错误是愚蠢的,我将不胜感激线索直接解决scheme。(对不起,使用多个variables相同的值..虚拟基地址)

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

正如@AndreasBombe所指出的那样,写入然后读取没有硬件的存储单元(RAM或设备寄存器/存储器都不会产生未定义的结果)。

我只是request_mem_region该地区,并做了一个ioremap使用该地区。 不应该这样工作吗? 我认为这是模拟内存映射的IO使用情况。

这应该“ 起作用 ”,因为你不会从这些调用中得到任何错误。 但是由于在这些物理位置上没有硬件,那么访问这些虚拟地址是没有意义的。

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

那些惯例不会做你认为他们做的事情。 你以前写过,物理地址没有硬件。 在这些例程被调用后也不会有任何东西。

request_mem_region()本质上是“分配”给定的物理地址范围(也就是说,它被记录为“由该驱动程序使用”)。 就这样; 没有别的,但地址的家务。
ioremap()是特定于体系结构的,其目的是为物理地址区域提供虚拟地址映射。 Linux代码只能使用虚拟地址来引用内存,所以现在可以访问那些设备寄存器/内存。
request_mem_region()ioremap()实际上不会提供任何物理内存供您的驱动程序使用。

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

内存映射的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 

ioread *()iowrite *()的通用版本经常被特定于架构的版本取代。

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

如果“自动”是指“始终”,那么“不”。 不是每个设备寄存器都可以是可读和/或可写的。
ioread *()只能在可读的寄存器上执行。 Iowrite *()只能在可写入的寄存器上执行。 EG设备状态寄存器当然是可读的,而且很可能不可写入。